18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * sst_acpi.c - SST (LPE) driver init file for ACPI enumeration.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2013, Intel Corporation.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *  Authors:	Ramesh Babu K V <Ramesh.Babu@intel.com>
88c2ecf20Sopenharmony_ci *  Authors:	Omair Mohammed Abdullah <omair.m.abdullah@intel.com>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/module.h>
128c2ecf20Sopenharmony_ci#include <linux/fs.h>
138c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
148c2ecf20Sopenharmony_ci#include <linux/slab.h>
158c2ecf20Sopenharmony_ci#include <linux/io.h>
168c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
178c2ecf20Sopenharmony_ci#include <linux/firmware.h>
188c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h>
198c2ecf20Sopenharmony_ci#include <linux/pm_qos.h>
208c2ecf20Sopenharmony_ci#include <linux/dmi.h>
218c2ecf20Sopenharmony_ci#include <linux/acpi.h>
228c2ecf20Sopenharmony_ci#include <asm/platform_sst_audio.h>
238c2ecf20Sopenharmony_ci#include <sound/core.h>
248c2ecf20Sopenharmony_ci#include <sound/soc.h>
258c2ecf20Sopenharmony_ci#include <sound/compress_driver.h>
268c2ecf20Sopenharmony_ci#include <acpi/acbuffer.h>
278c2ecf20Sopenharmony_ci#include <acpi/platform/acenv.h>
288c2ecf20Sopenharmony_ci#include <acpi/platform/aclinux.h>
298c2ecf20Sopenharmony_ci#include <acpi/actypes.h>
308c2ecf20Sopenharmony_ci#include <acpi/acpi_bus.h>
318c2ecf20Sopenharmony_ci#include <sound/soc-acpi.h>
328c2ecf20Sopenharmony_ci#include <sound/soc-acpi-intel-match.h>
338c2ecf20Sopenharmony_ci#include "../sst-mfld-platform.h"
348c2ecf20Sopenharmony_ci#include "../../common/soc-intel-quirks.h"
358c2ecf20Sopenharmony_ci#include "sst.h"
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/* LPE viewpoint addresses */
388c2ecf20Sopenharmony_ci#define SST_BYT_IRAM_PHY_START	0xff2c0000
398c2ecf20Sopenharmony_ci#define SST_BYT_IRAM_PHY_END	0xff2d4000
408c2ecf20Sopenharmony_ci#define SST_BYT_DRAM_PHY_START	0xff300000
418c2ecf20Sopenharmony_ci#define SST_BYT_DRAM_PHY_END	0xff320000
428c2ecf20Sopenharmony_ci#define SST_BYT_IMR_VIRT_START	0xc0000000 /* virtual addr in LPE */
438c2ecf20Sopenharmony_ci#define SST_BYT_IMR_VIRT_END	0xc01fffff
448c2ecf20Sopenharmony_ci#define SST_BYT_SHIM_PHY_ADDR	0xff340000
458c2ecf20Sopenharmony_ci#define SST_BYT_MBOX_PHY_ADDR	0xff344000
468c2ecf20Sopenharmony_ci#define SST_BYT_DMA0_PHY_ADDR	0xff298000
478c2ecf20Sopenharmony_ci#define SST_BYT_DMA1_PHY_ADDR	0xff29c000
488c2ecf20Sopenharmony_ci#define SST_BYT_SSP0_PHY_ADDR	0xff2a0000
498c2ecf20Sopenharmony_ci#define SST_BYT_SSP2_PHY_ADDR	0xff2a2000
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci#define BYT_FW_MOD_TABLE_OFFSET	0x80000
528c2ecf20Sopenharmony_ci#define BYT_FW_MOD_TABLE_SIZE	0x100
538c2ecf20Sopenharmony_ci#define BYT_FW_MOD_OFFSET	(BYT_FW_MOD_TABLE_OFFSET + BYT_FW_MOD_TABLE_SIZE)
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistatic const struct sst_info byt_fwparse_info = {
568c2ecf20Sopenharmony_ci	.use_elf	= false,
578c2ecf20Sopenharmony_ci	.max_streams	= 25,
588c2ecf20Sopenharmony_ci	.iram_start	= SST_BYT_IRAM_PHY_START,
598c2ecf20Sopenharmony_ci	.iram_end	= SST_BYT_IRAM_PHY_END,
608c2ecf20Sopenharmony_ci	.iram_use	= true,
618c2ecf20Sopenharmony_ci	.dram_start	= SST_BYT_DRAM_PHY_START,
628c2ecf20Sopenharmony_ci	.dram_end	= SST_BYT_DRAM_PHY_END,
638c2ecf20Sopenharmony_ci	.dram_use	= true,
648c2ecf20Sopenharmony_ci	.imr_start	= SST_BYT_IMR_VIRT_START,
658c2ecf20Sopenharmony_ci	.imr_end	= SST_BYT_IMR_VIRT_END,
668c2ecf20Sopenharmony_ci	.imr_use	= true,
678c2ecf20Sopenharmony_ci	.mailbox_start	= SST_BYT_MBOX_PHY_ADDR,
688c2ecf20Sopenharmony_ci	.num_probes	= 0,
698c2ecf20Sopenharmony_ci	.lpe_viewpt_rqd  = true,
708c2ecf20Sopenharmony_ci};
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistatic const struct sst_ipc_info byt_ipc_info = {
738c2ecf20Sopenharmony_ci	.ipc_offset = 0,
748c2ecf20Sopenharmony_ci	.mbox_recv_off = 0x400,
758c2ecf20Sopenharmony_ci};
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_cistatic const struct sst_lib_dnld_info  byt_lib_dnld_info = {
788c2ecf20Sopenharmony_ci	.mod_base           = SST_BYT_IMR_VIRT_START,
798c2ecf20Sopenharmony_ci	.mod_end            = SST_BYT_IMR_VIRT_END,
808c2ecf20Sopenharmony_ci	.mod_table_offset   = BYT_FW_MOD_TABLE_OFFSET,
818c2ecf20Sopenharmony_ci	.mod_table_size     = BYT_FW_MOD_TABLE_SIZE,
828c2ecf20Sopenharmony_ci	.mod_ddr_dnld       = false,
838c2ecf20Sopenharmony_ci};
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic const struct sst_res_info byt_rvp_res_info = {
868c2ecf20Sopenharmony_ci	.shim_offset = 0x140000,
878c2ecf20Sopenharmony_ci	.shim_size = 0x000100,
888c2ecf20Sopenharmony_ci	.shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
898c2ecf20Sopenharmony_ci	.ssp0_offset = 0xa0000,
908c2ecf20Sopenharmony_ci	.ssp0_size = 0x1000,
918c2ecf20Sopenharmony_ci	.dma0_offset = 0x98000,
928c2ecf20Sopenharmony_ci	.dma0_size = 0x4000,
938c2ecf20Sopenharmony_ci	.dma1_offset = 0x9c000,
948c2ecf20Sopenharmony_ci	.dma1_size = 0x4000,
958c2ecf20Sopenharmony_ci	.iram_offset = 0x0c0000,
968c2ecf20Sopenharmony_ci	.iram_size = 0x14000,
978c2ecf20Sopenharmony_ci	.dram_offset = 0x100000,
988c2ecf20Sopenharmony_ci	.dram_size = 0x28000,
998c2ecf20Sopenharmony_ci	.mbox_offset = 0x144000,
1008c2ecf20Sopenharmony_ci	.mbox_size = 0x1000,
1018c2ecf20Sopenharmony_ci	.acpi_lpe_res_index = 0,
1028c2ecf20Sopenharmony_ci	.acpi_ddr_index = 2,
1038c2ecf20Sopenharmony_ci	.acpi_ipc_irq_index = 5,
1048c2ecf20Sopenharmony_ci};
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci/* BYTCR has different BIOS from BYT */
1078c2ecf20Sopenharmony_cistatic const struct sst_res_info bytcr_res_info = {
1088c2ecf20Sopenharmony_ci	.shim_offset = 0x140000,
1098c2ecf20Sopenharmony_ci	.shim_size = 0x000100,
1108c2ecf20Sopenharmony_ci	.shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
1118c2ecf20Sopenharmony_ci	.ssp0_offset = 0xa0000,
1128c2ecf20Sopenharmony_ci	.ssp0_size = 0x1000,
1138c2ecf20Sopenharmony_ci	.dma0_offset = 0x98000,
1148c2ecf20Sopenharmony_ci	.dma0_size = 0x4000,
1158c2ecf20Sopenharmony_ci	.dma1_offset = 0x9c000,
1168c2ecf20Sopenharmony_ci	.dma1_size = 0x4000,
1178c2ecf20Sopenharmony_ci	.iram_offset = 0x0c0000,
1188c2ecf20Sopenharmony_ci	.iram_size = 0x14000,
1198c2ecf20Sopenharmony_ci	.dram_offset = 0x100000,
1208c2ecf20Sopenharmony_ci	.dram_size = 0x28000,
1218c2ecf20Sopenharmony_ci	.mbox_offset = 0x144000,
1228c2ecf20Sopenharmony_ci	.mbox_size = 0x1000,
1238c2ecf20Sopenharmony_ci	.acpi_lpe_res_index = 0,
1248c2ecf20Sopenharmony_ci	.acpi_ddr_index = 2,
1258c2ecf20Sopenharmony_ci	.acpi_ipc_irq_index = 0
1268c2ecf20Sopenharmony_ci};
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_cistatic struct sst_platform_info byt_rvp_platform_data = {
1298c2ecf20Sopenharmony_ci	.probe_data = &byt_fwparse_info,
1308c2ecf20Sopenharmony_ci	.ipc_info = &byt_ipc_info,
1318c2ecf20Sopenharmony_ci	.lib_info = &byt_lib_dnld_info,
1328c2ecf20Sopenharmony_ci	.res_info = &byt_rvp_res_info,
1338c2ecf20Sopenharmony_ci	.platform = "sst-mfld-platform",
1348c2ecf20Sopenharmony_ci	.streams_lost_on_suspend = true,
1358c2ecf20Sopenharmony_ci};
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci/* Cherryview (Cherrytrail and Braswell) uses same mrfld dpcm fw as Baytrail,
1388c2ecf20Sopenharmony_ci * so pdata is same as Baytrail, minus the streams_lost_on_suspend quirk.
1398c2ecf20Sopenharmony_ci */
1408c2ecf20Sopenharmony_cistatic struct sst_platform_info chv_platform_data = {
1418c2ecf20Sopenharmony_ci	.probe_data = &byt_fwparse_info,
1428c2ecf20Sopenharmony_ci	.ipc_info = &byt_ipc_info,
1438c2ecf20Sopenharmony_ci	.lib_info = &byt_lib_dnld_info,
1448c2ecf20Sopenharmony_ci	.res_info = &byt_rvp_res_info,
1458c2ecf20Sopenharmony_ci	.platform = "sst-mfld-platform",
1468c2ecf20Sopenharmony_ci};
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistatic int sst_platform_get_resources(struct intel_sst_drv *ctx)
1498c2ecf20Sopenharmony_ci{
1508c2ecf20Sopenharmony_ci	struct resource *rsrc;
1518c2ecf20Sopenharmony_ci	struct platform_device *pdev = to_platform_device(ctx->dev);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	/* All ACPI resource request here */
1548c2ecf20Sopenharmony_ci	/* Get Shim addr */
1558c2ecf20Sopenharmony_ci	rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
1568c2ecf20Sopenharmony_ci					ctx->pdata->res_info->acpi_lpe_res_index);
1578c2ecf20Sopenharmony_ci	if (!rsrc) {
1588c2ecf20Sopenharmony_ci		dev_err(ctx->dev, "Invalid SHIM base from IFWI\n");
1598c2ecf20Sopenharmony_ci		return -EIO;
1608c2ecf20Sopenharmony_ci	}
1618c2ecf20Sopenharmony_ci	dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start,
1628c2ecf20Sopenharmony_ci					(unsigned int)resource_size(rsrc));
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	ctx->iram_base = rsrc->start + ctx->pdata->res_info->iram_offset;
1658c2ecf20Sopenharmony_ci	ctx->iram_end =  ctx->iram_base + ctx->pdata->res_info->iram_size - 1;
1668c2ecf20Sopenharmony_ci	dev_info(ctx->dev, "IRAM base: %#x", ctx->iram_base);
1678c2ecf20Sopenharmony_ci	ctx->iram = devm_ioremap(ctx->dev, ctx->iram_base,
1688c2ecf20Sopenharmony_ci					 ctx->pdata->res_info->iram_size);
1698c2ecf20Sopenharmony_ci	if (!ctx->iram) {
1708c2ecf20Sopenharmony_ci		dev_err(ctx->dev, "unable to map IRAM\n");
1718c2ecf20Sopenharmony_ci		return -EIO;
1728c2ecf20Sopenharmony_ci	}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	ctx->dram_base = rsrc->start + ctx->pdata->res_info->dram_offset;
1758c2ecf20Sopenharmony_ci	ctx->dram_end = ctx->dram_base + ctx->pdata->res_info->dram_size - 1;
1768c2ecf20Sopenharmony_ci	dev_info(ctx->dev, "DRAM base: %#x", ctx->dram_base);
1778c2ecf20Sopenharmony_ci	ctx->dram = devm_ioremap(ctx->dev, ctx->dram_base,
1788c2ecf20Sopenharmony_ci					 ctx->pdata->res_info->dram_size);
1798c2ecf20Sopenharmony_ci	if (!ctx->dram) {
1808c2ecf20Sopenharmony_ci		dev_err(ctx->dev, "unable to map DRAM\n");
1818c2ecf20Sopenharmony_ci		return -EIO;
1828c2ecf20Sopenharmony_ci	}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	ctx->shim_phy_add = rsrc->start + ctx->pdata->res_info->shim_offset;
1858c2ecf20Sopenharmony_ci	dev_info(ctx->dev, "SHIM base: %#x", ctx->shim_phy_add);
1868c2ecf20Sopenharmony_ci	ctx->shim = devm_ioremap(ctx->dev, ctx->shim_phy_add,
1878c2ecf20Sopenharmony_ci					ctx->pdata->res_info->shim_size);
1888c2ecf20Sopenharmony_ci	if (!ctx->shim) {
1898c2ecf20Sopenharmony_ci		dev_err(ctx->dev, "unable to map SHIM\n");
1908c2ecf20Sopenharmony_ci		return -EIO;
1918c2ecf20Sopenharmony_ci	}
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	/* reassign physical address to LPE viewpoint address */
1948c2ecf20Sopenharmony_ci	ctx->shim_phy_add = ctx->pdata->res_info->shim_phy_addr;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	/* Get mailbox addr */
1978c2ecf20Sopenharmony_ci	ctx->mailbox_add = rsrc->start + ctx->pdata->res_info->mbox_offset;
1988c2ecf20Sopenharmony_ci	dev_info(ctx->dev, "Mailbox base: %#x", ctx->mailbox_add);
1998c2ecf20Sopenharmony_ci	ctx->mailbox = devm_ioremap(ctx->dev, ctx->mailbox_add,
2008c2ecf20Sopenharmony_ci					    ctx->pdata->res_info->mbox_size);
2018c2ecf20Sopenharmony_ci	if (!ctx->mailbox) {
2028c2ecf20Sopenharmony_ci		dev_err(ctx->dev, "unable to map mailbox\n");
2038c2ecf20Sopenharmony_ci		return -EIO;
2048c2ecf20Sopenharmony_ci	}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	/* reassign physical address to LPE viewpoint address */
2078c2ecf20Sopenharmony_ci	ctx->mailbox_add = ctx->info.mailbox_start;
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci	rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
2108c2ecf20Sopenharmony_ci					ctx->pdata->res_info->acpi_ddr_index);
2118c2ecf20Sopenharmony_ci	if (!rsrc) {
2128c2ecf20Sopenharmony_ci		dev_err(ctx->dev, "Invalid DDR base from IFWI\n");
2138c2ecf20Sopenharmony_ci		return -EIO;
2148c2ecf20Sopenharmony_ci	}
2158c2ecf20Sopenharmony_ci	ctx->ddr_base = rsrc->start;
2168c2ecf20Sopenharmony_ci	ctx->ddr_end = rsrc->end;
2178c2ecf20Sopenharmony_ci	dev_info(ctx->dev, "DDR base: %#x", ctx->ddr_base);
2188c2ecf20Sopenharmony_ci	ctx->ddr = devm_ioremap(ctx->dev, ctx->ddr_base,
2198c2ecf20Sopenharmony_ci					resource_size(rsrc));
2208c2ecf20Sopenharmony_ci	if (!ctx->ddr) {
2218c2ecf20Sopenharmony_ci		dev_err(ctx->dev, "unable to map DDR\n");
2228c2ecf20Sopenharmony_ci		return -EIO;
2238c2ecf20Sopenharmony_ci	}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	/* Find the IRQ */
2268c2ecf20Sopenharmony_ci	ctx->irq_num = platform_get_irq(pdev,
2278c2ecf20Sopenharmony_ci				ctx->pdata->res_info->acpi_ipc_irq_index);
2288c2ecf20Sopenharmony_ci	if (ctx->irq_num <= 0)
2298c2ecf20Sopenharmony_ci		return ctx->irq_num < 0 ? ctx->irq_num : -EIO;
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci	return 0;
2328c2ecf20Sopenharmony_ci}
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_cistatic int sst_acpi_probe(struct platform_device *pdev)
2358c2ecf20Sopenharmony_ci{
2368c2ecf20Sopenharmony_ci	struct device *dev = &pdev->dev;
2378c2ecf20Sopenharmony_ci	int ret = 0;
2388c2ecf20Sopenharmony_ci	struct intel_sst_drv *ctx;
2398c2ecf20Sopenharmony_ci	const struct acpi_device_id *id;
2408c2ecf20Sopenharmony_ci	struct snd_soc_acpi_mach *mach;
2418c2ecf20Sopenharmony_ci	struct platform_device *mdev;
2428c2ecf20Sopenharmony_ci	struct platform_device *plat_dev;
2438c2ecf20Sopenharmony_ci	struct sst_platform_info *pdata;
2448c2ecf20Sopenharmony_ci	unsigned int dev_id;
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci	id = acpi_match_device(dev->driver->acpi_match_table, dev);
2478c2ecf20Sopenharmony_ci	if (!id)
2488c2ecf20Sopenharmony_ci		return -ENODEV;
2498c2ecf20Sopenharmony_ci	dev_dbg(dev, "for %s\n", id->id);
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	mach = (struct snd_soc_acpi_mach *)id->driver_data;
2528c2ecf20Sopenharmony_ci	mach = snd_soc_acpi_find_machine(mach);
2538c2ecf20Sopenharmony_ci	if (mach == NULL) {
2548c2ecf20Sopenharmony_ci		dev_err(dev, "No matching machine driver found\n");
2558c2ecf20Sopenharmony_ci		return -ENODEV;
2568c2ecf20Sopenharmony_ci	}
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	if (soc_intel_is_byt())
2598c2ecf20Sopenharmony_ci		mach->pdata = &byt_rvp_platform_data;
2608c2ecf20Sopenharmony_ci	else
2618c2ecf20Sopenharmony_ci		mach->pdata = &chv_platform_data;
2628c2ecf20Sopenharmony_ci	pdata = mach->pdata;
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	ret = kstrtouint(id->id, 16, &dev_id);
2658c2ecf20Sopenharmony_ci	if (ret < 0) {
2668c2ecf20Sopenharmony_ci		dev_err(dev, "Unique device id conversion error: %d\n", ret);
2678c2ecf20Sopenharmony_ci		return ret;
2688c2ecf20Sopenharmony_ci	}
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci	dev_dbg(dev, "ACPI device id: %x\n", dev_id);
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	ret = sst_alloc_drv_context(&ctx, dev, dev_id);
2738c2ecf20Sopenharmony_ci	if (ret < 0)
2748c2ecf20Sopenharmony_ci		return ret;
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	if (soc_intel_is_byt_cr(pdev)) {
2778c2ecf20Sopenharmony_ci		/* override resource info */
2788c2ecf20Sopenharmony_ci		byt_rvp_platform_data.res_info = &bytcr_res_info;
2798c2ecf20Sopenharmony_ci	}
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci	/* update machine parameters */
2828c2ecf20Sopenharmony_ci	mach->mach_params.acpi_ipc_irq_index =
2838c2ecf20Sopenharmony_ci		pdata->res_info->acpi_ipc_irq_index;
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci	plat_dev = platform_device_register_data(dev, pdata->platform, -1,
2868c2ecf20Sopenharmony_ci						NULL, 0);
2878c2ecf20Sopenharmony_ci	if (IS_ERR(plat_dev)) {
2888c2ecf20Sopenharmony_ci		dev_err(dev, "Failed to create machine device: %s\n",
2898c2ecf20Sopenharmony_ci			pdata->platform);
2908c2ecf20Sopenharmony_ci		return PTR_ERR(plat_dev);
2918c2ecf20Sopenharmony_ci	}
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	/*
2948c2ecf20Sopenharmony_ci	 * Create platform device for sst machine driver,
2958c2ecf20Sopenharmony_ci	 * pass machine info as pdata
2968c2ecf20Sopenharmony_ci	 */
2978c2ecf20Sopenharmony_ci	mdev = platform_device_register_data(dev, mach->drv_name, -1,
2988c2ecf20Sopenharmony_ci					(const void *)mach, sizeof(*mach));
2998c2ecf20Sopenharmony_ci	if (IS_ERR(mdev)) {
3008c2ecf20Sopenharmony_ci		dev_err(dev, "Failed to create machine device: %s\n",
3018c2ecf20Sopenharmony_ci			mach->drv_name);
3028c2ecf20Sopenharmony_ci		return PTR_ERR(mdev);
3038c2ecf20Sopenharmony_ci	}
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	/* Fill sst platform data */
3068c2ecf20Sopenharmony_ci	ctx->pdata = pdata;
3078c2ecf20Sopenharmony_ci	strcpy(ctx->firmware_name, mach->fw_filename);
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	ret = sst_platform_get_resources(ctx);
3108c2ecf20Sopenharmony_ci	if (ret)
3118c2ecf20Sopenharmony_ci		return ret;
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci	ret = sst_context_init(ctx);
3148c2ecf20Sopenharmony_ci	if (ret < 0)
3158c2ecf20Sopenharmony_ci		return ret;
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci	sst_configure_runtime_pm(ctx);
3188c2ecf20Sopenharmony_ci	platform_set_drvdata(pdev, ctx);
3198c2ecf20Sopenharmony_ci	return ret;
3208c2ecf20Sopenharmony_ci}
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci/**
3238c2ecf20Sopenharmony_ci* intel_sst_remove - remove function
3248c2ecf20Sopenharmony_ci*
3258c2ecf20Sopenharmony_ci* @pdev:	platform device structure
3268c2ecf20Sopenharmony_ci*
3278c2ecf20Sopenharmony_ci* This function is called by OS when a device is unloaded
3288c2ecf20Sopenharmony_ci* This frees the interrupt etc
3298c2ecf20Sopenharmony_ci*/
3308c2ecf20Sopenharmony_cistatic int sst_acpi_remove(struct platform_device *pdev)
3318c2ecf20Sopenharmony_ci{
3328c2ecf20Sopenharmony_ci	struct intel_sst_drv *ctx;
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	ctx = platform_get_drvdata(pdev);
3358c2ecf20Sopenharmony_ci	sst_context_cleanup(ctx);
3368c2ecf20Sopenharmony_ci	platform_set_drvdata(pdev, NULL);
3378c2ecf20Sopenharmony_ci	return 0;
3388c2ecf20Sopenharmony_ci}
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_cistatic const struct acpi_device_id sst_acpi_ids[] = {
3418c2ecf20Sopenharmony_ci	{ "80860F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
3428c2ecf20Sopenharmony_ci	{ "808622A8", (unsigned long)&snd_soc_acpi_intel_cherrytrail_machines},
3438c2ecf20Sopenharmony_ci	{ },
3448c2ecf20Sopenharmony_ci};
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, sst_acpi_ids);
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_cistatic struct platform_driver sst_acpi_driver = {
3498c2ecf20Sopenharmony_ci	.driver = {
3508c2ecf20Sopenharmony_ci		.name			= "intel_sst_acpi",
3518c2ecf20Sopenharmony_ci		.acpi_match_table	= ACPI_PTR(sst_acpi_ids),
3528c2ecf20Sopenharmony_ci		.pm			= &intel_sst_pm,
3538c2ecf20Sopenharmony_ci	},
3548c2ecf20Sopenharmony_ci	.probe	= sst_acpi_probe,
3558c2ecf20Sopenharmony_ci	.remove	= sst_acpi_remove,
3568c2ecf20Sopenharmony_ci};
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_cimodule_platform_driver(sst_acpi_driver);
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine ACPI Driver");
3618c2ecf20Sopenharmony_ciMODULE_AUTHOR("Ramesh Babu K V");
3628c2ecf20Sopenharmony_ciMODULE_AUTHOR("Omair Mohammed Abdullah");
3638c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
3648c2ecf20Sopenharmony_ciMODULE_ALIAS("sst");
365