linux/drivers/video/fbdev/omap2/dss/hdmi4.c
<<
>>
Prefs
   1/*
   2 * HDMI interface DSS driver for TI's OMAP4 family of SoCs.
   3 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
   4 * Authors: Yong Zhi
   5 *      Mythri pk <mythripk@ti.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License version 2 as published by
   9 * the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#define DSS_SUBSYS_NAME "HDMI"
  21
  22#include <linux/kernel.h>
  23#include <linux/module.h>
  24#include <linux/err.h>
  25#include <linux/io.h>
  26#include <linux/interrupt.h>
  27#include <linux/mutex.h>
  28#include <linux/delay.h>
  29#include <linux/string.h>
  30#include <linux/platform_device.h>
  31#include <linux/pm_runtime.h>
  32#include <linux/clk.h>
  33#include <linux/gpio.h>
  34#include <linux/regulator/consumer.h>
  35#include <video/omapdss.h>
  36#include <sound/omap-hdmi-audio.h>
  37
  38#include "hdmi4_core.h"
  39#include "dss.h"
  40#include "dss_features.h"
  41#include "hdmi.h"
  42
  43static struct omap_hdmi hdmi;
  44
  45static int hdmi_runtime_get(void)
  46{
  47        int r;
  48
  49        DSSDBG("hdmi_runtime_get\n");
  50
  51        r = pm_runtime_get_sync(&hdmi.pdev->dev);
  52        WARN_ON(r < 0);
  53        if (r < 0)
  54                return r;
  55
  56        return 0;
  57}
  58
  59static void hdmi_runtime_put(void)
  60{
  61        int r;
  62
  63        DSSDBG("hdmi_runtime_put\n");
  64
  65        r = pm_runtime_put_sync(&hdmi.pdev->dev);
  66        WARN_ON(r < 0 && r != -ENOSYS);
  67}
  68
  69static irqreturn_t hdmi_irq_handler(int irq, void *data)
  70{
  71        struct hdmi_wp_data *wp = data;
  72        u32 irqstatus;
  73
  74        irqstatus = hdmi_wp_get_irqstatus(wp);
  75        hdmi_wp_set_irqstatus(wp, irqstatus);
  76
  77        if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
  78                        irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
  79                /*
  80                 * If we get both connect and disconnect interrupts at the same
  81                 * time, turn off the PHY, clear interrupts, and restart, which
  82                 * raises connect interrupt if a cable is connected, or nothing
  83                 * if cable is not connected.
  84                 */
  85                hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
  86
  87                hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
  88                                HDMI_IRQ_LINK_DISCONNECT);
  89
  90                hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
  91        } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
  92                hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
  93        } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
  94                hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
  95        }
  96
  97        return IRQ_HANDLED;
  98}
  99
 100static int hdmi_init_regulator(void)
 101{
 102        int r;
 103        struct regulator *reg;
 104
 105        if (hdmi.vdda_reg != NULL)
 106                return 0;
 107
 108        reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
 109
 110        if (IS_ERR(reg)) {
 111                if (PTR_ERR(reg) != -EPROBE_DEFER)
 112                        DSSERR("can't get VDDA regulator\n");
 113                return PTR_ERR(reg);
 114        }
 115
 116        if (regulator_can_change_voltage(reg)) {
 117                r = regulator_set_voltage(reg, 1800000, 1800000);
 118                if (r) {
 119                        devm_regulator_put(reg);
 120                        DSSWARN("can't set the regulator voltage\n");
 121                        return r;
 122                }
 123        }
 124
 125        hdmi.vdda_reg = reg;
 126
 127        return 0;
 128}
 129
 130static int hdmi_power_on_core(struct omap_dss_device *dssdev)
 131{
 132        int r;
 133
 134        r = regulator_enable(hdmi.vdda_reg);
 135        if (r)
 136                return r;
 137
 138        r = hdmi_runtime_get();
 139        if (r)
 140                goto err_runtime_get;
 141
 142        /* Make selection of HDMI in DSS */
 143        dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
 144
 145        hdmi.core_enabled = true;
 146
 147        return 0;
 148
 149err_runtime_get:
 150        regulator_disable(hdmi.vdda_reg);
 151
 152        return r;
 153}
 154
 155static void hdmi_power_off_core(struct omap_dss_device *dssdev)
 156{
 157        hdmi.core_enabled = false;
 158
 159        hdmi_runtime_put();
 160        regulator_disable(hdmi.vdda_reg);
 161}
 162
 163static int hdmi_power_on_full(struct omap_dss_device *dssdev)
 164{
 165        int r;
 166        struct omap_video_timings *p;
 167        struct omap_overlay_manager *mgr = hdmi.output.manager;
 168        struct hdmi_wp_data *wp = &hdmi.wp;
 169        struct dss_pll_clock_info hdmi_cinfo = { 0 };
 170
 171        r = hdmi_power_on_core(dssdev);
 172        if (r)
 173                return r;
 174
 175        /* disable and clear irqs */
 176        hdmi_wp_clear_irqenable(wp, 0xffffffff);
 177        hdmi_wp_set_irqstatus(wp, 0xffffffff);
 178
 179        p = &hdmi.cfg.timings;
 180
 181        DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
 182
 183        hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo);
 184
 185        r = dss_pll_enable(&hdmi.pll.pll);
 186        if (r) {
 187                DSSERR("Failed to enable PLL\n");
 188                goto err_pll_enable;
 189        }
 190
 191        r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo);
 192        if (r) {
 193                DSSERR("Failed to configure PLL\n");
 194                goto err_pll_cfg;
 195        }
 196
 197        r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco,
 198                hdmi_cinfo.clkout[0]);
 199        if (r) {
 200                DSSDBG("Failed to configure PHY\n");
 201                goto err_phy_cfg;
 202        }
 203
 204        r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
 205        if (r)
 206                goto err_phy_pwr;
 207
 208        hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
 209
 210        /* bypass TV gamma table */
 211        dispc_enable_gamma_table(0);
 212
 213        /* tv size */
 214        dss_mgr_set_timings(mgr, p);
 215
 216        r = hdmi_wp_video_start(&hdmi.wp);
 217        if (r)
 218                goto err_vid_enable;
 219
 220        r = dss_mgr_enable(mgr);
 221        if (r)
 222                goto err_mgr_enable;
 223
 224        hdmi_wp_set_irqenable(wp,
 225                HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
 226
 227        return 0;
 228
 229err_mgr_enable:
 230        hdmi_wp_video_stop(&hdmi.wp);
 231err_vid_enable:
 232err_phy_cfg:
 233        hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
 234err_phy_pwr:
 235err_pll_cfg:
 236        dss_pll_disable(&hdmi.pll.pll);
 237err_pll_enable:
 238        hdmi_power_off_core(dssdev);
 239        return -EIO;
 240}
 241
 242static void hdmi_power_off_full(struct omap_dss_device *dssdev)
 243{
 244        struct omap_overlay_manager *mgr = hdmi.output.manager;
 245
 246        hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
 247
 248        dss_mgr_disable(mgr);
 249
 250        hdmi_wp_video_stop(&hdmi.wp);
 251
 252        hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
 253
 254        dss_pll_disable(&hdmi.pll.pll);
 255
 256        hdmi_power_off_core(dssdev);
 257}
 258
 259static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
 260                                        struct omap_video_timings *timings)
 261{
 262        struct omap_dss_device *out = &hdmi.output;
 263
 264        if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
 265                return -EINVAL;
 266
 267        return 0;
 268}
 269
 270static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
 271                struct omap_video_timings *timings)
 272{
 273        mutex_lock(&hdmi.lock);
 274
 275        hdmi.cfg.timings = *timings;
 276
 277        dispc_set_tv_pclk(timings->pixelclock);
 278
 279        mutex_unlock(&hdmi.lock);
 280}
 281
 282static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
 283                struct omap_video_timings *timings)
 284{
 285        *timings = hdmi.cfg.timings;
 286}
 287
 288static void hdmi_dump_regs(struct seq_file *s)
 289{
 290        mutex_lock(&hdmi.lock);
 291
 292        if (hdmi_runtime_get()) {
 293                mutex_unlock(&hdmi.lock);
 294                return;
 295        }
 296
 297        hdmi_wp_dump(&hdmi.wp, s);
 298        hdmi_pll_dump(&hdmi.pll, s);
 299        hdmi_phy_dump(&hdmi.phy, s);
 300        hdmi4_core_dump(&hdmi.core, s);
 301
 302        hdmi_runtime_put();
 303        mutex_unlock(&hdmi.lock);
 304}
 305
 306static int read_edid(u8 *buf, int len)
 307{
 308        int r;
 309
 310        mutex_lock(&hdmi.lock);
 311
 312        r = hdmi_runtime_get();
 313        BUG_ON(r);
 314
 315        r = hdmi4_read_edid(&hdmi.core,  buf, len);
 316
 317        hdmi_runtime_put();
 318        mutex_unlock(&hdmi.lock);
 319
 320        return r;
 321}
 322
 323static int hdmi_display_enable(struct omap_dss_device *dssdev)
 324{
 325        struct omap_dss_device *out = &hdmi.output;
 326        int r = 0;
 327
 328        DSSDBG("ENTER hdmi_display_enable\n");
 329
 330        mutex_lock(&hdmi.lock);
 331
 332        if (out == NULL || out->manager == NULL) {
 333                DSSERR("failed to enable display: no output/manager\n");
 334                r = -ENODEV;
 335                goto err0;
 336        }
 337
 338        r = hdmi_power_on_full(dssdev);
 339        if (r) {
 340                DSSERR("failed to power on device\n");
 341                goto err0;
 342        }
 343
 344        hdmi.display_enabled = true;
 345
 346        mutex_unlock(&hdmi.lock);
 347        return 0;
 348
 349err0:
 350        mutex_unlock(&hdmi.lock);
 351        return r;
 352}
 353
 354static void hdmi_display_disable(struct omap_dss_device *dssdev)
 355{
 356        DSSDBG("Enter hdmi_display_disable\n");
 357
 358        mutex_lock(&hdmi.lock);
 359
 360        if (hdmi.audio_pdev && hdmi.audio_abort_cb)
 361                hdmi.audio_abort_cb(&hdmi.audio_pdev->dev);
 362
 363        hdmi_power_off_full(dssdev);
 364
 365        hdmi.display_enabled = false;
 366
 367        mutex_unlock(&hdmi.lock);
 368}
 369
 370static int hdmi_core_enable(struct omap_dss_device *dssdev)
 371{
 372        int r = 0;
 373
 374        DSSDBG("ENTER omapdss_hdmi_core_enable\n");
 375
 376        mutex_lock(&hdmi.lock);
 377
 378        r = hdmi_power_on_core(dssdev);
 379        if (r) {
 380                DSSERR("failed to power on device\n");
 381                goto err0;
 382        }
 383
 384        mutex_unlock(&hdmi.lock);
 385        return 0;
 386
 387err0:
 388        mutex_unlock(&hdmi.lock);
 389        return r;
 390}
 391
 392static void hdmi_core_disable(struct omap_dss_device *dssdev)
 393{
 394        DSSDBG("Enter omapdss_hdmi_core_disable\n");
 395
 396        mutex_lock(&hdmi.lock);
 397
 398        hdmi_power_off_core(dssdev);
 399
 400        mutex_unlock(&hdmi.lock);
 401}
 402
 403static int hdmi_connect(struct omap_dss_device *dssdev,
 404                struct omap_dss_device *dst)
 405{
 406        struct omap_overlay_manager *mgr;
 407        int r;
 408
 409        r = hdmi_init_regulator();
 410        if (r)
 411                return r;
 412
 413        mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
 414        if (!mgr)
 415                return -ENODEV;
 416
 417        r = dss_mgr_connect(mgr, dssdev);
 418        if (r)
 419                return r;
 420
 421        r = omapdss_output_set_device(dssdev, dst);
 422        if (r) {
 423                DSSERR("failed to connect output to new device: %s\n",
 424                                dst->name);
 425                dss_mgr_disconnect(mgr, dssdev);
 426                return r;
 427        }
 428
 429        return 0;
 430}
 431
 432static void hdmi_disconnect(struct omap_dss_device *dssdev,
 433                struct omap_dss_device *dst)
 434{
 435        WARN_ON(dst != dssdev->dst);
 436
 437        if (dst != dssdev->dst)
 438                return;
 439
 440        omapdss_output_unset_device(dssdev);
 441
 442        if (dssdev->manager)
 443                dss_mgr_disconnect(dssdev->manager, dssdev);
 444}
 445
 446static int hdmi_read_edid(struct omap_dss_device *dssdev,
 447                u8 *edid, int len)
 448{
 449        bool need_enable;
 450        int r;
 451
 452        need_enable = hdmi.core_enabled == false;
 453
 454        if (need_enable) {
 455                r = hdmi_core_enable(dssdev);
 456                if (r)
 457                        return r;
 458        }
 459
 460        r = read_edid(edid, len);
 461
 462        if (need_enable)
 463                hdmi_core_disable(dssdev);
 464
 465        return r;
 466}
 467
 468static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
 469                const struct hdmi_avi_infoframe *avi)
 470{
 471        hdmi.cfg.infoframe = *avi;
 472        return 0;
 473}
 474
 475static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
 476                bool hdmi_mode)
 477{
 478        hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
 479        return 0;
 480}
 481
 482static const struct omapdss_hdmi_ops hdmi_ops = {
 483        .connect                = hdmi_connect,
 484        .disconnect             = hdmi_disconnect,
 485
 486        .enable                 = hdmi_display_enable,
 487        .disable                = hdmi_display_disable,
 488
 489        .check_timings          = hdmi_display_check_timing,
 490        .set_timings            = hdmi_display_set_timing,
 491        .get_timings            = hdmi_display_get_timings,
 492
 493        .read_edid              = hdmi_read_edid,
 494        .set_infoframe          = hdmi_set_infoframe,
 495        .set_hdmi_mode          = hdmi_set_hdmi_mode,
 496};
 497
 498static void hdmi_init_output(struct platform_device *pdev)
 499{
 500        struct omap_dss_device *out = &hdmi.output;
 501
 502        out->dev = &pdev->dev;
 503        out->id = OMAP_DSS_OUTPUT_HDMI;
 504        out->output_type = OMAP_DISPLAY_TYPE_HDMI;
 505        out->name = "hdmi.0";
 506        out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
 507        out->ops.hdmi = &hdmi_ops;
 508        out->owner = THIS_MODULE;
 509
 510        omapdss_register_output(out);
 511}
 512
 513static void hdmi_uninit_output(struct platform_device *pdev)
 514{
 515        struct omap_dss_device *out = &hdmi.output;
 516
 517        omapdss_unregister_output(out);
 518}
 519
 520static int hdmi_probe_of(struct platform_device *pdev)
 521{
 522        struct device_node *node = pdev->dev.of_node;
 523        struct device_node *ep;
 524        int r;
 525
 526        ep = omapdss_of_get_first_endpoint(node);
 527        if (!ep)
 528                return 0;
 529
 530        r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy);
 531        if (r)
 532                goto err;
 533
 534        of_node_put(ep);
 535        return 0;
 536
 537err:
 538        of_node_put(ep);
 539        return r;
 540}
 541
 542/* Audio callbacks */
 543static int hdmi_audio_startup(struct device *dev,
 544                              void (*abort_cb)(struct device *dev))
 545{
 546        struct omap_hdmi *hd = dev_get_drvdata(dev);
 547        int ret = 0;
 548
 549        mutex_lock(&hd->lock);
 550
 551        if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
 552                ret = -EPERM;
 553                goto out;
 554        }
 555
 556        hd->audio_abort_cb = abort_cb;
 557
 558out:
 559        mutex_unlock(&hd->lock);
 560
 561        return ret;
 562}
 563
 564static int hdmi_audio_shutdown(struct device *dev)
 565{
 566        struct omap_hdmi *hd = dev_get_drvdata(dev);
 567
 568        mutex_lock(&hd->lock);
 569        hd->audio_abort_cb = NULL;
 570        mutex_unlock(&hd->lock);
 571
 572        return 0;
 573}
 574
 575static int hdmi_audio_start(struct device *dev)
 576{
 577        struct omap_hdmi *hd = dev_get_drvdata(dev);
 578
 579        WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
 580        WARN_ON(!hd->display_enabled);
 581
 582        hdmi_wp_audio_enable(&hd->wp, true);
 583        hdmi4_audio_start(&hd->core, &hd->wp);
 584
 585        return 0;
 586}
 587
 588static void hdmi_audio_stop(struct device *dev)
 589{
 590        struct omap_hdmi *hd = dev_get_drvdata(dev);
 591
 592        WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
 593        WARN_ON(!hd->display_enabled);
 594
 595        hdmi4_audio_stop(&hd->core, &hd->wp);
 596        hdmi_wp_audio_enable(&hd->wp, false);
 597}
 598
 599static int hdmi_audio_config(struct device *dev,
 600                             struct omap_dss_audio *dss_audio)
 601{
 602        struct omap_hdmi *hd = dev_get_drvdata(dev);
 603        int ret;
 604
 605        mutex_lock(&hd->lock);
 606
 607        if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
 608                ret = -EPERM;
 609                goto out;
 610        }
 611
 612        ret = hdmi4_audio_config(&hd->core, &hd->wp, dss_audio,
 613                                 hd->cfg.timings.pixelclock);
 614
 615out:
 616        mutex_unlock(&hd->lock);
 617
 618        return ret;
 619}
 620
 621static const struct omap_hdmi_audio_ops hdmi_audio_ops = {
 622        .audio_startup = hdmi_audio_startup,
 623        .audio_shutdown = hdmi_audio_shutdown,
 624        .audio_start = hdmi_audio_start,
 625        .audio_stop = hdmi_audio_stop,
 626        .audio_config = hdmi_audio_config,
 627};
 628
 629static int hdmi_audio_register(struct device *dev)
 630{
 631        struct omap_hdmi_audio_pdata pdata = {
 632                .dev = dev,
 633                .dss_version = omapdss_get_version(),
 634                .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
 635                .ops = &hdmi_audio_ops,
 636        };
 637
 638        hdmi.audio_pdev = platform_device_register_data(
 639                dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
 640                &pdata, sizeof(pdata));
 641
 642        if (IS_ERR(hdmi.audio_pdev))
 643                return PTR_ERR(hdmi.audio_pdev);
 644
 645        return 0;
 646}
 647
 648/* HDMI HW IP initialisation */
 649static int omapdss_hdmihw_probe(struct platform_device *pdev)
 650{
 651        int r;
 652        int irq;
 653
 654        hdmi.pdev = pdev;
 655        dev_set_drvdata(&pdev->dev, &hdmi);
 656
 657        mutex_init(&hdmi.lock);
 658
 659        if (pdev->dev.of_node) {
 660                r = hdmi_probe_of(pdev);
 661                if (r)
 662                        return r;
 663        }
 664
 665        r = hdmi_wp_init(pdev, &hdmi.wp);
 666        if (r)
 667                return r;
 668
 669        r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp);
 670        if (r)
 671                return r;
 672
 673        r = hdmi_phy_init(pdev, &hdmi.phy);
 674        if (r)
 675                goto err;
 676
 677        r = hdmi4_core_init(pdev, &hdmi.core);
 678        if (r)
 679                goto err;
 680
 681        irq = platform_get_irq(pdev, 0);
 682        if (irq < 0) {
 683                DSSERR("platform_get_irq failed\n");
 684                r = -ENODEV;
 685                goto err;
 686        }
 687
 688        r = devm_request_threaded_irq(&pdev->dev, irq,
 689                        NULL, hdmi_irq_handler,
 690                        IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
 691        if (r) {
 692                DSSERR("HDMI IRQ request failed\n");
 693                goto err;
 694        }
 695
 696        pm_runtime_enable(&pdev->dev);
 697
 698        hdmi_init_output(pdev);
 699
 700        r = hdmi_audio_register(&pdev->dev);
 701        if (r) {
 702                DSSERR("Registering HDMI audio failed\n");
 703                hdmi_uninit_output(pdev);
 704                pm_runtime_disable(&pdev->dev);
 705                return r;
 706        }
 707
 708        dss_debugfs_create_file("hdmi", hdmi_dump_regs);
 709
 710        return 0;
 711err:
 712        hdmi_pll_uninit(&hdmi.pll);
 713        return r;
 714}
 715
 716static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
 717{
 718        if (hdmi.audio_pdev)
 719                platform_device_unregister(hdmi.audio_pdev);
 720
 721        hdmi_uninit_output(pdev);
 722
 723        hdmi_pll_uninit(&hdmi.pll);
 724
 725        pm_runtime_disable(&pdev->dev);
 726
 727        return 0;
 728}
 729
 730static int hdmi_runtime_suspend(struct device *dev)
 731{
 732        dispc_runtime_put();
 733
 734        return 0;
 735}
 736
 737static int hdmi_runtime_resume(struct device *dev)
 738{
 739        int r;
 740
 741        r = dispc_runtime_get();
 742        if (r < 0)
 743                return r;
 744
 745        return 0;
 746}
 747
 748static const struct dev_pm_ops hdmi_pm_ops = {
 749        .runtime_suspend = hdmi_runtime_suspend,
 750        .runtime_resume = hdmi_runtime_resume,
 751};
 752
 753static const struct of_device_id hdmi_of_match[] = {
 754        { .compatible = "ti,omap4-hdmi", },
 755        {},
 756};
 757
 758static struct platform_driver omapdss_hdmihw_driver = {
 759        .probe          = omapdss_hdmihw_probe,
 760        .remove         = __exit_p(omapdss_hdmihw_remove),
 761        .driver         = {
 762                .name   = "omapdss_hdmi",
 763                .pm     = &hdmi_pm_ops,
 764                .of_match_table = hdmi_of_match,
 765                .suppress_bind_attrs = true,
 766        },
 767};
 768
 769int __init hdmi4_init_platform_driver(void)
 770{
 771        return platform_driver_register(&omapdss_hdmihw_driver);
 772}
 773
 774void __exit hdmi4_uninit_platform_driver(void)
 775{
 776        platform_driver_unregister(&omapdss_hdmihw_driver);
 777}
 778
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.