Exemplo n.º 1
0
/*
 * 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;
}
Exemplo n.º 2
0
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;
}