static int sst_acpi_probe(struct platform_device *pdev) { const struct acpi_device_id *id; struct device *dev = &pdev->dev; struct sst_acpi_priv *sst_acpi; struct sst_pdata *sst_pdata; struct sst_acpi_mach *mach; struct sst_acpi_desc *desc; struct resource *mmio; int ret = 0; sst_acpi = devm_kzalloc(dev, sizeof(*sst_acpi), GFP_KERNEL); if (sst_acpi == NULL) return -ENOMEM; id = acpi_match_device(dev->driver->acpi_match_table, dev); if (!id) return -ENODEV; desc = (struct sst_acpi_desc *)id->driver_data; mach = sst_acpi_find_machine(desc->machines); if (mach == NULL) { dev_err(dev, "No matching ASoC machine driver found\n"); return -ENODEV; } sst_pdata = &sst_acpi->sst_pdata; sst_pdata->id = desc->sst_id; sst_acpi->desc = desc; sst_acpi->mach = mach; if (desc->resindex_dma_base >= 0) { sst_pdata->dma_engine = desc->dma_engine; sst_pdata->dma_base = desc->resindex_dma_base; sst_pdata->dma_size = desc->dma_size; } if (desc->irqindex_host_ipc >= 0) sst_pdata->irq = platform_get_irq(pdev, desc->irqindex_host_ipc); if (desc->resindex_lpe_base >= 0) { mmio = platform_get_resource(pdev, IORESOURCE_MEM, desc->resindex_lpe_base); if (mmio) { sst_pdata->lpe_base = mmio->start; sst_pdata->lpe_size = resource_size(mmio); } } if (desc->resindex_pcicfg_base >= 0) { mmio = platform_get_resource(pdev, IORESOURCE_MEM, desc->resindex_pcicfg_base); if (mmio) { sst_pdata->pcicfg_base = mmio->start; sst_pdata->pcicfg_size = resource_size(mmio); } } if (desc->resindex_fw_base >= 0) { mmio = platform_get_resource(pdev, IORESOURCE_MEM, desc->resindex_fw_base); if (mmio) { sst_pdata->fw_base = mmio->start; sst_pdata->fw_size = resource_size(mmio); } } platform_set_drvdata(pdev, sst_acpi); /* register machine driver */ sst_acpi->pdev_mach = platform_device_register_data(dev, mach->drv_name, -1, sst_pdata, sizeof(*sst_pdata)); if (IS_ERR(sst_acpi->pdev_mach)) return PTR_ERR(sst_acpi->pdev_mach); /* continue SST probing after firmware is loaded */ ret = request_firmware_nowait(THIS_MODULE, true, mach->fw_filename, dev, GFP_KERNEL, pdev, sst_acpi_fw_cb); if (ret) platform_device_unregister(sst_acpi->pdev_mach); return ret; }
static int sst_acpi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int ret = 0; struct intel_sst_drv *ctx; const struct acpi_device_id *id; struct sst_acpi_mach *mach; struct platform_device *mdev; struct platform_device *plat_dev; struct sst_platform_info *pdata; unsigned int dev_id; id = acpi_match_device(dev->driver->acpi_match_table, dev); if (!id) return -ENODEV; dev_dbg(dev, "for %s", id->id); mach = (struct sst_acpi_mach *)id->driver_data; mach = sst_acpi_find_machine(mach); if (mach == NULL) { dev_err(dev, "No matching machine driver found\n"); return -ENODEV; } pdata = mach->pdata; ret = kstrtouint(id->id, 16, &dev_id); if (ret < 0) { dev_err(dev, "Unique device id conversion error: %d\n", ret); return ret; } dev_dbg(dev, "ACPI device id: %x\n", dev_id); plat_dev = platform_device_register_data(dev, pdata->platform, -1, NULL, 0); if (IS_ERR(plat_dev)) { dev_err(dev, "Failed to create machine device: %s\n", pdata->platform); return PTR_ERR(plat_dev); } /* * Create platform device for sst machine driver, * pass machine info as pdata */ mdev = platform_device_register_data(dev, mach->drv_name, -1, (const void *)mach, sizeof(*mach)); if (IS_ERR(mdev)) { dev_err(dev, "Failed to create machine device: %s\n", mach->drv_name); return PTR_ERR(mdev); } ret = sst_alloc_drv_context(&ctx, dev, dev_id); if (ret < 0) return ret; /* Fill sst platform data */ ctx->pdata = pdata; strcpy(ctx->firmware_name, mach->fw_filename); ret = sst_platform_get_resources(ctx); if (ret) return ret; ret = sst_context_init(ctx); if (ret < 0) return ret; /* need to save shim registers in BYT */ ctx->shim_regs64 = devm_kzalloc(ctx->dev, sizeof(*ctx->shim_regs64), GFP_KERNEL); if (!ctx->shim_regs64) { ret = -ENOMEM; goto do_sst_cleanup; } sst_configure_runtime_pm(ctx); platform_set_drvdata(pdev, ctx); return ret; do_sst_cleanup: sst_context_cleanup(ctx); platform_set_drvdata(pdev, NULL); dev_err(ctx->dev, "failed with %d\n", ret); return ret; }