162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * sst_acpi.c - SST (LPE) driver init file for ACPI enumeration. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2013, Intel Corporation. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Authors: Ramesh Babu K V <Ramesh.Babu@intel.com> 862306a36Sopenharmony_ci * Authors: Omair Mohammed Abdullah <omair.m.abdullah@intel.com> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/module.h> 1262306a36Sopenharmony_ci#include <linux/fs.h> 1362306a36Sopenharmony_ci#include <linux/interrupt.h> 1462306a36Sopenharmony_ci#include <linux/slab.h> 1562306a36Sopenharmony_ci#include <linux/io.h> 1662306a36Sopenharmony_ci#include <linux/platform_device.h> 1762306a36Sopenharmony_ci#include <linux/firmware.h> 1862306a36Sopenharmony_ci#include <linux/pm_qos.h> 1962306a36Sopenharmony_ci#include <linux/dmi.h> 2062306a36Sopenharmony_ci#include <linux/acpi.h> 2162306a36Sopenharmony_ci#include <asm/platform_sst_audio.h> 2262306a36Sopenharmony_ci#include <sound/core.h> 2362306a36Sopenharmony_ci#include <sound/intel-dsp-config.h> 2462306a36Sopenharmony_ci#include <sound/soc.h> 2562306a36Sopenharmony_ci#include <sound/compress_driver.h> 2662306a36Sopenharmony_ci#include <acpi/acbuffer.h> 2762306a36Sopenharmony_ci#include <acpi/platform/acenv.h> 2862306a36Sopenharmony_ci#include <acpi/platform/aclinux.h> 2962306a36Sopenharmony_ci#include <acpi/actypes.h> 3062306a36Sopenharmony_ci#include <acpi/acpi_bus.h> 3162306a36Sopenharmony_ci#include <sound/soc-acpi.h> 3262306a36Sopenharmony_ci#include <sound/soc-acpi-intel-match.h> 3362306a36Sopenharmony_ci#include "../sst-mfld-platform.h" 3462306a36Sopenharmony_ci#include "../../common/soc-intel-quirks.h" 3562306a36Sopenharmony_ci#include "sst.h" 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* LPE viewpoint addresses */ 3862306a36Sopenharmony_ci#define SST_BYT_IRAM_PHY_START 0xff2c0000 3962306a36Sopenharmony_ci#define SST_BYT_IRAM_PHY_END 0xff2d4000 4062306a36Sopenharmony_ci#define SST_BYT_DRAM_PHY_START 0xff300000 4162306a36Sopenharmony_ci#define SST_BYT_DRAM_PHY_END 0xff320000 4262306a36Sopenharmony_ci#define SST_BYT_IMR_VIRT_START 0xc0000000 /* virtual addr in LPE */ 4362306a36Sopenharmony_ci#define SST_BYT_IMR_VIRT_END 0xc01fffff 4462306a36Sopenharmony_ci#define SST_BYT_SHIM_PHY_ADDR 0xff340000 4562306a36Sopenharmony_ci#define SST_BYT_MBOX_PHY_ADDR 0xff344000 4662306a36Sopenharmony_ci#define SST_BYT_DMA0_PHY_ADDR 0xff298000 4762306a36Sopenharmony_ci#define SST_BYT_DMA1_PHY_ADDR 0xff29c000 4862306a36Sopenharmony_ci#define SST_BYT_SSP0_PHY_ADDR 0xff2a0000 4962306a36Sopenharmony_ci#define SST_BYT_SSP2_PHY_ADDR 0xff2a2000 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#define BYT_FW_MOD_TABLE_OFFSET 0x80000 5262306a36Sopenharmony_ci#define BYT_FW_MOD_TABLE_SIZE 0x100 5362306a36Sopenharmony_ci#define BYT_FW_MOD_OFFSET (BYT_FW_MOD_TABLE_OFFSET + BYT_FW_MOD_TABLE_SIZE) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic const struct sst_info byt_fwparse_info = { 5662306a36Sopenharmony_ci .use_elf = false, 5762306a36Sopenharmony_ci .max_streams = 25, 5862306a36Sopenharmony_ci .iram_start = SST_BYT_IRAM_PHY_START, 5962306a36Sopenharmony_ci .iram_end = SST_BYT_IRAM_PHY_END, 6062306a36Sopenharmony_ci .iram_use = true, 6162306a36Sopenharmony_ci .dram_start = SST_BYT_DRAM_PHY_START, 6262306a36Sopenharmony_ci .dram_end = SST_BYT_DRAM_PHY_END, 6362306a36Sopenharmony_ci .dram_use = true, 6462306a36Sopenharmony_ci .imr_start = SST_BYT_IMR_VIRT_START, 6562306a36Sopenharmony_ci .imr_end = SST_BYT_IMR_VIRT_END, 6662306a36Sopenharmony_ci .imr_use = true, 6762306a36Sopenharmony_ci .mailbox_start = SST_BYT_MBOX_PHY_ADDR, 6862306a36Sopenharmony_ci .num_probes = 0, 6962306a36Sopenharmony_ci .lpe_viewpt_rqd = true, 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistatic const struct sst_ipc_info byt_ipc_info = { 7362306a36Sopenharmony_ci .ipc_offset = 0, 7462306a36Sopenharmony_ci .mbox_recv_off = 0x400, 7562306a36Sopenharmony_ci}; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic const struct sst_lib_dnld_info byt_lib_dnld_info = { 7862306a36Sopenharmony_ci .mod_base = SST_BYT_IMR_VIRT_START, 7962306a36Sopenharmony_ci .mod_end = SST_BYT_IMR_VIRT_END, 8062306a36Sopenharmony_ci .mod_table_offset = BYT_FW_MOD_TABLE_OFFSET, 8162306a36Sopenharmony_ci .mod_table_size = BYT_FW_MOD_TABLE_SIZE, 8262306a36Sopenharmony_ci .mod_ddr_dnld = false, 8362306a36Sopenharmony_ci}; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistatic const struct sst_res_info byt_rvp_res_info = { 8662306a36Sopenharmony_ci .shim_offset = 0x140000, 8762306a36Sopenharmony_ci .shim_size = 0x000100, 8862306a36Sopenharmony_ci .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR, 8962306a36Sopenharmony_ci .ssp0_offset = 0xa0000, 9062306a36Sopenharmony_ci .ssp0_size = 0x1000, 9162306a36Sopenharmony_ci .dma0_offset = 0x98000, 9262306a36Sopenharmony_ci .dma0_size = 0x4000, 9362306a36Sopenharmony_ci .dma1_offset = 0x9c000, 9462306a36Sopenharmony_ci .dma1_size = 0x4000, 9562306a36Sopenharmony_ci .iram_offset = 0x0c0000, 9662306a36Sopenharmony_ci .iram_size = 0x14000, 9762306a36Sopenharmony_ci .dram_offset = 0x100000, 9862306a36Sopenharmony_ci .dram_size = 0x28000, 9962306a36Sopenharmony_ci .mbox_offset = 0x144000, 10062306a36Sopenharmony_ci .mbox_size = 0x1000, 10162306a36Sopenharmony_ci .acpi_lpe_res_index = 0, 10262306a36Sopenharmony_ci .acpi_ddr_index = 2, 10362306a36Sopenharmony_ci .acpi_ipc_irq_index = 5, 10462306a36Sopenharmony_ci}; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/* BYTCR has different BIOS from BYT */ 10762306a36Sopenharmony_cistatic const struct sst_res_info bytcr_res_info = { 10862306a36Sopenharmony_ci .shim_offset = 0x140000, 10962306a36Sopenharmony_ci .shim_size = 0x000100, 11062306a36Sopenharmony_ci .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR, 11162306a36Sopenharmony_ci .ssp0_offset = 0xa0000, 11262306a36Sopenharmony_ci .ssp0_size = 0x1000, 11362306a36Sopenharmony_ci .dma0_offset = 0x98000, 11462306a36Sopenharmony_ci .dma0_size = 0x4000, 11562306a36Sopenharmony_ci .dma1_offset = 0x9c000, 11662306a36Sopenharmony_ci .dma1_size = 0x4000, 11762306a36Sopenharmony_ci .iram_offset = 0x0c0000, 11862306a36Sopenharmony_ci .iram_size = 0x14000, 11962306a36Sopenharmony_ci .dram_offset = 0x100000, 12062306a36Sopenharmony_ci .dram_size = 0x28000, 12162306a36Sopenharmony_ci .mbox_offset = 0x144000, 12262306a36Sopenharmony_ci .mbox_size = 0x1000, 12362306a36Sopenharmony_ci .acpi_lpe_res_index = 0, 12462306a36Sopenharmony_ci .acpi_ddr_index = 2, 12562306a36Sopenharmony_ci .acpi_ipc_irq_index = 0 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic struct sst_platform_info byt_rvp_platform_data = { 12962306a36Sopenharmony_ci .probe_data = &byt_fwparse_info, 13062306a36Sopenharmony_ci .ipc_info = &byt_ipc_info, 13162306a36Sopenharmony_ci .lib_info = &byt_lib_dnld_info, 13262306a36Sopenharmony_ci .res_info = &byt_rvp_res_info, 13362306a36Sopenharmony_ci .platform = "sst-mfld-platform", 13462306a36Sopenharmony_ci .streams_lost_on_suspend = true, 13562306a36Sopenharmony_ci}; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci/* Cherryview (Cherrytrail and Braswell) uses same mrfld dpcm fw as Baytrail, 13862306a36Sopenharmony_ci * so pdata is same as Baytrail, minus the streams_lost_on_suspend quirk. 13962306a36Sopenharmony_ci */ 14062306a36Sopenharmony_cistatic struct sst_platform_info chv_platform_data = { 14162306a36Sopenharmony_ci .probe_data = &byt_fwparse_info, 14262306a36Sopenharmony_ci .ipc_info = &byt_ipc_info, 14362306a36Sopenharmony_ci .lib_info = &byt_lib_dnld_info, 14462306a36Sopenharmony_ci .res_info = &byt_rvp_res_info, 14562306a36Sopenharmony_ci .platform = "sst-mfld-platform", 14662306a36Sopenharmony_ci}; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic int sst_platform_get_resources(struct intel_sst_drv *ctx) 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci struct resource *rsrc; 15162306a36Sopenharmony_ci struct platform_device *pdev = to_platform_device(ctx->dev); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci /* All ACPI resource request here */ 15462306a36Sopenharmony_ci /* Get Shim addr */ 15562306a36Sopenharmony_ci rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 15662306a36Sopenharmony_ci ctx->pdata->res_info->acpi_lpe_res_index); 15762306a36Sopenharmony_ci if (!rsrc) { 15862306a36Sopenharmony_ci dev_err(ctx->dev, "Invalid SHIM base from IFWI\n"); 15962306a36Sopenharmony_ci return -EIO; 16062306a36Sopenharmony_ci } 16162306a36Sopenharmony_ci dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start, 16262306a36Sopenharmony_ci (unsigned int)resource_size(rsrc)); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci ctx->iram_base = rsrc->start + ctx->pdata->res_info->iram_offset; 16562306a36Sopenharmony_ci ctx->iram_end = ctx->iram_base + ctx->pdata->res_info->iram_size - 1; 16662306a36Sopenharmony_ci dev_info(ctx->dev, "IRAM base: %#x", ctx->iram_base); 16762306a36Sopenharmony_ci ctx->iram = devm_ioremap(ctx->dev, ctx->iram_base, 16862306a36Sopenharmony_ci ctx->pdata->res_info->iram_size); 16962306a36Sopenharmony_ci if (!ctx->iram) { 17062306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map IRAM\n"); 17162306a36Sopenharmony_ci return -EIO; 17262306a36Sopenharmony_ci } 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci ctx->dram_base = rsrc->start + ctx->pdata->res_info->dram_offset; 17562306a36Sopenharmony_ci ctx->dram_end = ctx->dram_base + ctx->pdata->res_info->dram_size - 1; 17662306a36Sopenharmony_ci dev_info(ctx->dev, "DRAM base: %#x", ctx->dram_base); 17762306a36Sopenharmony_ci ctx->dram = devm_ioremap(ctx->dev, ctx->dram_base, 17862306a36Sopenharmony_ci ctx->pdata->res_info->dram_size); 17962306a36Sopenharmony_ci if (!ctx->dram) { 18062306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map DRAM\n"); 18162306a36Sopenharmony_ci return -EIO; 18262306a36Sopenharmony_ci } 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci ctx->shim_phy_add = rsrc->start + ctx->pdata->res_info->shim_offset; 18562306a36Sopenharmony_ci dev_info(ctx->dev, "SHIM base: %#x", ctx->shim_phy_add); 18662306a36Sopenharmony_ci ctx->shim = devm_ioremap(ctx->dev, ctx->shim_phy_add, 18762306a36Sopenharmony_ci ctx->pdata->res_info->shim_size); 18862306a36Sopenharmony_ci if (!ctx->shim) { 18962306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map SHIM\n"); 19062306a36Sopenharmony_ci return -EIO; 19162306a36Sopenharmony_ci } 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci /* reassign physical address to LPE viewpoint address */ 19462306a36Sopenharmony_ci ctx->shim_phy_add = ctx->pdata->res_info->shim_phy_addr; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci /* Get mailbox addr */ 19762306a36Sopenharmony_ci ctx->mailbox_add = rsrc->start + ctx->pdata->res_info->mbox_offset; 19862306a36Sopenharmony_ci dev_info(ctx->dev, "Mailbox base: %#x", ctx->mailbox_add); 19962306a36Sopenharmony_ci ctx->mailbox = devm_ioremap(ctx->dev, ctx->mailbox_add, 20062306a36Sopenharmony_ci ctx->pdata->res_info->mbox_size); 20162306a36Sopenharmony_ci if (!ctx->mailbox) { 20262306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map mailbox\n"); 20362306a36Sopenharmony_ci return -EIO; 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci /* reassign physical address to LPE viewpoint address */ 20762306a36Sopenharmony_ci ctx->mailbox_add = ctx->info.mailbox_start; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 21062306a36Sopenharmony_ci ctx->pdata->res_info->acpi_ddr_index); 21162306a36Sopenharmony_ci if (!rsrc) { 21262306a36Sopenharmony_ci dev_err(ctx->dev, "Invalid DDR base from IFWI\n"); 21362306a36Sopenharmony_ci return -EIO; 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci ctx->ddr_base = rsrc->start; 21662306a36Sopenharmony_ci ctx->ddr_end = rsrc->end; 21762306a36Sopenharmony_ci dev_info(ctx->dev, "DDR base: %#x", ctx->ddr_base); 21862306a36Sopenharmony_ci ctx->ddr = devm_ioremap(ctx->dev, ctx->ddr_base, 21962306a36Sopenharmony_ci resource_size(rsrc)); 22062306a36Sopenharmony_ci if (!ctx->ddr) { 22162306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map DDR\n"); 22262306a36Sopenharmony_ci return -EIO; 22362306a36Sopenharmony_ci } 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci /* Find the IRQ */ 22662306a36Sopenharmony_ci ctx->irq_num = platform_get_irq(pdev, 22762306a36Sopenharmony_ci ctx->pdata->res_info->acpi_ipc_irq_index); 22862306a36Sopenharmony_ci if (ctx->irq_num <= 0) 22962306a36Sopenharmony_ci return ctx->irq_num < 0 ? ctx->irq_num : -EIO; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci return 0; 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic int sst_acpi_probe(struct platform_device *pdev) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci struct device *dev = &pdev->dev; 23762306a36Sopenharmony_ci int ret = 0; 23862306a36Sopenharmony_ci struct intel_sst_drv *ctx; 23962306a36Sopenharmony_ci const struct acpi_device_id *id; 24062306a36Sopenharmony_ci struct snd_soc_acpi_mach *mach; 24162306a36Sopenharmony_ci struct platform_device *mdev; 24262306a36Sopenharmony_ci struct platform_device *plat_dev; 24362306a36Sopenharmony_ci struct sst_platform_info *pdata; 24462306a36Sopenharmony_ci unsigned int dev_id; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci id = acpi_match_device(dev->driver->acpi_match_table, dev); 24762306a36Sopenharmony_ci if (!id) 24862306a36Sopenharmony_ci return -ENODEV; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci ret = snd_intel_acpi_dsp_driver_probe(dev, id->id); 25162306a36Sopenharmony_ci if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SST) { 25262306a36Sopenharmony_ci dev_dbg(dev, "SST ACPI driver not selected, aborting probe\n"); 25362306a36Sopenharmony_ci return -ENODEV; 25462306a36Sopenharmony_ci } 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci dev_dbg(dev, "for %s\n", id->id); 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci mach = (struct snd_soc_acpi_mach *)id->driver_data; 25962306a36Sopenharmony_ci mach = snd_soc_acpi_find_machine(mach); 26062306a36Sopenharmony_ci if (mach == NULL) { 26162306a36Sopenharmony_ci dev_err(dev, "No matching machine driver found\n"); 26262306a36Sopenharmony_ci return -ENODEV; 26362306a36Sopenharmony_ci } 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci if (soc_intel_is_byt()) 26662306a36Sopenharmony_ci mach->pdata = &byt_rvp_platform_data; 26762306a36Sopenharmony_ci else 26862306a36Sopenharmony_ci mach->pdata = &chv_platform_data; 26962306a36Sopenharmony_ci pdata = mach->pdata; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci ret = kstrtouint(id->id, 16, &dev_id); 27262306a36Sopenharmony_ci if (ret < 0) { 27362306a36Sopenharmony_ci dev_err(dev, "Unique device id conversion error: %d\n", ret); 27462306a36Sopenharmony_ci return ret; 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci dev_dbg(dev, "ACPI device id: %x\n", dev_id); 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci ret = sst_alloc_drv_context(&ctx, dev, dev_id); 28062306a36Sopenharmony_ci if (ret < 0) 28162306a36Sopenharmony_ci return ret; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci if (soc_intel_is_byt_cr(pdev)) { 28462306a36Sopenharmony_ci /* override resource info */ 28562306a36Sopenharmony_ci byt_rvp_platform_data.res_info = &bytcr_res_info; 28662306a36Sopenharmony_ci } 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci /* update machine parameters */ 28962306a36Sopenharmony_ci mach->mach_params.acpi_ipc_irq_index = 29062306a36Sopenharmony_ci pdata->res_info->acpi_ipc_irq_index; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci plat_dev = platform_device_register_data(dev, pdata->platform, -1, 29362306a36Sopenharmony_ci NULL, 0); 29462306a36Sopenharmony_ci if (IS_ERR(plat_dev)) { 29562306a36Sopenharmony_ci dev_err(dev, "Failed to create machine device: %s\n", 29662306a36Sopenharmony_ci pdata->platform); 29762306a36Sopenharmony_ci return PTR_ERR(plat_dev); 29862306a36Sopenharmony_ci } 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci /* 30162306a36Sopenharmony_ci * Create platform device for sst machine driver, 30262306a36Sopenharmony_ci * pass machine info as pdata 30362306a36Sopenharmony_ci */ 30462306a36Sopenharmony_ci mdev = platform_device_register_data(dev, mach->drv_name, -1, 30562306a36Sopenharmony_ci (const void *)mach, sizeof(*mach)); 30662306a36Sopenharmony_ci if (IS_ERR(mdev)) { 30762306a36Sopenharmony_ci dev_err(dev, "Failed to create machine device: %s\n", 30862306a36Sopenharmony_ci mach->drv_name); 30962306a36Sopenharmony_ci return PTR_ERR(mdev); 31062306a36Sopenharmony_ci } 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci /* Fill sst platform data */ 31362306a36Sopenharmony_ci ctx->pdata = pdata; 31462306a36Sopenharmony_ci strcpy(ctx->firmware_name, mach->fw_filename); 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci ret = sst_platform_get_resources(ctx); 31762306a36Sopenharmony_ci if (ret) 31862306a36Sopenharmony_ci return ret; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci ret = sst_context_init(ctx); 32162306a36Sopenharmony_ci if (ret < 0) 32262306a36Sopenharmony_ci return ret; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci sst_configure_runtime_pm(ctx); 32562306a36Sopenharmony_ci platform_set_drvdata(pdev, ctx); 32662306a36Sopenharmony_ci return ret; 32762306a36Sopenharmony_ci} 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci/** 33062306a36Sopenharmony_ci* sst_acpi_remove - remove function 33162306a36Sopenharmony_ci* 33262306a36Sopenharmony_ci* @pdev: platform device structure 33362306a36Sopenharmony_ci* 33462306a36Sopenharmony_ci* This function is called by OS when a device is unloaded 33562306a36Sopenharmony_ci* This frees the interrupt etc 33662306a36Sopenharmony_ci*/ 33762306a36Sopenharmony_cistatic void sst_acpi_remove(struct platform_device *pdev) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci struct intel_sst_drv *ctx; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci ctx = platform_get_drvdata(pdev); 34262306a36Sopenharmony_ci sst_context_cleanup(ctx); 34362306a36Sopenharmony_ci platform_set_drvdata(pdev, NULL); 34462306a36Sopenharmony_ci} 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_cistatic const struct acpi_device_id sst_acpi_ids[] = { 34762306a36Sopenharmony_ci { "80860F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines}, 34862306a36Sopenharmony_ci { "808622A8", (unsigned long)&snd_soc_acpi_intel_cherrytrail_machines}, 34962306a36Sopenharmony_ci { }, 35062306a36Sopenharmony_ci}; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, sst_acpi_ids); 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_cistatic struct platform_driver sst_acpi_driver = { 35562306a36Sopenharmony_ci .driver = { 35662306a36Sopenharmony_ci .name = "intel_sst_acpi", 35762306a36Sopenharmony_ci .acpi_match_table = ACPI_PTR(sst_acpi_ids), 35862306a36Sopenharmony_ci .pm = &intel_sst_pm, 35962306a36Sopenharmony_ci }, 36062306a36Sopenharmony_ci .probe = sst_acpi_probe, 36162306a36Sopenharmony_ci .remove_new = sst_acpi_remove, 36262306a36Sopenharmony_ci}; 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_cimodule_platform_driver(sst_acpi_driver); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ciMODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine ACPI Driver"); 36762306a36Sopenharmony_ciMODULE_AUTHOR("Ramesh Babu K V"); 36862306a36Sopenharmony_ciMODULE_AUTHOR("Omair Mohammed Abdullah"); 36962306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 37062306a36Sopenharmony_ciMODULE_ALIAS("sst"); 371