diff options
author | Tomasz Stanislawski <t.stanislaws@samsung.com> | 2012-10-04 11:18:46 -0400 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2012-10-05 06:14:55 -0400 |
commit | fca57122c45942b9013a74afeab9bf15b9eba19a (patch) | |
tree | aa15836ec1a476832cb43d7c72f63531ca3d8669 /drivers/gpu | |
parent | 07c8bdd79c7d7cc4142ba01a97a06133a429fe77 (diff) |
drm: exynos: hdmi: use s5p-hdmi platform data
The 'exynos-drm-hdmi' driver makes use of s5p-tv platform devices. Therefore
the driver should use the same platform data to prevent crashes caused by
dereferencing incorrect types. This patch corrects the exynos-drm-hdmi driver
to the platform data from s5p-hdmi.
Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_hdmi.c | 55 |
1 files changed, 24 insertions, 31 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 3902917cbd03..90dce8c45f8d 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -40,6 +40,9 @@ | |||
40 | 40 | ||
41 | #include "exynos_hdmi.h" | 41 | #include "exynos_hdmi.h" |
42 | 42 | ||
43 | #include <linux/gpio.h> | ||
44 | #include <media/s5p_hdmi.h> | ||
45 | |||
43 | #define MAX_WIDTH 1920 | 46 | #define MAX_WIDTH 1920 |
44 | #define MAX_HEIGHT 1080 | 47 | #define MAX_HEIGHT 1080 |
45 | #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) | 48 | #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) |
@@ -76,8 +79,7 @@ struct hdmi_context { | |||
76 | struct hdmi_resources res; | 79 | struct hdmi_resources res; |
77 | void *parent_ctx; | 80 | void *parent_ctx; |
78 | 81 | ||
79 | void (*cfg_hpd)(bool external); | 82 | int hpd_gpio; |
80 | int (*get_hpd)(void); | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | /* HDMI Version 1.3 */ | 85 | /* HDMI Version 1.3 */ |
@@ -2024,8 +2026,6 @@ static void hdmi_poweron(struct hdmi_context *hdata) | |||
2024 | 2026 | ||
2025 | hdata->powered = true; | 2027 | hdata->powered = true; |
2026 | 2028 | ||
2027 | if (hdata->cfg_hpd) | ||
2028 | hdata->cfg_hpd(true); | ||
2029 | mutex_unlock(&hdata->hdmi_mutex); | 2029 | mutex_unlock(&hdata->hdmi_mutex); |
2030 | 2030 | ||
2031 | pm_runtime_get_sync(hdata->dev); | 2031 | pm_runtime_get_sync(hdata->dev); |
@@ -2061,8 +2061,6 @@ static void hdmi_poweroff(struct hdmi_context *hdata) | |||
2061 | pm_runtime_put_sync(hdata->dev); | 2061 | pm_runtime_put_sync(hdata->dev); |
2062 | 2062 | ||
2063 | mutex_lock(&hdata->hdmi_mutex); | 2063 | mutex_lock(&hdata->hdmi_mutex); |
2064 | if (hdata->cfg_hpd) | ||
2065 | hdata->cfg_hpd(false); | ||
2066 | 2064 | ||
2067 | hdata->powered = false; | 2065 | hdata->powered = false; |
2068 | 2066 | ||
@@ -2110,17 +2108,13 @@ static irqreturn_t hdmi_external_irq_thread(int irq, void *arg) | |||
2110 | struct exynos_drm_hdmi_context *ctx = arg; | 2108 | struct exynos_drm_hdmi_context *ctx = arg; |
2111 | struct hdmi_context *hdata = ctx->ctx; | 2109 | struct hdmi_context *hdata = ctx->ctx; |
2112 | 2110 | ||
2113 | if (!hdata->get_hpd) | ||
2114 | goto out; | ||
2115 | |||
2116 | mutex_lock(&hdata->hdmi_mutex); | 2111 | mutex_lock(&hdata->hdmi_mutex); |
2117 | hdata->hpd = hdata->get_hpd(); | 2112 | hdata->hpd = gpio_get_value(hdata->hpd_gpio); |
2118 | mutex_unlock(&hdata->hdmi_mutex); | 2113 | mutex_unlock(&hdata->hdmi_mutex); |
2119 | 2114 | ||
2120 | if (ctx->drm_dev) | 2115 | if (ctx->drm_dev) |
2121 | drm_helper_hpd_irq_event(ctx->drm_dev); | 2116 | drm_helper_hpd_irq_event(ctx->drm_dev); |
2122 | 2117 | ||
2123 | out: | ||
2124 | return IRQ_HANDLED; | 2118 | return IRQ_HANDLED; |
2125 | } | 2119 | } |
2126 | 2120 | ||
@@ -2143,18 +2137,9 @@ static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg) | |||
2143 | HDMI_INTC_FLAG_HPD_PLUG); | 2137 | HDMI_INTC_FLAG_HPD_PLUG); |
2144 | } | 2138 | } |
2145 | 2139 | ||
2146 | mutex_lock(&hdata->hdmi_mutex); | ||
2147 | hdata->hpd = hdmi_reg_read(hdata, HDMI_HPD_STATUS); | ||
2148 | if (hdata->powered && hdata->hpd) { | ||
2149 | mutex_unlock(&hdata->hdmi_mutex); | ||
2150 | goto out; | ||
2151 | } | ||
2152 | mutex_unlock(&hdata->hdmi_mutex); | ||
2153 | |||
2154 | if (ctx->drm_dev) | 2140 | if (ctx->drm_dev) |
2155 | drm_helper_hpd_irq_event(ctx->drm_dev); | 2141 | drm_helper_hpd_irq_event(ctx->drm_dev); |
2156 | 2142 | ||
2157 | out: | ||
2158 | return IRQ_HANDLED; | 2143 | return IRQ_HANDLED; |
2159 | } | 2144 | } |
2160 | 2145 | ||
@@ -2287,7 +2272,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
2287 | struct device *dev = &pdev->dev; | 2272 | struct device *dev = &pdev->dev; |
2288 | struct exynos_drm_hdmi_context *drm_hdmi_ctx; | 2273 | struct exynos_drm_hdmi_context *drm_hdmi_ctx; |
2289 | struct hdmi_context *hdata; | 2274 | struct hdmi_context *hdata; |
2290 | struct exynos_drm_hdmi_pdata *pdata; | 2275 | struct s5p_hdmi_platform_data *pdata; |
2291 | struct resource *res; | 2276 | struct resource *res; |
2292 | int ret; | 2277 | int ret; |
2293 | enum hdmi_type hdmi_type; | 2278 | enum hdmi_type hdmi_type; |
@@ -2323,8 +2308,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
2323 | 2308 | ||
2324 | hdmi_type = platform_get_device_id(pdev)->driver_data; | 2309 | hdmi_type = platform_get_device_id(pdev)->driver_data; |
2325 | hdata->is_v13 = (hdmi_type == HDMI_TYPE13); | 2310 | hdata->is_v13 = (hdmi_type == HDMI_TYPE13); |
2326 | hdata->cfg_hpd = pdata->cfg_hpd; | 2311 | hdata->hpd_gpio = pdata->hpd_gpio; |
2327 | hdata->get_hpd = pdata->get_hpd; | ||
2328 | hdata->dev = dev; | 2312 | hdata->dev = dev; |
2329 | 2313 | ||
2330 | ret = hdmi_resources_init(hdata); | 2314 | ret = hdmi_resources_init(hdata); |
@@ -2342,11 +2326,17 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
2342 | goto err_resource; | 2326 | goto err_resource; |
2343 | } | 2327 | } |
2344 | 2328 | ||
2329 | ret = gpio_request(hdata->hpd_gpio, "HPD"); | ||
2330 | if (ret) { | ||
2331 | DRM_ERROR("failed to request HPD gpio\n"); | ||
2332 | goto err_resource; | ||
2333 | } | ||
2334 | |||
2345 | /* DDC i2c driver */ | 2335 | /* DDC i2c driver */ |
2346 | if (i2c_add_driver(&ddc_driver)) { | 2336 | if (i2c_add_driver(&ddc_driver)) { |
2347 | DRM_ERROR("failed to register ddc i2c driver\n"); | 2337 | DRM_ERROR("failed to register ddc i2c driver\n"); |
2348 | ret = -ENOENT; | 2338 | ret = -ENOENT; |
2349 | goto err_resource; | 2339 | goto err_gpio; |
2350 | } | 2340 | } |
2351 | 2341 | ||
2352 | hdata->ddc_port = hdmi_ddc; | 2342 | hdata->ddc_port = hdmi_ddc; |
@@ -2360,32 +2350,31 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
2360 | 2350 | ||
2361 | hdata->hdmiphy_port = hdmi_hdmiphy; | 2351 | hdata->hdmiphy_port = hdmi_hdmiphy; |
2362 | 2352 | ||
2363 | hdata->external_irq = platform_get_irq_byname(pdev, "external_irq"); | 2353 | hdata->external_irq = gpio_to_irq(hdata->hpd_gpio); |
2364 | if (hdata->external_irq < 0) { | 2354 | if (hdata->external_irq < 0) { |
2365 | DRM_ERROR("failed to get platform irq\n"); | 2355 | DRM_ERROR("failed to get GPIO external irq\n"); |
2366 | ret = hdata->external_irq; | 2356 | ret = hdata->external_irq; |
2367 | goto err_hdmiphy; | 2357 | goto err_hdmiphy; |
2368 | } | 2358 | } |
2369 | 2359 | ||
2370 | hdata->internal_irq = platform_get_irq_byname(pdev, "internal_irq"); | 2360 | hdata->internal_irq = platform_get_irq(pdev, 0); |
2371 | if (hdata->internal_irq < 0) { | 2361 | if (hdata->internal_irq < 0) { |
2372 | DRM_ERROR("failed to get platform internal irq\n"); | 2362 | DRM_ERROR("failed to get platform internal irq\n"); |
2373 | ret = hdata->internal_irq; | 2363 | ret = hdata->internal_irq; |
2374 | goto err_hdmiphy; | 2364 | goto err_hdmiphy; |
2375 | } | 2365 | } |
2376 | 2366 | ||
2367 | hdata->hpd = gpio_get_value(hdata->hpd_gpio); | ||
2368 | |||
2377 | ret = request_threaded_irq(hdata->external_irq, NULL, | 2369 | ret = request_threaded_irq(hdata->external_irq, NULL, |
2378 | hdmi_external_irq_thread, IRQF_TRIGGER_RISING | | 2370 | hdmi_external_irq_thread, IRQF_TRIGGER_RISING | |
2379 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 2371 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
2380 | "hdmi_external", drm_hdmi_ctx); | 2372 | "hdmi_external", drm_hdmi_ctx); |
2381 | if (ret) { | 2373 | if (ret) { |
2382 | DRM_ERROR("failed to register hdmi internal interrupt\n"); | 2374 | DRM_ERROR("failed to register hdmi external interrupt\n"); |
2383 | goto err_hdmiphy; | 2375 | goto err_hdmiphy; |
2384 | } | 2376 | } |
2385 | 2377 | ||
2386 | if (hdata->cfg_hpd) | ||
2387 | hdata->cfg_hpd(false); | ||
2388 | |||
2389 | ret = request_threaded_irq(hdata->internal_irq, NULL, | 2378 | ret = request_threaded_irq(hdata->internal_irq, NULL, |
2390 | hdmi_internal_irq_thread, IRQF_ONESHOT, | 2379 | hdmi_internal_irq_thread, IRQF_ONESHOT, |
2391 | "hdmi_internal", drm_hdmi_ctx); | 2380 | "hdmi_internal", drm_hdmi_ctx); |
@@ -2407,6 +2396,8 @@ err_hdmiphy: | |||
2407 | i2c_del_driver(&hdmiphy_driver); | 2396 | i2c_del_driver(&hdmiphy_driver); |
2408 | err_ddc: | 2397 | err_ddc: |
2409 | i2c_del_driver(&ddc_driver); | 2398 | i2c_del_driver(&ddc_driver); |
2399 | err_gpio: | ||
2400 | gpio_free(hdata->hpd_gpio); | ||
2410 | err_resource: | 2401 | err_resource: |
2411 | hdmi_resources_cleanup(hdata); | 2402 | hdmi_resources_cleanup(hdata); |
2412 | err_data: | 2403 | err_data: |
@@ -2426,6 +2417,8 @@ static int __devexit hdmi_remove(struct platform_device *pdev) | |||
2426 | free_irq(hdata->internal_irq, hdata); | 2417 | free_irq(hdata->internal_irq, hdata); |
2427 | free_irq(hdata->external_irq, hdata); | 2418 | free_irq(hdata->external_irq, hdata); |
2428 | 2419 | ||
2420 | gpio_free(hdata->hpd_gpio); | ||
2421 | |||
2429 | hdmi_resources_cleanup(hdata); | 2422 | hdmi_resources_cleanup(hdata); |
2430 | 2423 | ||
2431 | /* hdmiphy i2c driver */ | 2424 | /* hdmiphy i2c driver */ |