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; }