static int ath10k_ahb_rst_ctrl_init(struct ath10k *ar) { struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar); struct device *dev; dev = &ar_ahb->pdev->dev; ar_ahb->core_cold_rst = devm_reset_control_get_exclusive(dev, "wifi_core_cold"); if (IS_ERR(ar_ahb->core_cold_rst)) { ath10k_err(ar, "failed to get core cold rst ctrl: %ld\n", PTR_ERR(ar_ahb->core_cold_rst)); return PTR_ERR(ar_ahb->core_cold_rst); } ar_ahb->radio_cold_rst = devm_reset_control_get_exclusive(dev, "wifi_radio_cold"); if (IS_ERR(ar_ahb->radio_cold_rst)) { ath10k_err(ar, "failed to get radio cold rst ctrl: %ld\n", PTR_ERR(ar_ahb->radio_cold_rst)); return PTR_ERR(ar_ahb->radio_cold_rst); } ar_ahb->radio_warm_rst = devm_reset_control_get_exclusive(dev, "wifi_radio_warm"); if (IS_ERR(ar_ahb->radio_warm_rst)) { ath10k_err(ar, "failed to get radio warm rst ctrl: %ld\n", PTR_ERR(ar_ahb->radio_warm_rst)); return PTR_ERR(ar_ahb->radio_warm_rst); } ar_ahb->radio_srif_rst = devm_reset_control_get_exclusive(dev, "wifi_radio_srif"); if (IS_ERR(ar_ahb->radio_srif_rst)) { ath10k_err(ar, "failed to get radio srif rst ctrl: %ld\n", PTR_ERR(ar_ahb->radio_srif_rst)); return PTR_ERR(ar_ahb->radio_srif_rst); } ar_ahb->cpu_init_rst = devm_reset_control_get_exclusive(dev, "wifi_cpu_init"); if (IS_ERR(ar_ahb->cpu_init_rst)) { ath10k_err(ar, "failed to get cpu init rst ctrl: %ld\n", PTR_ERR(ar_ahb->cpu_init_rst)); return PTR_ERR(ar_ahb->cpu_init_rst); } return 0; }
static int adsp_init_reset(struct qcom_adsp *adsp) { adsp->pdc_sync_reset = devm_reset_control_get_exclusive(adsp->dev, "pdc_sync"); if (IS_ERR(adsp->pdc_sync_reset)) { dev_err(adsp->dev, "failed to acquire pdc_sync reset\n"); return PTR_ERR(adsp->pdc_sync_reset); } adsp->cc_lpass_restart = devm_reset_control_get_exclusive(adsp->dev, "cc_lpass"); if (IS_ERR(adsp->cc_lpass_restart)) { dev_err(adsp->dev, "failed to acquire cc_lpass restart\n"); return PTR_ERR(adsp->cc_lpass_restart); } return 0; }
static int mt7621_wdt_probe(struct platform_device *pdev) { struct resource *res; int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mt7621_wdt_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(mt7621_wdt_base)) return PTR_ERR(mt7621_wdt_base); mt7621_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(mt7621_wdt_reset)) reset_control_deassert(mt7621_wdt_reset); mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause(); watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout, &pdev->dev); watchdog_set_nowayout(&mt7621_wdt_dev, nowayout); ret = watchdog_register_device(&mt7621_wdt_dev); return 0; }
static int stm32_qspi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct spi_controller *ctrl; struct reset_control *rstc; struct stm32_qspi *qspi; struct resource *res; int ret, irq; ctrl = spi_alloc_master(dev, sizeof(*qspi)); if (!ctrl) return -ENOMEM; qspi = spi_controller_get_devdata(ctrl); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi"); qspi->io_base = devm_ioremap_resource(dev, res); if (IS_ERR(qspi->io_base)) return PTR_ERR(qspi->io_base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mm"); qspi->mm_base = devm_ioremap_resource(dev, res); if (IS_ERR(qspi->mm_base)) return PTR_ERR(qspi->mm_base); qspi->mm_size = resource_size(res); if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ) return -EINVAL; irq = platform_get_irq(pdev, 0); ret = devm_request_irq(dev, irq, stm32_qspi_irq, 0, dev_name(dev), qspi); if (ret) { dev_err(dev, "failed to request irq\n"); return ret; } init_completion(&qspi->data_completion); qspi->clk = devm_clk_get(dev, NULL); if (IS_ERR(qspi->clk)) return PTR_ERR(qspi->clk); qspi->clk_rate = clk_get_rate(qspi->clk); if (!qspi->clk_rate) return -EINVAL; ret = clk_prepare_enable(qspi->clk); if (ret) { dev_err(dev, "can not enable the clock\n"); return ret; } rstc = devm_reset_control_get_exclusive(dev, NULL); if (!IS_ERR(rstc)) { reset_control_assert(rstc); udelay(2); reset_control_deassert(rstc); } qspi->dev = dev; platform_set_drvdata(pdev, qspi); mutex_init(&qspi->lock); ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; ctrl->setup = stm32_qspi_setup; ctrl->bus_num = -1; ctrl->mem_ops = &stm32_qspi_mem_ops; ctrl->num_chipselect = STM32_QSPI_MAX_NORCHIP; ctrl->dev.of_node = dev->of_node; ret = devm_spi_register_master(dev, ctrl); if (ret) goto err_spi_register; return 0; err_spi_register: stm32_qspi_release(qspi); return ret; }
static int stm32_sai_probe(struct platform_device *pdev) { struct stm32_sai_data *sai; struct reset_control *rst; struct resource *res; const struct of_device_id *of_id; sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); if (!sai) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); sai->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(sai->base)) return PTR_ERR(sai->base); of_id = of_match_device(stm32_sai_ids, &pdev->dev); if (of_id) sai->conf = (struct stm32_sai_conf *)of_id->data; else return -EINVAL; if (!STM_SAI_IS_F4(sai)) { sai->pclk = devm_clk_get(&pdev->dev, "pclk"); if (IS_ERR(sai->pclk)) { dev_err(&pdev->dev, "missing bus clock pclk\n"); return PTR_ERR(sai->pclk); } } sai->clk_x8k = devm_clk_get(&pdev->dev, "x8k"); if (IS_ERR(sai->clk_x8k)) { dev_err(&pdev->dev, "missing x8k parent clock\n"); return PTR_ERR(sai->clk_x8k); } sai->clk_x11k = devm_clk_get(&pdev->dev, "x11k"); if (IS_ERR(sai->clk_x11k)) { dev_err(&pdev->dev, "missing x11k parent clock\n"); return PTR_ERR(sai->clk_x11k); } /* init irqs */ sai->irq = platform_get_irq(pdev, 0); if (sai->irq < 0) { dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); return sai->irq; } /* reset */ rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); reset_control_deassert(rst); } sai->pdev = pdev; sai->set_sync = &stm32_sai_set_sync; platform_set_drvdata(pdev, sai); return devm_of_platform_populate(&pdev->dev); }
static int rockchip_saradc_probe(struct platform_device *pdev) { struct rockchip_saradc *info = NULL; struct device_node *np = pdev->dev.of_node; struct iio_dev *indio_dev = NULL; struct resource *mem; const struct of_device_id *match; int ret; int irq; if (!np) return -ENODEV; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); if (!indio_dev) { dev_err(&pdev->dev, "failed allocating iio device\n"); return -ENOMEM; } info = iio_priv(indio_dev); match = of_match_device(rockchip_saradc_match, &pdev->dev); if (!match) { dev_err(&pdev->dev, "failed to match device\n"); return -ENODEV; } info->data = match->data; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); info->regs = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(info->regs)) return PTR_ERR(info->regs); /* * The reset should be an optional property, as it should work * with old devicetrees as well */ info->reset = devm_reset_control_get_exclusive(&pdev->dev, "saradc-apb"); if (IS_ERR(info->reset)) { ret = PTR_ERR(info->reset); if (ret != -ENOENT) return ret; dev_dbg(&pdev->dev, "no reset control found\n"); info->reset = NULL; } init_completion(&info->completion); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq resource?\n"); return irq; } ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr, 0, dev_name(&pdev->dev), info); if (ret < 0) { dev_err(&pdev->dev, "failed requesting irq %d\n", irq); return ret; } info->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); if (IS_ERR(info->pclk)) { dev_err(&pdev->dev, "failed to get pclk\n"); return PTR_ERR(info->pclk); } info->clk = devm_clk_get(&pdev->dev, "saradc"); if (IS_ERR(info->clk)) { dev_err(&pdev->dev, "failed to get adc clock\n"); return PTR_ERR(info->clk); } info->vref = devm_regulator_get(&pdev->dev, "vref"); if (IS_ERR(info->vref)) { dev_err(&pdev->dev, "failed to get regulator, %ld\n", PTR_ERR(info->vref)); return PTR_ERR(info->vref); } if (info->reset) rockchip_saradc_reset_controller(info->reset); /* * Use a default value for the converter clock. * This may become user-configurable in the future. */ ret = clk_set_rate(info->clk, info->data->clk_rate); if (ret < 0) { dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret); return ret; } ret = regulator_enable(info->vref); if (ret < 0) { dev_err(&pdev->dev, "failed to enable vref regulator\n"); return ret; } ret = clk_prepare_enable(info->pclk); if (ret < 0) { dev_err(&pdev->dev, "failed to enable pclk\n"); goto err_reg_voltage; } ret = clk_prepare_enable(info->clk); if (ret < 0) { dev_err(&pdev->dev, "failed to enable converter clock\n"); goto err_pclk; } platform_set_drvdata(pdev, indio_dev); indio_dev->name = dev_name(&pdev->dev); indio_dev->dev.parent = &pdev->dev; indio_dev->dev.of_node = pdev->dev.of_node; indio_dev->info = &rockchip_saradc_iio_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = info->data->channels; indio_dev->num_channels = info->data->num_channels; ret = iio_device_register(indio_dev); if (ret) goto err_clk; return 0; err_clk: clk_disable_unprepare(info->clk); err_pclk: clk_disable_unprepare(info->pclk); err_reg_voltage: regulator_disable(info->vref); return ret; }
static int da8xx_rproc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct da8xx_rproc *drproc; struct rproc *rproc; struct irq_data *irq_data; struct resource *bootreg_res; struct resource *chipsig_res; struct clk *dsp_clk; struct reset_control *dsp_reset; void __iomem *chipsig; void __iomem *bootreg; int irq; int ret; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "platform_get_irq(pdev, 0) error: %d\n", irq); return irq; } irq_data = irq_get_irq_data(irq); if (!irq_data) { dev_err(dev, "irq_get_irq_data(%d): NULL\n", irq); return -EINVAL; } bootreg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "host1cfg"); bootreg = devm_ioremap_resource(dev, bootreg_res); if (IS_ERR(bootreg)) return PTR_ERR(bootreg); chipsig_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "chipsig"); chipsig = devm_ioremap_resource(dev, chipsig_res); if (IS_ERR(chipsig)) return PTR_ERR(chipsig); dsp_clk = devm_clk_get(dev, NULL); if (IS_ERR(dsp_clk)) { dev_err(dev, "clk_get error: %ld\n", PTR_ERR(dsp_clk)); return PTR_ERR(dsp_clk); } dsp_reset = devm_reset_control_get_exclusive(dev, NULL); if (IS_ERR(dsp_reset)) { if (PTR_ERR(dsp_reset) != -EPROBE_DEFER) dev_err(dev, "unable to get reset control: %ld\n", PTR_ERR(dsp_reset)); return PTR_ERR(dsp_reset); } if (dev->of_node) { ret = of_reserved_mem_device_init(dev); if (ret) { dev_err(dev, "device does not have specific CMA pool: %d\n", ret); return ret; } } rproc = rproc_alloc(dev, "dsp", &da8xx_rproc_ops, da8xx_fw_name, sizeof(*drproc)); if (!rproc) { ret = -ENOMEM; goto free_mem; } /* error recovery is not supported at present */ rproc->recovery_disabled = true; drproc = rproc->priv; drproc->rproc = rproc; drproc->dsp_clk = dsp_clk; drproc->dsp_reset = dsp_reset; rproc->has_iommu = false; ret = da8xx_rproc_get_internal_memories(pdev, drproc); if (ret) goto free_rproc; platform_set_drvdata(pdev, rproc); /* everything the ISR needs is now setup, so hook it up */ ret = devm_request_threaded_irq(dev, irq, da8xx_rproc_callback, handle_event, 0, "da8xx-remoteproc", rproc); if (ret) { dev_err(dev, "devm_request_threaded_irq error: %d\n", ret); goto free_rproc; } /* * rproc_add() can end up enabling the DSP's clk with the DSP * *not* in reset, but da8xx_rproc_start() needs the DSP to be * held in reset at the time it is called. */ ret = reset_control_assert(dsp_reset); if (ret) goto free_rproc; drproc->chipsig = chipsig; drproc->bootreg = bootreg; drproc->ack_fxn = irq_data->chip->irq_ack; drproc->irq_data = irq_data; drproc->irq = irq; ret = rproc_add(rproc); if (ret) { dev_err(dev, "rproc_add failed: %d\n", ret); goto free_rproc; } return 0; free_rproc: rproc_free(rproc); free_mem: if (dev->of_node) of_reserved_mem_device_release(dev); return ret; }
static int img_i2s_out_probe(struct platform_device *pdev) { struct img_i2s_out *i2s; struct resource *res; void __iomem *base; int i, ret; unsigned int max_i2s_chan_pow_2; u32 reg; struct device *dev = &pdev->dev; i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); if (!i2s) return -ENOMEM; platform_set_drvdata(pdev, i2s); i2s->dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); i2s->base = base; if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels", &i2s->max_i2s_chan)) { dev_err(&pdev->dev, "No img,i2s-channels property\n"); return -EINVAL; } max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan); i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20); i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(i2s->rst)) { if (PTR_ERR(i2s->rst) != -EPROBE_DEFER) dev_err(&pdev->dev, "No top level reset found\n"); return PTR_ERR(i2s->rst); } i2s->clk_sys = devm_clk_get(&pdev->dev, "sys"); if (IS_ERR(i2s->clk_sys)) { if (PTR_ERR(i2s->clk_sys) != -EPROBE_DEFER) dev_err(dev, "Failed to acquire clock 'sys'\n"); return PTR_ERR(i2s->clk_sys); } i2s->clk_ref = devm_clk_get(&pdev->dev, "ref"); if (IS_ERR(i2s->clk_ref)) { if (PTR_ERR(i2s->clk_ref) != -EPROBE_DEFER) dev_err(dev, "Failed to acquire clock 'ref'\n"); return PTR_ERR(i2s->clk_ref); } i2s->suspend_ch_ctl = devm_kcalloc(dev, i2s->max_i2s_chan, sizeof(*i2s->suspend_ch_ctl), GFP_KERNEL); if (!i2s->suspend_ch_ctl) return -ENOMEM; pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = img_i2s_out_runtime_resume(&pdev->dev); if (ret) goto err_pm_disable; } ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) goto err_suspend; reg = IMG_I2S_OUT_CTL_FRM_SIZE_MASK; img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL); reg = IMG_I2S_OUT_CHAN_CTL_JUST_MASK | IMG_I2S_OUT_CHAN_CTL_LT_MASK | IMG_I2S_OUT_CHAN_CTL_CH_MASK | (8 << IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT); for (i = 0; i < i2s->max_i2s_chan; i++) img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL); img_i2s_out_reset(i2s); pm_runtime_put(&pdev->dev); i2s->active_channels = 1; i2s->dma_data.addr = res->start + IMG_I2S_OUT_TX_FIFO; i2s->dma_data.addr_width = 4; i2s->dma_data.maxburst = 4; i2s->dai_driver.probe = img_i2s_out_dai_probe; i2s->dai_driver.playback.channels_min = 2; i2s->dai_driver.playback.channels_max = i2s->max_i2s_chan * 2; i2s->dai_driver.playback.rates = SNDRV_PCM_RATE_8000_192000; i2s->dai_driver.playback.formats = SNDRV_PCM_FMTBIT_S32_LE; i2s->dai_driver.ops = &img_i2s_out_dai_ops; ret = devm_snd_soc_register_component(&pdev->dev, &img_i2s_out_component, &i2s->dai_driver, 1); if (ret) goto err_suspend; ret = devm_snd_dmaengine_pcm_register(&pdev->dev, &img_i2s_out_dma_config, 0); if (ret) goto err_suspend; return 0; err_suspend: if (!pm_runtime_status_suspended(&pdev->dev)) img_i2s_out_runtime_suspend(&pdev->dev); err_pm_disable: pm_runtime_disable(&pdev->dev); return ret; }
static int sun6i_spi_probe(struct platform_device *pdev) { struct spi_master *master; struct sun6i_spi *sspi; struct resource *res; int ret = 0, irq; master = spi_alloc_master(&pdev->dev, sizeof(struct sun6i_spi)); if (!master) { dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); return -ENOMEM; } platform_set_drvdata(pdev, master); sspi = spi_master_get_devdata(master); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); sspi->base_addr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(sspi->base_addr)) { ret = PTR_ERR(sspi->base_addr); goto err_free_master; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "No spi IRQ specified\n"); ret = -ENXIO; goto err_free_master; } ret = devm_request_irq(&pdev->dev, irq, sun6i_spi_handler, 0, "sun6i-spi", sspi); if (ret) { dev_err(&pdev->dev, "Cannot request IRQ\n"); goto err_free_master; } sspi->master = master; sspi->fifo_depth = (unsigned long)of_device_get_match_data(&pdev->dev); master->max_speed_hz = 100 * 1000 * 1000; master->min_speed_hz = 3 * 1000; master->set_cs = sun6i_spi_set_cs; master->transfer_one = sun6i_spi_transfer_one; master->num_chipselect = 4; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; master->bits_per_word_mask = SPI_BPW_MASK(8); master->dev.of_node = pdev->dev.of_node; master->auto_runtime_pm = true; master->max_transfer_size = sun6i_spi_max_transfer_size; sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); if (IS_ERR(sspi->hclk)) { dev_err(&pdev->dev, "Unable to acquire AHB clock\n"); ret = PTR_ERR(sspi->hclk); goto err_free_master; } sspi->mclk = devm_clk_get(&pdev->dev, "mod"); if (IS_ERR(sspi->mclk)) { dev_err(&pdev->dev, "Unable to acquire module clock\n"); ret = PTR_ERR(sspi->mclk); goto err_free_master; } init_completion(&sspi->done); sspi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(sspi->rstc)) { dev_err(&pdev->dev, "Couldn't get reset controller\n"); ret = PTR_ERR(sspi->rstc); goto err_free_master; } /* * This wake-up/shutdown pattern is to be able to have the * device woken up, even if runtime_pm is disabled */ ret = sun6i_spi_runtime_resume(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Couldn't resume the device\n"); goto err_free_master; } pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_idle(&pdev->dev); ret = devm_spi_register_master(&pdev->dev, master); if (ret) { dev_err(&pdev->dev, "cannot register SPI master\n"); goto err_pm_disable; } return 0; err_pm_disable: pm_runtime_disable(&pdev->dev); sun6i_spi_runtime_suspend(&pdev->dev); err_free_master: spi_master_put(master); return ret; }
static int sdhci_tegra_probe(struct platform_device *pdev) { const struct of_device_id *match; const struct sdhci_tegra_soc_data *soc_data; struct sdhci_host *host; struct sdhci_pltfm_host *pltfm_host; struct sdhci_tegra *tegra_host; struct clk *clk; int rc; match = of_match_device(sdhci_tegra_dt_match, &pdev->dev); if (!match) return -EINVAL; soc_data = match->data; host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*tegra_host)); if (IS_ERR(host)) return PTR_ERR(host); pltfm_host = sdhci_priv(host); tegra_host = sdhci_pltfm_priv(pltfm_host); tegra_host->ddr_signaling = false; tegra_host->pad_calib_required = false; tegra_host->pad_control_available = false; tegra_host->soc_data = soc_data; if (soc_data->nvquirks & NVQUIRK_NEEDS_PAD_CONTROL) { rc = tegra_sdhci_init_pinctrl_info(&pdev->dev, tegra_host); if (rc == 0) host->mmc_host_ops.start_signal_voltage_switch = sdhci_tegra_start_signal_voltage_switch; } /* Hook to periodically rerun pad calibration */ if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB) host->mmc_host_ops.request = tegra_sdhci_request; host->mmc_host_ops.hs400_enhanced_strobe = tegra_sdhci_hs400_enhanced_strobe; rc = mmc_of_parse(host->mmc); if (rc) goto err_parse_dt; if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) host->mmc->caps |= MMC_CAP_1_8V_DDR; tegra_sdhci_parse_pad_autocal_dt(host); tegra_sdhci_parse_tap_and_trim(host); tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", GPIOD_OUT_HIGH); if (IS_ERR(tegra_host->power_gpio)) { rc = PTR_ERR(tegra_host->power_gpio); goto err_power_req; } clk = devm_clk_get(mmc_dev(host->mmc), NULL); if (IS_ERR(clk)) { dev_err(mmc_dev(host->mmc), "clk err\n"); rc = PTR_ERR(clk); goto err_clk_get; } clk_prepare_enable(clk); pltfm_host->clk = clk; tegra_host->rst = devm_reset_control_get_exclusive(&pdev->dev, "sdhci"); if (IS_ERR(tegra_host->rst)) { rc = PTR_ERR(tegra_host->rst); dev_err(&pdev->dev, "failed to get reset control: %d\n", rc); goto err_rst_get; } rc = reset_control_assert(tegra_host->rst); if (rc) goto err_rst_get; usleep_range(2000, 4000); rc = reset_control_deassert(tegra_host->rst); if (rc) goto err_rst_get; usleep_range(2000, 4000); rc = sdhci_add_host(host); if (rc) goto err_add_host; return 0; err_add_host: reset_control_assert(tegra_host->rst); err_rst_get: clk_disable_unprepare(pltfm_host->clk); err_clk_get: err_power_req: err_parse_dt: sdhci_pltfm_free(pdev); return rc; }
static int sunxi_de2_clk_probe(struct platform_device *pdev) { struct resource *res; struct clk *bus_clk, *mod_clk; struct reset_control *rstc; void __iomem *reg; const struct sunxi_ccu_desc *ccu_desc; int ret; ccu_desc = of_device_get_match_data(&pdev->dev); if (!ccu_desc) return -EINVAL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); bus_clk = devm_clk_get(&pdev->dev, "bus"); if (IS_ERR(bus_clk)) { ret = PTR_ERR(bus_clk); if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret); return ret; } mod_clk = devm_clk_get(&pdev->dev, "mod"); if (IS_ERR(mod_clk)) { ret = PTR_ERR(mod_clk); if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "Couldn't get mod clk: %d\n", ret); return ret; } rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(rstc)) { ret = PTR_ERR(rstc); if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "Couldn't get reset control: %d\n", ret); return ret; } /* The clocks need to be enabled for us to access the registers */ ret = clk_prepare_enable(bus_clk); if (ret) { dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret); return ret; } ret = clk_prepare_enable(mod_clk); if (ret) { dev_err(&pdev->dev, "Couldn't enable mod clk: %d\n", ret); goto err_disable_bus_clk; } /* The reset control needs to be asserted for the controls to work */ ret = reset_control_deassert(rstc); if (ret) { dev_err(&pdev->dev, "Couldn't deassert reset control: %d\n", ret); goto err_disable_mod_clk; } ret = sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc); if (ret) goto err_assert_reset; return 0; err_assert_reset: reset_control_assert(rstc); err_disable_mod_clk: clk_disable_unprepare(mod_clk); err_disable_bus_clk: clk_disable_unprepare(bus_clk); return ret; }
static int p2wi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct device_node *childnp; unsigned long parent_clk_freq; u32 clk_freq = 100000; struct resource *r; struct p2wi *p2wi; u32 slave_addr; int clk_div; int irq; int ret; of_property_read_u32(np, "clock-frequency", &clk_freq); if (clk_freq > P2WI_MAX_FREQ) { dev_err(dev, "required clock-frequency (%u Hz) is too high (max = 6MHz)", clk_freq); return -EINVAL; } if (of_get_child_count(np) > 1) { dev_err(dev, "P2WI only supports one slave device\n"); return -EINVAL; } p2wi = devm_kzalloc(dev, sizeof(struct p2wi), GFP_KERNEL); if (!p2wi) return -ENOMEM; p2wi->slave_addr = -1; /* * Authorize a p2wi node without any children to be able to use an * i2c-dev from userpace. * In this case the slave_addr is set to -1 and won't be checked when * launching a P2WI transfer. */ childnp = of_get_next_available_child(np, NULL); if (childnp) { ret = of_property_read_u32(childnp, "reg", &slave_addr); if (ret) { dev_err(dev, "invalid slave address on node %pOF\n", childnp); return -EINVAL; } p2wi->slave_addr = slave_addr; } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); p2wi->regs = devm_ioremap_resource(dev, r); if (IS_ERR(p2wi->regs)) return PTR_ERR(p2wi->regs); strlcpy(p2wi->adapter.name, pdev->name, sizeof(p2wi->adapter.name)); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "failed to retrieve irq: %d\n", irq); return irq; } p2wi->clk = devm_clk_get(dev, NULL); if (IS_ERR(p2wi->clk)) { ret = PTR_ERR(p2wi->clk); dev_err(dev, "failed to retrieve clk: %d\n", ret); return ret; } ret = clk_prepare_enable(p2wi->clk); if (ret) { dev_err(dev, "failed to enable clk: %d\n", ret); return ret; } parent_clk_freq = clk_get_rate(p2wi->clk); p2wi->rstc = devm_reset_control_get_exclusive(dev, NULL); if (IS_ERR(p2wi->rstc)) { ret = PTR_ERR(p2wi->rstc); dev_err(dev, "failed to retrieve reset controller: %d\n", ret); goto err_clk_disable; } ret = reset_control_deassert(p2wi->rstc); if (ret) { dev_err(dev, "failed to deassert reset line: %d\n", ret); goto err_clk_disable; } init_completion(&p2wi->complete); p2wi->adapter.dev.parent = dev; p2wi->adapter.algo = &p2wi_algo; p2wi->adapter.owner = THIS_MODULE; p2wi->adapter.dev.of_node = pdev->dev.of_node; platform_set_drvdata(pdev, p2wi); i2c_set_adapdata(&p2wi->adapter, p2wi); ret = devm_request_irq(dev, irq, p2wi_interrupt, 0, pdev->name, p2wi); if (ret) { dev_err(dev, "can't register interrupt handler irq%d: %d\n", irq, ret); goto err_reset_assert; } writel(P2WI_CTRL_SOFT_RST, p2wi->regs + P2WI_CTRL); clk_div = parent_clk_freq / clk_freq; if (!clk_div) { dev_warn(dev, "clock-frequency is too high, setting it to %lu Hz\n", parent_clk_freq); clk_div = 1; } else if (clk_div > P2WI_CCR_MAX_CLK_DIV) { dev_warn(dev, "clock-frequency is too low, setting it to %lu Hz\n", parent_clk_freq / P2WI_CCR_MAX_CLK_DIV); clk_div = P2WI_CCR_MAX_CLK_DIV; } writel(P2WI_CCR_SDA_OUT_DELAY(1) | P2WI_CCR_CLK_DIV(clk_div), p2wi->regs + P2WI_CCR); ret = i2c_add_adapter(&p2wi->adapter); if (!ret) return 0; err_reset_assert: reset_control_assert(p2wi->rstc); err_clk_disable: clk_disable_unprepare(p2wi->clk); return ret; }
static int meson_dw_hdmi_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); const struct meson_dw_hdmi_data *match; struct meson_dw_hdmi *meson_dw_hdmi; struct drm_device *drm = data; struct meson_drm *priv = drm->dev_private; struct dw_hdmi_plat_data *dw_plat_data; struct drm_encoder *encoder; struct resource *res; int irq; int ret; DRM_DEBUG_DRIVER("\n"); if (!meson_hdmi_connector_is_available(dev)) { dev_info(drm->dev, "HDMI Output connector not available\n"); return -ENODEV; } match = of_device_get_match_data(&pdev->dev); if (!match) { dev_err(&pdev->dev, "failed to get match data\n"); return -ENODEV; } meson_dw_hdmi = devm_kzalloc(dev, sizeof(*meson_dw_hdmi), GFP_KERNEL); if (!meson_dw_hdmi) return -ENOMEM; meson_dw_hdmi->priv = priv; meson_dw_hdmi->dev = dev; meson_dw_hdmi->data = match; dw_plat_data = &meson_dw_hdmi->dw_plat_data; encoder = &meson_dw_hdmi->encoder; meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi"); if (IS_ERR(meson_dw_hdmi->hdmi_supply)) { if (PTR_ERR(meson_dw_hdmi->hdmi_supply) == -EPROBE_DEFER) return -EPROBE_DEFER; meson_dw_hdmi->hdmi_supply = NULL; } else { ret = regulator_enable(meson_dw_hdmi->hdmi_supply); if (ret) return ret; } meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, "hdmitx_apb"); if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) { dev_err(dev, "Failed to get hdmitx_apb reset\n"); return PTR_ERR(meson_dw_hdmi->hdmitx_apb); } meson_dw_hdmi->hdmitx_ctrl = devm_reset_control_get_exclusive(dev, "hdmitx"); if (IS_ERR(meson_dw_hdmi->hdmitx_ctrl)) { dev_err(dev, "Failed to get hdmitx reset\n"); return PTR_ERR(meson_dw_hdmi->hdmitx_ctrl); } meson_dw_hdmi->hdmitx_phy = devm_reset_control_get_exclusive(dev, "hdmitx_phy"); if (IS_ERR(meson_dw_hdmi->hdmitx_phy)) { dev_err(dev, "Failed to get hdmitx_phy reset\n"); return PTR_ERR(meson_dw_hdmi->hdmitx_phy); } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res); if (IS_ERR(meson_dw_hdmi->hdmitx)) return PTR_ERR(meson_dw_hdmi->hdmitx); meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr"); if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) { dev_err(dev, "Unable to get HDMI pclk\n"); return PTR_ERR(meson_dw_hdmi->hdmi_pclk); } clk_prepare_enable(meson_dw_hdmi->hdmi_pclk); meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci"); if (IS_ERR(meson_dw_hdmi->venci_clk)) { dev_err(dev, "Unable to get venci clk\n"); return PTR_ERR(meson_dw_hdmi->venci_clk); } clk_prepare_enable(meson_dw_hdmi->venci_clk); dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, &meson_dw_hdmi_regmap_config); if (IS_ERR(dw_plat_data->regm)) return PTR_ERR(dw_plat_data->regm); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "Failed to get hdmi top irq\n"); return irq; } ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq, dw_hdmi_top_thread_irq, IRQF_SHARED, "dw_hdmi_top_irq", meson_dw_hdmi); if (ret) { dev_err(dev, "Failed to request hdmi top irq\n"); return ret; } /* Encoder */ drm_encoder_helper_add(encoder, &meson_venc_hdmi_encoder_helper_funcs); ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs, DRM_MODE_ENCODER_TMDS, "meson_hdmi"); if (ret) { dev_err(priv->dev, "Failed to init HDMI encoder\n"); return ret; } encoder->possible_crtcs = BIT(0); DRM_DEBUG_DRIVER("encoder initialized\n"); /* Enable clocks */ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); /* Bring HDMITX MEM output of power down */ regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); /* Reset HDMITX APB & TX & PHY */ reset_control_reset(meson_dw_hdmi->hdmitx_apb); reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); reset_control_reset(meson_dw_hdmi->hdmitx_phy); /* Enable APB3 fail on error */ if (!meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) { writel_bits_relaxed(BIT(15), BIT(15), meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG); writel_bits_relaxed(BIT(15), BIT(15), meson_dw_hdmi->hdmitx + HDMITX_DWC_CTRL_REG); } /* Bring out of reset */ meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_SW_RESET, 0); msleep(20); meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_CLK_CNTL, 0xff); /* Enable HDMI-TX Interrupt */ meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, HDMITX_TOP_INTR_CORE); meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_MASKN, HDMITX_TOP_INTR_CORE); /* Bridge / Connector */ dw_plat_data->mode_valid = dw_hdmi_mode_valid; dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; dw_plat_data->phy_name = "meson_dw_hdmi_phy"; dw_plat_data->phy_data = meson_dw_hdmi; dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24; dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; platform_set_drvdata(pdev, meson_dw_hdmi); meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder, &meson_dw_hdmi->dw_plat_data); if (IS_ERR(meson_dw_hdmi->hdmi)) return PTR_ERR(meson_dw_hdmi->hdmi); DRM_DEBUG_DRIVER("HDMI controller initialized\n"); return 0; }
static int tegra_uart_probe(struct platform_device *pdev) { struct tegra_uart_port *tup; struct uart_port *u; struct resource *resource; int ret; const struct tegra_uart_chip_data *cdata; const struct of_device_id *match; match = of_match_device(tegra_uart_of_match, &pdev->dev); if (!match) { dev_err(&pdev->dev, "Error: No device match found\n"); return -ENODEV; } cdata = match->data; tup = devm_kzalloc(&pdev->dev, sizeof(*tup), GFP_KERNEL); if (!tup) { dev_err(&pdev->dev, "Failed to allocate memory for tup\n"); return -ENOMEM; } ret = tegra_uart_parse_dt(pdev, tup); if (ret < 0) return ret; u = &tup->uport; u->dev = &pdev->dev; u->ops = &tegra_uart_ops; u->type = PORT_TEGRA; u->fifosize = 32; tup->cdata = cdata; platform_set_drvdata(pdev, tup); resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!resource) { dev_err(&pdev->dev, "No IO memory resource\n"); return -ENODEV; } u->mapbase = resource->start; u->membase = devm_ioremap_resource(&pdev->dev, resource); if (IS_ERR(u->membase)) return PTR_ERR(u->membase); tup->uart_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(tup->uart_clk)) { dev_err(&pdev->dev, "Couldn't get the clock\n"); return PTR_ERR(tup->uart_clk); } tup->rst = devm_reset_control_get_exclusive(&pdev->dev, "serial"); if (IS_ERR(tup->rst)) { dev_err(&pdev->dev, "Couldn't get the reset\n"); return PTR_ERR(tup->rst); } u->iotype = UPIO_MEM32; ret = platform_get_irq(pdev, 0); if (ret < 0) { dev_err(&pdev->dev, "Couldn't get IRQ\n"); return ret; } u->irq = ret; u->regshift = 2; ret = uart_add_one_port(&tegra_uart_driver, u); if (ret < 0) { dev_err(&pdev->dev, "Failed to add uart port, err %d\n", ret); return ret; } return ret; }
static int img_spdif_out_probe(struct platform_device *pdev) { struct img_spdif_out *spdif; struct resource *res; void __iomem *base; int ret; struct device *dev = &pdev->dev; spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL); if (!spdif) return -ENOMEM; platform_set_drvdata(pdev, spdif); spdif->dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); spdif->base = base; spdif->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(spdif->rst)) { if (PTR_ERR(spdif->rst) != -EPROBE_DEFER) dev_err(&pdev->dev, "No top level reset found\n"); return PTR_ERR(spdif->rst); } spdif->clk_sys = devm_clk_get(&pdev->dev, "sys"); if (IS_ERR(spdif->clk_sys)) { if (PTR_ERR(spdif->clk_sys) != -EPROBE_DEFER) dev_err(dev, "Failed to acquire clock 'sys'\n"); return PTR_ERR(spdif->clk_sys); } spdif->clk_ref = devm_clk_get(&pdev->dev, "ref"); if (IS_ERR(spdif->clk_ref)) { if (PTR_ERR(spdif->clk_ref) != -EPROBE_DEFER) dev_err(dev, "Failed to acquire clock 'ref'\n"); return PTR_ERR(spdif->clk_ref); } ret = clk_prepare_enable(spdif->clk_sys); if (ret) return ret; img_spdif_out_writel(spdif, IMG_SPDIF_OUT_CTL_FS_MASK, IMG_SPDIF_OUT_CTL); img_spdif_out_reset(spdif); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = img_spdif_out_resume(&pdev->dev); if (ret) goto err_pm_disable; } spin_lock_init(&spdif->lock); spdif->dma_data.addr = res->start + IMG_SPDIF_OUT_TX_FIFO; spdif->dma_data.addr_width = 4; spdif->dma_data.maxburst = 4; ret = devm_snd_soc_register_component(&pdev->dev, &img_spdif_out_component, &img_spdif_out_dai, 1); if (ret) goto err_suspend; ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); if (ret) goto err_suspend; dev_dbg(&pdev->dev, "Probe successful\n"); return 0; err_suspend: if (!pm_runtime_status_suspended(&pdev->dev)) img_spdif_out_suspend(&pdev->dev); err_pm_disable: pm_runtime_disable(&pdev->dev); clk_disable_unprepare(spdif->clk_sys); return ret; }
static int stm32_i2s_parse_dt(struct platform_device *pdev, struct stm32_i2s_data *i2s) { struct device_node *np = pdev->dev.of_node; const struct of_device_id *of_id; struct reset_control *rst; struct resource *res; int irq, ret; if (!np) return -ENODEV; of_id = of_match_device(stm32_i2s_ids, &pdev->dev); if (of_id) i2s->regmap_conf = (const struct regmap_config *)of_id->data; else return -EINVAL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2s->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(i2s->base)) return PTR_ERR(i2s->base); i2s->phys_addr = res->start; /* Get clocks */ i2s->pclk = devm_clk_get(&pdev->dev, "pclk"); if (IS_ERR(i2s->pclk)) { dev_err(&pdev->dev, "Could not get pclk\n"); return PTR_ERR(i2s->pclk); } i2s->i2sclk = devm_clk_get(&pdev->dev, "i2sclk"); if (IS_ERR(i2s->i2sclk)) { dev_err(&pdev->dev, "Could not get i2sclk\n"); return PTR_ERR(i2s->i2sclk); } i2s->x8kclk = devm_clk_get(&pdev->dev, "x8k"); if (IS_ERR(i2s->x8kclk)) { dev_err(&pdev->dev, "missing x8k parent clock\n"); return PTR_ERR(i2s->x8kclk); } i2s->x11kclk = devm_clk_get(&pdev->dev, "x11k"); if (IS_ERR(i2s->x11kclk)) { dev_err(&pdev->dev, "missing x11k parent clock\n"); return PTR_ERR(i2s->x11kclk); } /* Get irqs */ irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); return -ENOENT; } ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, IRQF_ONESHOT, dev_name(&pdev->dev), i2s); if (ret) { dev_err(&pdev->dev, "irq request returned %d\n", ret); return ret; } /* Reset */ rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); reset_control_deassert(rst); } return 0; }
static int st_dwc3_probe(struct platform_device *pdev) { struct st_dwc3 *dwc3_data; struct resource *res; struct device *dev = &pdev->dev; struct device_node *node = dev->of_node, *child; struct platform_device *child_pdev; struct regmap *regmap; int ret; dwc3_data = devm_kzalloc(dev, sizeof(*dwc3_data), GFP_KERNEL); if (!dwc3_data) return -ENOMEM; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg-glue"); dwc3_data->glue_base = devm_ioremap_resource(dev, res); if (IS_ERR(dwc3_data->glue_base)) return PTR_ERR(dwc3_data->glue_base); regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg"); if (IS_ERR(regmap)) return PTR_ERR(regmap); dwc3_data->dev = dev; dwc3_data->regmap = regmap; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "syscfg-reg"); if (!res) { ret = -ENXIO; goto undo_platform_dev_alloc; } dwc3_data->syscfg_reg_off = res->start; dev_vdbg(&pdev->dev, "glue-logic addr 0x%pK, syscfg-reg offset 0x%x\n", dwc3_data->glue_base, dwc3_data->syscfg_reg_off); dwc3_data->rstc_pwrdn = devm_reset_control_get_exclusive(dev, "powerdown"); if (IS_ERR(dwc3_data->rstc_pwrdn)) { dev_err(&pdev->dev, "could not get power controller\n"); ret = PTR_ERR(dwc3_data->rstc_pwrdn); goto undo_platform_dev_alloc; } /* Manage PowerDown */ reset_control_deassert(dwc3_data->rstc_pwrdn); dwc3_data->rstc_rst = devm_reset_control_get_shared(dev, "softreset"); if (IS_ERR(dwc3_data->rstc_rst)) { dev_err(&pdev->dev, "could not get reset controller\n"); ret = PTR_ERR(dwc3_data->rstc_rst); goto undo_powerdown; } /* Manage SoftReset */ reset_control_deassert(dwc3_data->rstc_rst); child = of_get_child_by_name(node, "dwc3"); if (!child) { dev_err(&pdev->dev, "failed to find dwc3 core node\n"); ret = -ENODEV; goto undo_softreset; } /* Allocate and initialize the core */ ret = of_platform_populate(node, NULL, NULL, dev); if (ret) { dev_err(dev, "failed to add dwc3 core\n"); goto undo_softreset; } child_pdev = of_find_device_by_node(child); if (!child_pdev) { dev_err(dev, "failed to find dwc3 core device\n"); ret = -ENODEV; goto undo_softreset; } dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev); /* * Configure the USB port as device or host according to the static * configuration passed from DT. * DRD is the only mode currently supported so this will be enhanced * as soon as OTG is available. */ ret = st_dwc3_drd_init(dwc3_data); if (ret) { dev_err(dev, "drd initialisation failed\n"); goto undo_softreset; } /* ST glue logic init */ st_dwc3_init(dwc3_data); platform_set_drvdata(pdev, dwc3_data); return 0; undo_softreset: reset_control_assert(dwc3_data->rstc_rst); undo_powerdown: reset_control_assert(dwc3_data->rstc_pwrdn); undo_platform_dev_alloc: platform_device_put(pdev); return ret; }