diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_hdmi.c')
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_hdmi.c | 288 |
1 files changed, 158 insertions, 130 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 2092a650df7d..01813e11e6c6 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2011 Samsung Electronics Co.Ltd * Authors: @@ -6,46 +7,41 @@ * Joonyoung Shim <jy0922.shim@samsung.com> * * Based on drivers/media/video/s5p-tv/hdmi_drv.c - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ -#include <drm/drmP.h> -#include <drm/drm_edid.h> -#include <drm/drm_crtc_helper.h> -#include <drm/drm_atomic_helper.h> - -#include "regs-hdmi.h" - -#include <linux/kernel.h> -#include <linux/wait.h> -#include <linux/i2c.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/delay.h> -#include <linux/pm_runtime.h> +#include <drm/exynos_drm.h> #include <linux/clk.h> +#include <linux/component.h> +#include <linux/delay.h> #include <linux/gpio/consumer.h> -#include <linux/regulator/consumer.h> +#include <linux/hdmi.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> #include <linux/io.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/of.h> #include <linux/of_address.h> -#include <linux/of_device.h> #include <linux/of_graph.h> -#include <linux/hdmi.h> -#include <linux/component.h> -#include <linux/mfd/syscon.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> -#include <sound/hdmi-codec.h> -#include <drm/exynos_drm.h> +#include <linux/regulator/consumer.h> +#include <linux/wait.h> +#include <sound/hdmi-codec.h> #include <media/cec-notifier.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_bridge.h> +#include <drm/drm_edid.h> +#include <drm/drm_print.h> +#include <drm/drm_probe_helper.h> +#include <drm/drm_simple_kms_helper.h> + #include "exynos_drm_crtc.h" +#include "regs-hdmi.h" #define HOTPLUG_DEBOUNCE_MS 1100 @@ -526,6 +522,15 @@ static const struct hdmiphy_config hdmiphy_5420_configs[] = { 0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80, }, }, + { + .pixel_clock = 154000000, + .conf = { + 0x01, 0xD1, 0x20, 0x01, 0x40, 0x30, 0x08, 0xCC, + 0x8C, 0xE8, 0xC1, 0xD8, 0x45, 0xA0, 0xAC, 0x80, + 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x86, + 0x54, 0x3F, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80, + }, + }, }; static const struct hdmiphy_config hdmiphy_5433_configs[] = { @@ -819,7 +824,8 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata) return; } - ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi, m, false); + ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi, + &hdata->connector, m); if (!ret) ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf)); if (ret > 0) { @@ -857,6 +863,10 @@ static enum drm_connector_status hdmi_detect(struct drm_connector *connector, static void hdmi_connector_destroy(struct drm_connector *connector) { + struct hdmi_context *hdata = connector_to_hdmi(connector); + + cec_notifier_conn_unregister(hdata->notifier); + drm_connector_unregister(connector); drm_connector_cleanup(connector); } @@ -873,29 +883,37 @@ static const struct drm_connector_funcs hdmi_connector_funcs = { static int hdmi_get_modes(struct drm_connector *connector) { struct hdmi_context *hdata = connector_to_hdmi(connector); - struct edid *edid; + const struct drm_display_info *info = &connector->display_info; + const struct drm_edid *drm_edid; int ret; if (!hdata->ddc_adpt) - return -ENODEV; + goto no_edid; - edid = drm_get_edid(connector, hdata->ddc_adpt); - if (!edid) - return -ENODEV; + drm_edid = drm_edid_read_ddc(connector, hdata->ddc_adpt); + + ret = drm_edid_connector_update(connector, drm_edid); + if (ret) + return 0; + + cec_notifier_set_phys_addr(hdata->notifier, info->source_physical_address); - hdata->dvi_mode = !drm_detect_hdmi_monitor(edid); - DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", - (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), - edid->width_cm, edid->height_cm); + if (!drm_edid) + goto no_edid; - drm_connector_update_edid_property(connector, edid); - cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid); + hdata->dvi_mode = !info->is_hdmi; + DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n", + (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), + info->width_mm / 10, info->height_mm / 10); - ret = drm_add_edid_modes(connector, edid); + ret = drm_edid_connector_add_modes(connector); - kfree(edid); + drm_edid_free(drm_edid); return ret; + +no_edid: + return drm_add_modes_noedid(connector, 640, 480); } static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) @@ -907,20 +925,23 @@ static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) if (confs->data[i].pixel_clock == pixel_clock) return i; - DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock); + DRM_DEV_DEBUG_KMS(hdata->dev, "Could not find phy config for %d\n", + pixel_clock); return -EINVAL; } -static int hdmi_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status hdmi_mode_valid(struct drm_connector *connector, + const struct drm_display_mode *mode) { struct hdmi_context *hdata = connector_to_hdmi(connector); int ret; - DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n", - mode->hdisplay, mode->vdisplay, mode->vrefresh, - (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true : - false, mode->clock * 1000); + DRM_DEV_DEBUG_KMS(hdata->dev, + "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n", + mode->hdisplay, mode->vdisplay, + drm_mode_vrefresh(mode), + (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true : + false, mode->clock * 1000); ret = hdmi_find_phy_conf(hdata, mode->clock * 1000); if (ret < 0) @@ -938,25 +959,35 @@ static int hdmi_create_connector(struct drm_encoder *encoder) { struct hdmi_context *hdata = encoder_to_hdmi(encoder); struct drm_connector *connector = &hdata->connector; + struct cec_connector_info conn_info; int ret; connector->interlace_allowed = true; connector->polled = DRM_CONNECTOR_POLL_HPD; - ret = drm_connector_init(hdata->drm_dev, connector, - &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); + ret = drm_connector_init_with_ddc(hdata->drm_dev, connector, + &hdmi_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA, + hdata->ddc_adpt); if (ret) { - DRM_ERROR("Failed to initialize connector with drm\n"); + DRM_DEV_ERROR(hdata->dev, + "Failed to initialize connector with drm\n"); return ret; } drm_connector_helper_add(connector, &hdmi_connector_helper_funcs); drm_connector_attach_encoder(connector, encoder); - if (hdata->bridge) { - ret = drm_bridge_attach(encoder, hdata->bridge, NULL); - if (ret) - DRM_ERROR("Failed to attach bridge\n"); + if (hdata->bridge) + ret = drm_bridge_attach(encoder, hdata->bridge, NULL, 0); + + cec_fill_conn_info_from_drm(&conn_info, connector); + + hdata->notifier = cec_notifier_conn_register(hdata->dev, NULL, + &conn_info); + if (!hdata->notifier) { + ret = -ENOMEM; + DRM_DEV_ERROR(hdata->dev, "Failed to allocate CEC notifier\n"); } return ret; @@ -1001,8 +1032,10 @@ static bool hdmi_mode_fixup(struct drm_encoder *encoder, DRM_INFO("desired mode doesn't exist so\n"); DRM_INFO("use the most suitable mode among modes.\n"); - DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n", - m->hdisplay, m->vdisplay, m->vrefresh); + DRM_DEV_DEBUG_KMS(dev->dev, + "Adjusted Mode: [%d]x[%d] [%d]Hz\n", + m->hdisplay, m->vdisplay, + drm_mode_vrefresh(m)); drm_mode_copy(adjusted_mode, m); break; @@ -1168,13 +1201,15 @@ static void hdmiphy_wait_for_pll(struct hdmi_context *hdata) u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS); if (val & HDMI_PHY_STATUS_READY) { - DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries); + DRM_DEV_DEBUG_KMS(hdata->dev, + "PLL stabilized after %d tries\n", + tries); return; } usleep_range(10, 20); } - DRM_ERROR("PLL could not reach steady state\n"); + DRM_DEV_ERROR(hdata->dev, "PLL could not reach steady state\n"); } static void hdmi_v13_mode_apply(struct hdmi_context *hdata) @@ -1410,7 +1445,7 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) ret = hdmi_find_phy_conf(hdata, m->clock * 1000); if (ret < 0) { - DRM_ERROR("failed to find hdmiphy conf\n"); + DRM_DEV_ERROR(hdata->dev, "failed to find hdmiphy conf\n"); return; } phy_conf = hdata->drv_data->phy_confs.data[ret].conf; @@ -1422,7 +1457,7 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) hdmiphy_enable_mode_set(hdata, true); ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32); if (ret) { - DRM_ERROR("failed to configure hdmiphy\n"); + DRM_DEV_ERROR(hdata->dev, "failed to configure hdmiphy\n"); return; } hdmiphy_enable_mode_set(hdata, false); @@ -1453,13 +1488,20 @@ static void hdmi_set_refclk(struct hdmi_context *hdata, bool on) /* Should be called with hdata->mutex mutex held. */ static void hdmiphy_enable(struct hdmi_context *hdata) { + int ret; + if (hdata->powered) return; - pm_runtime_get_sync(hdata->dev); + ret = pm_runtime_resume_and_get(hdata->dev); + if (ret < 0) { + dev_err(hdata->dev, "failed to enable HDMIPHY device.\n"); + return; + } if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk)) - DRM_DEBUG_KMS("failed to enable regulator bulk\n"); + DRM_DEV_DEBUG_KMS(hdata->dev, + "failed to enable regulator bulk\n"); regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, PMU_HDMI_PHY_ENABLE_BIT, 1); @@ -1525,8 +1567,8 @@ static void hdmi_disable(struct drm_encoder *encoder) */ mutex_unlock(&hdata->mutex); cancel_delayed_work(&hdata->hotplug_work); - cec_notifier_set_phys_addr(hdata->notifier, - CEC_PHYS_ADDR_INVALID); + if (hdata->notifier) + cec_notifier_phys_addr_invalidate(hdata->notifier); return; } @@ -1539,10 +1581,6 @@ static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = .disable = hdmi_disable, }; -static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = { - .destroy = drm_encoder_cleanup, -}; - static void hdmi_audio_shutdown(struct device *dev, void *data) { struct hdmi_context *hdata = dev_get_drvdata(dev); @@ -1564,12 +1602,12 @@ static int hdmi_audio_hw_params(struct device *dev, void *data, struct hdmi_context *hdata = dev_get_drvdata(dev); if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv || - daifmt->frame_clk_inv || daifmt->bit_clk_master || - daifmt->frame_clk_master) { + daifmt->frame_clk_inv || daifmt->bit_clk_provider || + daifmt->frame_clk_provider) { dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__, daifmt->bit_clk_inv, daifmt->frame_clk_inv, - daifmt->bit_clk_master, - daifmt->frame_clk_master); + daifmt->bit_clk_provider, + daifmt->frame_clk_provider); return -EINVAL; } @@ -1587,7 +1625,8 @@ static int hdmi_audio_hw_params(struct device *dev, void *data, return 0; } -static int hdmi_audio_digital_mute(struct device *dev, void *data, bool mute) +static int hdmi_audio_mute(struct device *dev, void *data, + bool mute, int direction) { struct hdmi_context *hdata = dev_get_drvdata(dev); @@ -1609,7 +1648,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, struct hdmi_context *hdata = dev_get_drvdata(dev); struct drm_connector *connector = &hdata->connector; + mutex_lock(&connector->eld_mutex); memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); + mutex_unlock(&connector->eld_mutex); return 0; } @@ -1617,7 +1658,7 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, static const struct hdmi_codec_ops audio_codec_ops = { .hw_params = hdmi_audio_hw_params, .audio_shutdown = hdmi_audio_shutdown, - .digital_mute = hdmi_audio_digital_mute, + .mute_stream = hdmi_audio_mute, .get_eld = hdmi_audio_get_eld, }; @@ -1627,6 +1668,7 @@ static int hdmi_register_audio_device(struct hdmi_context *hdata) .ops = &audio_codec_ops, .max_i2s_channels = 6, .i2s = 1, + .no_capture_mute = 1, }; hdata->audio.pdev = platform_device_register_data( @@ -1733,7 +1775,7 @@ static int hdmi_bridge_init(struct hdmi_context *hdata) np = of_graph_get_remote_port_parent(ep); of_node_put(ep); if (!np) { - DRM_ERROR("failed to get remote port parent"); + DRM_DEV_ERROR(dev, "failed to get remote port parent"); return -EINVAL; } @@ -1751,17 +1793,17 @@ static int hdmi_resources_init(struct hdmi_context *hdata) struct device *dev = hdata->dev; int i, ret; - DRM_DEBUG_KMS("HDMI resource init\n"); + DRM_DEV_DEBUG_KMS(dev, "HDMI resource init\n"); hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN); if (IS_ERR(hdata->hpd_gpio)) { - DRM_ERROR("cannot get hpd gpio property\n"); + DRM_DEV_ERROR(dev, "cannot get hpd gpio property\n"); return PTR_ERR(hdata->hpd_gpio); } hdata->irq = gpiod_to_irq(hdata->hpd_gpio); if (hdata->irq < 0) { - DRM_ERROR("failed to get GPIO irq\n"); + DRM_DEV_ERROR(dev, "failed to get GPIO irq\n"); return hdata->irq; } @@ -1777,25 +1819,15 @@ static int hdmi_resources_init(struct hdmi_context *hdata) hdata->regul_bulk[i].supply = supply[i]; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk); - if (ret) { - if (ret != -EPROBE_DEFER) - DRM_ERROR("failed to get regulators\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to get regulators\n"); hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en"); - if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) { + if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) if (IS_ERR(hdata->reg_hdmi_en)) return PTR_ERR(hdata->reg_hdmi_en); - ret = regulator_enable(hdata->reg_hdmi_en); - if (ret) { - DRM_ERROR("failed to enable hdmi-en regulator\n"); - return ret; - } - } - return hdmi_bridge_init(hdata); } @@ -1830,8 +1862,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) hdata->phy_clk.enable = hdmiphy_clk_enable; - drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs, - DRM_MODE_ENCODER_TMDS, NULL); + drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS); drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs); @@ -1840,11 +1871,14 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) return ret; crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI); + if (IS_ERR(crtc)) + return PTR_ERR(crtc); crtc->pipe_clk = &hdata->phy_clk; ret = hdmi_create_connector(encoder); if (ret) { - DRM_ERROR("failed to create connector ret = %d\n", ret); + DRM_DEV_ERROR(dev, "failed to create connector ret = %d\n", + ret); drm_encoder_cleanup(encoder); return ret; } @@ -1874,7 +1908,8 @@ static int hdmi_get_ddc_adapter(struct hdmi_context *hdata) np = of_parse_phandle(hdata->dev->of_node, "ddc", 0); if (!np) { - DRM_ERROR("Failed to find ddc node in device tree\n"); + DRM_DEV_ERROR(hdata->dev, + "Failed to find ddc node in device tree\n"); return -ENODEV; } @@ -1894,14 +1929,14 @@ static int hdmi_get_ddc_adapter(struct hdmi_context *hdata) static int hdmi_get_phy_io(struct hdmi_context *hdata) { const char *compatible_str = "samsung,exynos4212-hdmiphy"; - struct device_node *np; - int ret = 0; + struct device_node *np __free(device_node) = + of_find_compatible_node(NULL, NULL, compatible_str); - np = of_find_compatible_node(NULL, NULL, compatible_str); if (!np) { np = of_parse_phandle(hdata->dev->of_node, "phy", 0); if (!np) { - DRM_ERROR("Failed to find hdmiphy node in device tree\n"); + DRM_DEV_ERROR(hdata->dev, + "Failed to find hdmiphy node in device tree\n"); return -ENODEV; } } @@ -1909,22 +1944,19 @@ static int hdmi_get_phy_io(struct hdmi_context *hdata) if (hdata->drv_data->is_apb_phy) { hdata->regs_hdmiphy = of_iomap(np, 0); if (!hdata->regs_hdmiphy) { - DRM_ERROR("failed to ioremap hdmi phy\n"); - ret = -ENOMEM; - goto out; + DRM_DEV_ERROR(hdata->dev, + "failed to ioremap hdmi phy\n"); + return -ENOMEM; } } else { hdata->hdmiphy_port = of_find_i2c_device_by_node(np); if (!hdata->hdmiphy_port) { DRM_INFO("Failed to get hdmi phy i2c client\n"); - ret = -EPROBE_DEFER; - goto out; + return -EPROBE_DEFER; } } -out: - of_node_put(np); - return ret; + return 0; } static int hdmi_probe(struct platform_device *pdev) @@ -1932,7 +1964,6 @@ static int hdmi_probe(struct platform_device *pdev) struct hdmi_audio_infoframe *audio_infoframe; struct device *dev = &pdev->dev; struct hdmi_context *hdata; - struct resource *res; int ret; hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL); @@ -1950,12 +1981,11 @@ static int hdmi_probe(struct platform_device *pdev) ret = hdmi_resources_init(hdata); if (ret) { if (ret != -EPROBE_DEFER) - DRM_ERROR("hdmi_resources_init failed\n"); + DRM_DEV_ERROR(dev, "hdmi_resources_init failed\n"); return ret; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdata->regs = devm_ioremap_resource(dev, res); + hdata->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(hdata->regs)) { ret = PTR_ERR(hdata->regs); return ret; @@ -1976,14 +2006,14 @@ static int hdmi_probe(struct platform_device *pdev) IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "hdmi", hdata); if (ret) { - DRM_ERROR("failed to register hdmi interrupt\n"); + DRM_DEV_ERROR(dev, "failed to register hdmi interrupt\n"); goto err_hdmiphy; } hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,syscon-phandle"); if (IS_ERR(hdata->pmureg)) { - DRM_ERROR("syscon regmap lookup failed.\n"); + DRM_DEV_ERROR(dev, "syscon regmap lookup failed.\n"); ret = -EPROBE_DEFER; goto err_hdmiphy; } @@ -1992,16 +2022,19 @@ static int hdmi_probe(struct platform_device *pdev) hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,sysreg-phandle"); if (IS_ERR(hdata->sysreg)) { - DRM_ERROR("sysreg regmap lookup failed.\n"); + DRM_DEV_ERROR(dev, "sysreg regmap lookup failed.\n"); ret = -EPROBE_DEFER; goto err_hdmiphy; } } - hdata->notifier = cec_notifier_get(&pdev->dev); - if (hdata->notifier == NULL) { - ret = -ENOMEM; - goto err_hdmiphy; + if (!IS_ERR(hdata->reg_hdmi_en)) { + ret = regulator_enable(hdata->reg_hdmi_en); + if (ret) { + DRM_DEV_ERROR(dev, + "failed to enable hdmi-en regulator\n"); + goto err_hdmiphy; + } } pm_runtime_enable(dev); @@ -2015,7 +2048,7 @@ static int hdmi_probe(struct platform_device *pdev) ret = hdmi_register_audio_device(hdata); if (ret) - goto err_notifier_put; + goto err_rpm_disable; ret = component_add(&pdev->dev, &hdmi_component_ops); if (ret) @@ -2026,10 +2059,10 @@ static int hdmi_probe(struct platform_device *pdev) err_unregister_audio: platform_device_unregister(hdata->audio.pdev); -err_notifier_put: - cec_notifier_put(hdata->notifier); +err_rpm_disable: pm_runtime_disable(dev); - + if (!IS_ERR(hdata->reg_hdmi_en)) + regulator_disable(hdata->reg_hdmi_en); err_hdmiphy: if (hdata->hdmiphy_port) put_device(&hdata->hdmiphy_port->dev); @@ -2041,17 +2074,15 @@ err_ddc: return ret; } -static int hdmi_remove(struct platform_device *pdev) +static void hdmi_remove(struct platform_device *pdev) { struct hdmi_context *hdata = platform_get_drvdata(pdev); cancel_delayed_work_sync(&hdata->hotplug_work); - cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID); component_del(&pdev->dev, &hdmi_component_ops); platform_device_unregister(hdata->audio.pdev); - cec_notifier_put(hdata->notifier); pm_runtime_disable(&pdev->dev); if (!IS_ERR(hdata->reg_hdmi_en)) @@ -2066,8 +2097,6 @@ static int hdmi_remove(struct platform_device *pdev) put_device(&hdata->ddc_adpt->dev); mutex_destroy(&hdata->mutex); - - return 0; } static int __maybe_unused exynos_hdmi_suspend(struct device *dev) @@ -2102,7 +2131,6 @@ struct platform_driver hdmi_driver = { .remove = hdmi_remove, .driver = { .name = "exynos-hdmi", - .owner = THIS_MODULE, .pm = &exynos_hdmi_pm_ops, .of_match_table = hdmi_match_types, }, |
