/* * intel_sst_probe - PCI probe function * * @pci: PCI device structure * @pci_id: PCI device ID structure * */ static int intel_sst_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { int ret = 0; struct intel_sst_drv *sst_drv_ctx; struct sst_platform_info *sst_pdata = pci->dev.platform_data; dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device); ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device); if (ret < 0) return ret; sst_drv_ctx->pdata = sst_pdata; sst_drv_ctx->irq_num = pci->irq; snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name), "%s%04x%s", "fw_sst_", sst_drv_ctx->dev_id, ".bin"); ret = sst_context_init(sst_drv_ctx); if (ret < 0) return ret; /* Init the device */ ret = pcim_enable_device(pci); if (ret) { dev_err(sst_drv_ctx->dev, "device can't be enabled. Returned err: %d\n", ret); goto do_free_drv_ctx; } sst_drv_ctx->pci = pci_dev_get(pci); ret = sst_platform_get_resources(sst_drv_ctx); if (ret < 0) goto do_free_drv_ctx; pci_set_drvdata(pci, sst_drv_ctx); sst_configure_runtime_pm(sst_drv_ctx); return ret; do_free_drv_ctx: sst_context_cleanup(sst_drv_ctx); dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); 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; }
int __devinit sst_acpi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; acpi_handle handle = ACPI_HANDLE(dev); struct acpi_device *device; const char *hid; int i, ret = 0; struct sst_probe_info *info; struct intel_sst_drv *ctx; ret = acpi_bus_get_device(handle, &device); if (ret) { pr_err("%s: could not get acpi device - %d\n", __func__, ret); return -ENODEV; } if (acpi_bus_get_status(device) || !device->status.present) { pr_err("%s: device has invalid status", __func__); return -ENODEV; } hid = acpi_device_hid(device); pr_debug("%s for %s", __func__, hid); ret = sst_alloc_drv_context(dev); if (ret) return ret; ctx = sst_drv_ctx; ctx->dev = dev; ctx->pci_id = SST_BYT_PCI_ID; /* need to save shim registers in BYT */ ctx->shim_regs64 = devm_kzalloc(dev, sizeof(*ctx->shim_regs64), GFP_KERNEL); if (!ctx->shim_regs64) return -ENOMEM; ctx->use_32bit_ops = true; ret = sst_driver_ops(ctx); if (ret != 0) return -EINVAL; sst_init_locks(ctx); ctx->stream_cnt = 0; ctx->fw_in_mem = NULL; ctx->use_dma = 1; ctx->use_lli = 1; if (sst_workqueue_init(ctx)) goto do_free_wq; info = sst_get_acpi_driver_data(hid); if (!info) return -EINVAL; memcpy(&ctx->info, info, sizeof(ctx->info)); ctx->ipc_reg.ipcx = SST_PRH_IPCX; ctx->ipc_reg.ipcd = SST_PRH_IPCD; pr_debug("Got drv data max stream %d\n", ctx->info.max_streams); for (i = 1; i <= ctx->info.max_streams; i++) { struct stream_info *stream = &ctx->streams[i]; mutex_init(&stream->lock); } ret = sst_platform_get_resources(ctx, pdev); if (ret) goto do_free_wq; /*Register LPE Control as misc driver*/ ret = misc_register(&lpe_ctrl); if (ret) { pr_err("couldn't register control device\n"); goto do_free_wq; } /* mask all SSP and DMA interrupts to IA - enable when needed */ sst_shim_write64(ctx->shim, SST_IMRX, 0xFFFF0038); if (ctx->use_32bit_ops) { pr_debug("allocate mem for context save/restore\n "); /*allocate mem for fw context save during suspend*/ ctx->fw_cntx = devm_kzalloc(ctx->dev, FW_CONTEXT_MEM, GFP_KERNEL); if (!ctx->fw_cntx) { ret = -ENOMEM; goto do_free_misc; } /*setting zero as that is valid mem to restore*/ ctx->fw_cntx_size = 0; } platform_set_drvdata(pdev, ctx); pm_runtime_enable(dev); register_sst(dev); sst_debugfs_init(ctx); sst_set_fw_state_locked(ctx, SST_UN_INIT); sst_save_shim64(ctx, ctx->shim, ctx->shim_regs64); pr_info("%s successfully done!\n", __func__); return ret; do_free_misc: misc_deregister(&lpe_ctrl); do_free_wq: sst_destroy_workqueue(ctx); sst_drv_ctx = NULL; platform_set_drvdata(pdev, NULL); pr_err("%s: failed with %d\n", __func__, ret); return ret; }
int sst_acpi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; acpi_handle handle = ACPI_HANDLE(dev); struct acpi_device *device; const char *hid; int i, ret = 0; struct intel_sst_drv *ctx; ret = acpi_bus_get_device(handle, &device); if (ret) { pr_err("%s: could not get acpi device - %d\n", __func__, ret); return -ENODEV; } if (acpi_bus_get_status(device) || !device->status.present) { pr_err("%s: device has invalid status", __func__); return -ENODEV; } hid = acpi_device_hid(device); pr_debug("%s for %s", __func__, hid); ret = sst_alloc_drv_context(dev); if (ret) return ret; ctx = sst_drv_ctx; ctx->dev = dev; ctx->hid = hid; ret = sst_platform_get_resources(hid, ctx, pdev); if (ret) return ret; /* need to save shim registers in BYT */ ctx->shim_regs64 = devm_kzalloc(dev, sizeof(*ctx->shim_regs64), GFP_KERNEL); if (!ctx->shim_regs64) return -ENOMEM; ret = sst_driver_ops(ctx); if (ret != 0) return -EINVAL; sst_init_locks(ctx); ctx->stream_cnt = 0; ctx->fw_in_mem = NULL; ctx->use_dma = 1; ctx->use_lli = 1; if (sst_workqueue_init(ctx)) goto do_free_wq; ctx->pdata = sst_get_acpi_driver_data(hid); if (!ctx->pdata) return -EINVAL; if (INTEL_MID_BOARD(3, TABLET, BYT, BLK, PRO, CRV2)) { /* BYT-CR V2 has only mono speaker, while * byt has stereo speaker, for both * HID is same, so platform data also is * same, hence overriding bdata based on spid */ ctx->pdata->bdata = &sst_byt_crv2_bdata; pr_info("Overriding bdata for byt-crv2\n"); } ctx->use_32bit_ops = ctx->pdata->ipc_info->use_32bit_ops; ctx->mailbox_recv_offset = ctx->pdata->ipc_info->mbox_recv_off; memcpy(&ctx->info, ctx->pdata->probe_data, sizeof(ctx->info)); ctx->ipc_reg.ipcx = SST_IPCX + ctx->pdata->ipc_info->ipc_offset; ctx->ipc_reg.ipcd = SST_IPCD + ctx->pdata->ipc_info->ipc_offset; pr_debug("Got drv data max stream %d\n", ctx->info.max_streams); for (i = 1; i <= ctx->info.max_streams; i++) { struct stream_info *stream = &ctx->streams[i]; mutex_init(&stream->lock); } ret = sst_request_firmware_async(ctx); if (ret) { pr_err("Firmware download failed:%d\n", ret); goto do_free_wq; } ret = devm_request_threaded_irq(ctx->dev, ctx->irq_num, ctx->ops->interrupt, ctx->ops->irq_thread, 0, SST_DRV_NAME, ctx); if (ret) return ret; pr_debug("Registered IRQ %#x\n", ctx->irq_num); /*Register LPE Control as misc driver*/ ret = misc_register(&lpe_ctrl); if (ret) { pr_err("couldn't register control device\n"); goto do_free_wq; } /* mask all SSP and DMA irq to IA - enabled in acpi kernel driver */ sst_shim_write64(ctx->shim, SST_IMRX, 0xFFFF0038); if (ctx->use_32bit_ops) { pr_debug("allocate mem for context save/restore\n "); /*allocate mem for fw context save during suspend*/ ctx->fw_cntx = devm_kzalloc(ctx->dev, FW_CONTEXT_MEM, GFP_KERNEL); if (!ctx->fw_cntx) { ret = -ENOMEM; goto do_free_misc; } /*setting zero as that is valid mem to restore*/ ctx->fw_cntx_size = 0; } platform_set_drvdata(pdev, ctx); pm_runtime_set_active(dev); pm_runtime_enable(dev); register_sst(dev); sst_debugfs_init(ctx); sst_set_fw_state_locked(ctx, SST_UN_INIT); sst_save_shim64(ctx, ctx->shim, ctx->shim_regs64); pr_info("%s successfully done!\n", __func__); return ret; do_free_misc: misc_deregister(&lpe_ctrl); do_free_wq: sst_destroy_workqueue(ctx); sst_drv_ctx = NULL; platform_set_drvdata(pdev, NULL); pr_err("%s: failed with %d\n", __func__, ret); return ret; }