void tegra_pd_remove_device(struct device *dev) { struct generic_pm_domain *genpd = dev_to_genpd(dev); if (!IS_ERR_OR_NULL(genpd)) pm_genpd_remove_device(genpd, dev); }
static int __devinit hdmi_probe(struct platform_device *pdev) { struct s5p_hdmi_platdata *pdata; struct device *dev = &pdev->dev; struct resource *res; struct i2c_adapter *phy_adapter; struct hdmi_device *hdmi_dev = NULL; struct hdmi_driver_data *drv_data; struct generic_pm_domain *genpd; int ret; dev_dbg(dev, "probe start\n"); hdmi_dev = kzalloc(sizeof(*hdmi_dev), GFP_KERNEL); if (!hdmi_dev) { dev_err(dev, "out of memory\n"); ret = -ENOMEM; goto fail; } hdmi_dev->dev = dev; ret = hdmi_resources_init(hdmi_dev); if (ret) goto fail_hdev; /* mapping HDMI registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(dev, "get memory resource failed.\n"); ret = -ENXIO; goto fail_init; } hdmi_dev->regs = ioremap(res->start, resource_size(res)); if (hdmi_dev->regs == NULL) { dev_err(dev, "register mapping failed.\n"); ret = -ENXIO; goto fail_hdev; } /* External hpd */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(dev, "get external interrupt resource failed.\n"); ret = -ENXIO; goto fail_regs; } hdmi_dev->ext_irq = res->start; /* Internal hpd */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); if (res == NULL) { dev_err(dev, "get internal interrupt resource failed.\n"); ret = -ENXIO; goto fail_regs; } hdmi_dev->int_irq = res->start; INIT_WORK(&hdmi_dev->hpd_work, hdmi_hpd_work); INIT_DELAYED_WORK(&hdmi_dev->hpd_work_ext, hdmi_hpd_work_ext); mutex_init(&hdmi_dev->mutex); /* setting v4l2 name to prevent WARN_ON in v4l2_device_register */ strlcpy(hdmi_dev->v4l2_dev.name, dev_name(dev), sizeof(hdmi_dev->v4l2_dev.name)); /* passing NULL owner prevents driver from erasing drvdata */ ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev); if (ret) { dev_err(dev, "could not register v4l2 device.\n"); goto fail_regs; } drv_data = (struct hdmi_driver_data *) platform_get_device_id(pdev)->driver_data; dev_info(dev, "hdmiphy i2c bus number = %d\n", drv_data->hdmiphy_bus); phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus); if (phy_adapter == NULL) { dev_err(dev, "adapter request failed\n"); ret = -ENXIO; goto fail_vdev; } hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev, phy_adapter, &hdmiphy_info, NULL); /* on failure or not adapter is no longer useful */ i2c_put_adapter(phy_adapter); if (hdmi_dev->phy_sd == NULL) { dev_err(dev, "missing subdev for hdmiphy\n"); ret = -ENODEV; goto fail_vdev; } pdata = pdev->dev.platform_data; /* HDMI PHY power off * HDMI PHY is on as default configuration * So, HDMI PHY must be turned off if it's not used */ if (pdata->hdmiphy_enable) pdata->hdmiphy_enable(pdev, 1); v4l2_subdev_call(hdmi_dev->phy_sd, core, s_power, 0); if (pdata->hdmiphy_enable) pdata->hdmiphy_enable(pdev, 0); #ifdef CONFIG_PM_GENERIC_DOMAINS genpd = dev_to_genpd(hdmi_dev->dev); if (IS_ERR(genpd)) { dev_err(dev, "failed get genpd\n"); goto fail_vdev; } genpd->domain.ops.suspend = hdmi_suspend; genpd->domain.ops.resume = hdmi_resume; #endif pm_runtime_enable(dev); hdmi_dev->hpd_switch.name = "hdmi"; switch_dev_register(&hdmi_dev->hpd_switch); hdmi_dev->hpd_audio_switch.name = "hdmi_audio"; switch_dev_register(&hdmi_dev->hpd_audio_switch); ret = request_irq(hdmi_dev->int_irq, hdmi_irq_handler, 0, "hdmi-int", hdmi_dev); if (ret) { dev_err(dev, "request int interrupt failed.\n"); goto fail_vdev; } disable_irq(hdmi_dev->int_irq); s5p_v4l2_int_src_ext_hpd(); ret = request_irq(hdmi_dev->ext_irq, hdmi_irq_handler_ext, IRQ_TYPE_EDGE_BOTH, "hdmi-ext", hdmi_dev); if (ret) { dev_err(dev, "request ext interrupt failed.\n"); goto fail_ext; } hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET; /* FIXME: missing fail preset is not supported */ hdmi_dev->cur_conf = hdmi_preset2conf(hdmi_dev->cur_preset); /* default audio configuration : disable audio */ hdmi_dev->audio_enable = 0; hdmi_dev->audio_channel_count = 2; hdmi_dev->sample_rate = DEFAULT_SAMPLE_RATE; hdmi_dev->color_range = 3; hdmi_dev->bits_per_sample = DEFAULT_BITS_PER_SAMPLE; hdmi_dev->audio_codec = DEFAULT_AUDIO_CODEC; /* default aspect ratio is 16:9 */ hdmi_dev->aspect = HDMI_ASPECT_RATIO_16_9; /* register hdmi subdev as entity */ ret = hdmi_register_entity(hdmi_dev); if (ret) goto fail_irq; hdmi_entity_info_print(hdmi_dev); /* initialize hdcp resource */ ret = hdcp_prepare(hdmi_dev); if (ret) goto fail_irq; queue_delayed_work(system_nrt_wq, &hdmi_dev->hpd_work_ext, msecs_to_jiffies(1000)); dev_info(dev, "probe sucessful\n"); hdmi_debugfs_init(hdmi_dev); return 0; fail_irq: free_irq(hdmi_dev->ext_irq, hdmi_dev); fail_ext: free_irq(hdmi_dev->int_irq, hdmi_dev); fail_vdev: v4l2_device_unregister(&hdmi_dev->v4l2_dev); fail_regs: iounmap(hdmi_dev->regs); fail_init: hdmi_resources_cleanup(hdmi_dev); fail_hdev: kfree(hdmi_dev); fail: dev_err(dev, "probe failed\n"); return ret; }