xref: /linux/drivers/soundwire/intel_init.c (revision 4a17c441c7cb06ac1e5fd3409a64d8ce78151983)
1d62a7d41SVinod Koul // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2d62a7d41SVinod Koul // Copyright(c) 2015-17 Intel Corporation.
3d62a7d41SVinod Koul 
4d62a7d41SVinod Koul /*
5d62a7d41SVinod Koul  * SDW Intel Init Routines
6d62a7d41SVinod Koul  *
7d62a7d41SVinod Koul  * Initializes and creates SDW devices based on ACPI and Hardware values
8d62a7d41SVinod Koul  */
9d62a7d41SVinod Koul 
10d62a7d41SVinod Koul #include <linux/acpi.h>
114abbd783SPaul Gortmaker #include <linux/export.h>
123fc40449SVinod Koul #include <linux/io.h>
134abbd783SPaul Gortmaker #include <linux/module.h>
14d62a7d41SVinod Koul #include <linux/platform_device.h>
15d62a7d41SVinod Koul #include <linux/soundwire/sdw_intel.h>
16b6109dd6SPierre-Louis Bossart #include "cadence_master.h"
17d62a7d41SVinod Koul #include "intel.h"
18d62a7d41SVinod Koul 
196f11586fSPierre-Louis Bossart #define SDW_LINK_TYPE		4 /* from Intel ACPI documentation */
20d62a7d41SVinod Koul #define SDW_MAX_LINKS		4
21d62a7d41SVinod Koul #define SDW_SHIM_LCAP		0x0
22d62a7d41SVinod Koul #define SDW_SHIM_BASE		0x2C000
23d62a7d41SVinod Koul #define SDW_ALH_BASE		0x2C800
24d62a7d41SVinod Koul #define SDW_LINK_BASE		0x30000
25d62a7d41SVinod Koul #define SDW_LINK_SIZE		0x10000
26d62a7d41SVinod Koul 
276d2c6669SPierre-Louis Bossart static int ctrl_link_mask;
286d2c6669SPierre-Louis Bossart module_param_named(sdw_link_mask, ctrl_link_mask, int, 0444);
2950302fc7SPierre-Louis Bossart MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)");
3050302fc7SPierre-Louis Bossart 
316d2c6669SPierre-Louis Bossart static bool is_link_enabled(struct fwnode_handle *fw_node, int i)
326d2c6669SPierre-Louis Bossart {
336d2c6669SPierre-Louis Bossart 	struct fwnode_handle *link;
346d2c6669SPierre-Louis Bossart 	char name[32];
356d2c6669SPierre-Louis Bossart 	u32 quirk_mask = 0;
366d2c6669SPierre-Louis Bossart 
376d2c6669SPierre-Louis Bossart 	/* Find master handle */
386d2c6669SPierre-Louis Bossart 	snprintf(name, sizeof(name),
396d2c6669SPierre-Louis Bossart 		 "mipi-sdw-link-%d-subproperties", i);
406d2c6669SPierre-Louis Bossart 
416d2c6669SPierre-Louis Bossart 	link = fwnode_get_named_child_node(fw_node, name);
426d2c6669SPierre-Louis Bossart 	if (!link)
436d2c6669SPierre-Louis Bossart 		return false;
446d2c6669SPierre-Louis Bossart 
456d2c6669SPierre-Louis Bossart 	fwnode_property_read_u32(link,
466d2c6669SPierre-Louis Bossart 				 "intel-quirk-mask",
476d2c6669SPierre-Louis Bossart 				 &quirk_mask);
486d2c6669SPierre-Louis Bossart 
496d2c6669SPierre-Louis Bossart 	if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
506d2c6669SPierre-Louis Bossart 		return false;
516d2c6669SPierre-Louis Bossart 
526d2c6669SPierre-Louis Bossart 	return true;
536d2c6669SPierre-Louis Bossart }
546d2c6669SPierre-Louis Bossart 
556d2c6669SPierre-Louis Bossart static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
56d62a7d41SVinod Koul {
57f98f690fSPierre-Louis Bossart 	struct sdw_intel_link_res *link = ctx->links;
586d2c6669SPierre-Louis Bossart 	u32 link_mask;
59d62a7d41SVinod Koul 	int i;
60d62a7d41SVinod Koul 
61d62a7d41SVinod Koul 	if (!link)
62d62a7d41SVinod Koul 		return 0;
63d62a7d41SVinod Koul 
646d2c6669SPierre-Louis Bossart 	link_mask = ctx->link_mask;
656d2c6669SPierre-Louis Bossart 
666d2c6669SPierre-Louis Bossart 	for (i = 0; i < ctx->count; i++, link++) {
676d2c6669SPierre-Louis Bossart 		if (!(link_mask & BIT(i)))
686d2c6669SPierre-Louis Bossart 			continue;
696d2c6669SPierre-Louis Bossart 
70d62a7d41SVinod Koul 		if (link->pdev)
71d62a7d41SVinod Koul 			platform_device_unregister(link->pdev);
72d62a7d41SVinod Koul 	}
73d62a7d41SVinod Koul 
74d62a7d41SVinod Koul 	return 0;
75d62a7d41SVinod Koul }
76d62a7d41SVinod Koul 
776d2c6669SPierre-Louis Bossart static int
786d2c6669SPierre-Louis Bossart sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
79d62a7d41SVinod Koul {
80d62a7d41SVinod Koul 	struct acpi_device *adev;
81d62a7d41SVinod Koul 	int ret, i;
82d62a7d41SVinod Koul 	u8 count;
83d62a7d41SVinod Koul 
846d2c6669SPierre-Louis Bossart 	if (acpi_bus_get_device(info->handle, &adev))
856d2c6669SPierre-Louis Bossart 		return -EINVAL;
86d62a7d41SVinod Koul 
87d62a7d41SVinod Koul 	/* Found controller, find links supported */
88d62a7d41SVinod Koul 	count = 0;
89d62a7d41SVinod Koul 	ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
90d62a7d41SVinod Koul 					    "mipi-sdw-master-count", &count, 1);
91d62a7d41SVinod Koul 
926d2c6669SPierre-Louis Bossart 	/*
936d2c6669SPierre-Louis Bossart 	 * In theory we could check the number of links supported in
946d2c6669SPierre-Louis Bossart 	 * hardware, but in that step we cannot assume SoundWire IP is
956d2c6669SPierre-Louis Bossart 	 * powered.
966d2c6669SPierre-Louis Bossart 	 *
976d2c6669SPierre-Louis Bossart 	 * In addition, if the BIOS doesn't even provide this
986d2c6669SPierre-Louis Bossart 	 * 'master-count' property then all the inits based on link
996d2c6669SPierre-Louis Bossart 	 * masks will fail as well.
1006d2c6669SPierre-Louis Bossart 	 *
1016d2c6669SPierre-Louis Bossart 	 * We will check the hardware capabilities in the startup() step
1026d2c6669SPierre-Louis Bossart 	 */
1036d2c6669SPierre-Louis Bossart 
104d62a7d41SVinod Koul 	if (ret) {
105d62a7d41SVinod Koul 		dev_err(&adev->dev,
106d62a7d41SVinod Koul 			"Failed to read mipi-sdw-master-count: %d\n", ret);
1076d2c6669SPierre-Louis Bossart 		return -EINVAL;
108d62a7d41SVinod Koul 	}
109d62a7d41SVinod Koul 
110d62a7d41SVinod Koul 	/* Check count is within bounds */
111d62a7d41SVinod Koul 	if (count > SDW_MAX_LINKS) {
112d62a7d41SVinod Koul 		dev_err(&adev->dev, "Link count %d exceeds max %d\n",
113d62a7d41SVinod Koul 			count, SDW_MAX_LINKS);
1146d2c6669SPierre-Louis Bossart 		return -EINVAL;
1156f7219feSGuennadi Liakhovetski 	}
1166f7219feSGuennadi Liakhovetski 
1176f7219feSGuennadi Liakhovetski 	if (!count) {
118432732b8SPierre-Louis Bossart 		dev_warn(&adev->dev, "No SoundWire links detected\n");
1196d2c6669SPierre-Louis Bossart 		return -EINVAL;
1206d2c6669SPierre-Louis Bossart 	}
1216d2c6669SPierre-Louis Bossart 	dev_dbg(&adev->dev, "ACPI reports %d SDW Link devices\n", count);
1226d2c6669SPierre-Louis Bossart 
1236d2c6669SPierre-Louis Bossart 	info->count = count;
1246d2c6669SPierre-Louis Bossart 	info->link_mask = 0;
1256d2c6669SPierre-Louis Bossart 
1266d2c6669SPierre-Louis Bossart 	for (i = 0; i < count; i++) {
1276d2c6669SPierre-Louis Bossart 		if (ctrl_link_mask && !(ctrl_link_mask & BIT(i))) {
1286d2c6669SPierre-Louis Bossart 			dev_dbg(&adev->dev,
1296d2c6669SPierre-Louis Bossart 				"Link %d masked, will not be enabled\n", i);
1306d2c6669SPierre-Louis Bossart 			continue;
131d62a7d41SVinod Koul 		}
132d62a7d41SVinod Koul 
1336d2c6669SPierre-Louis Bossart 		if (!is_link_enabled(acpi_fwnode_handle(adev), i)) {
1346d2c6669SPierre-Louis Bossart 			dev_dbg(&adev->dev,
1356d2c6669SPierre-Louis Bossart 				"Link %d not selected in firmware\n", i);
1366d2c6669SPierre-Louis Bossart 			continue;
1376d2c6669SPierre-Louis Bossart 		}
1386d2c6669SPierre-Louis Bossart 
1396d2c6669SPierre-Louis Bossart 		info->link_mask |= BIT(i);
1406d2c6669SPierre-Louis Bossart 	}
1416d2c6669SPierre-Louis Bossart 
1426d2c6669SPierre-Louis Bossart 	return 0;
1436d2c6669SPierre-Louis Bossart }
1446d2c6669SPierre-Louis Bossart 
1456d2c6669SPierre-Louis Bossart static struct sdw_intel_ctx
1466d2c6669SPierre-Louis Bossart *sdw_intel_probe_controller(struct sdw_intel_res *res)
1476d2c6669SPierre-Louis Bossart {
1486d2c6669SPierre-Louis Bossart 	struct platform_device_info pdevinfo;
1496d2c6669SPierre-Louis Bossart 	struct platform_device *pdev;
1506d2c6669SPierre-Louis Bossart 	struct sdw_intel_link_res *link;
1516d2c6669SPierre-Louis Bossart 	struct sdw_intel_ctx *ctx;
1526d2c6669SPierre-Louis Bossart 	struct acpi_device *adev;
1536d2c6669SPierre-Louis Bossart 	u32 link_mask;
1546d2c6669SPierre-Louis Bossart 	int count;
1556d2c6669SPierre-Louis Bossart 	int i;
1566d2c6669SPierre-Louis Bossart 
1576d2c6669SPierre-Louis Bossart 	if (!res)
1586d2c6669SPierre-Louis Bossart 		return NULL;
1596d2c6669SPierre-Louis Bossart 
1606d2c6669SPierre-Louis Bossart 	if (acpi_bus_get_device(res->handle, &adev))
1616d2c6669SPierre-Louis Bossart 		return NULL;
1626d2c6669SPierre-Louis Bossart 
1636d2c6669SPierre-Louis Bossart 	if (!res->count)
1646d2c6669SPierre-Louis Bossart 		return NULL;
1656d2c6669SPierre-Louis Bossart 
1666d2c6669SPierre-Louis Bossart 	count = res->count;
167d62a7d41SVinod Koul 	dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count);
168d62a7d41SVinod Koul 
169dd906cc6SPierre-Louis Bossart 	ctx = devm_kzalloc(&adev->dev, sizeof(*ctx), GFP_KERNEL);
170d62a7d41SVinod Koul 	if (!ctx)
171d62a7d41SVinod Koul 		return NULL;
172d62a7d41SVinod Koul 
173d62a7d41SVinod Koul 	ctx->count = count;
174dd906cc6SPierre-Louis Bossart 	ctx->links = devm_kcalloc(&adev->dev, ctx->count,
175dd906cc6SPierre-Louis Bossart 				  sizeof(*ctx->links), GFP_KERNEL);
176d62a7d41SVinod Koul 	if (!ctx->links)
177dd906cc6SPierre-Louis Bossart 		return NULL;
178d62a7d41SVinod Koul 
1796d2c6669SPierre-Louis Bossart 	ctx->count = count;
1806d2c6669SPierre-Louis Bossart 	ctx->mmio_base = res->mmio_base;
1816d2c6669SPierre-Louis Bossart 	ctx->link_mask = res->link_mask;
1826d2c6669SPierre-Louis Bossart 	ctx->handle = res->handle;
183*4a17c441SPierre-Louis Bossart 	mutex_init(&ctx->shim_lock);
1846d2c6669SPierre-Louis Bossart 
185d62a7d41SVinod Koul 	link = ctx->links;
1866d2c6669SPierre-Louis Bossart 	link_mask = ctx->link_mask;
187d62a7d41SVinod Koul 
188d62a7d41SVinod Koul 	/* Create SDW Master devices */
1896d2c6669SPierre-Louis Bossart 	for (i = 0; i < count; i++, link++) {
1909cd1c5a7SPierre-Louis Bossart 		if (!(link_mask & BIT(i))) {
19150302fc7SPierre-Louis Bossart 			dev_dbg(&adev->dev,
19250302fc7SPierre-Louis Bossart 				"Link %d masked, will not be enabled\n", i);
19350302fc7SPierre-Louis Bossart 			continue;
19450302fc7SPierre-Louis Bossart 		}
19550302fc7SPierre-Louis Bossart 
1966d2c6669SPierre-Louis Bossart 		link->mmio_base = res->mmio_base;
197f98f690fSPierre-Louis Bossart 		link->registers = res->mmio_base + SDW_LINK_BASE
198d62a7d41SVinod Koul 			+ (SDW_LINK_SIZE * i);
199f98f690fSPierre-Louis Bossart 		link->shim = res->mmio_base + SDW_SHIM_BASE;
200f98f690fSPierre-Louis Bossart 		link->alh = res->mmio_base + SDW_ALH_BASE;
201d62a7d41SVinod Koul 
202f98f690fSPierre-Louis Bossart 		link->ops = res->ops;
2034b206d34SRander Wang 		link->dev = res->dev;
204c46302ecSVinod Koul 
205*4a17c441SPierre-Louis Bossart 		link->shim_lock = &ctx->shim_lock;
206*4a17c441SPierre-Louis Bossart 		link->shim_mask = &ctx->shim_mask;
207*4a17c441SPierre-Louis Bossart 
208d62a7d41SVinod Koul 		memset(&pdevinfo, 0, sizeof(pdevinfo));
209d62a7d41SVinod Koul 
210d62a7d41SVinod Koul 		pdevinfo.parent = res->parent;
2116d2c6669SPierre-Louis Bossart 		pdevinfo.name = "intel-sdw";
212d62a7d41SVinod Koul 		pdevinfo.id = i;
213d62a7d41SVinod Koul 		pdevinfo.fwnode = acpi_fwnode_handle(adev);
2144ab34412SPierre-Louis Bossart 		pdevinfo.data = link;
2154ab34412SPierre-Louis Bossart 		pdevinfo.size_data = sizeof(*link);
216d62a7d41SVinod Koul 
217d62a7d41SVinod Koul 		pdev = platform_device_register_full(&pdevinfo);
218d62a7d41SVinod Koul 		if (IS_ERR(pdev)) {
219d62a7d41SVinod Koul 			dev_err(&adev->dev,
220d62a7d41SVinod Koul 				"platform device creation failed: %ld\n",
221d62a7d41SVinod Koul 				PTR_ERR(pdev));
2226d2c6669SPierre-Louis Bossart 			goto err;
223d62a7d41SVinod Koul 		}
224d62a7d41SVinod Koul 		link->pdev = pdev;
225d62a7d41SVinod Koul 	}
226d62a7d41SVinod Koul 
227d62a7d41SVinod Koul 	return ctx;
228d62a7d41SVinod Koul 
2296d2c6669SPierre-Louis Bossart err:
230dd906cc6SPierre-Louis Bossart 	ctx->count = i;
2316d2c6669SPierre-Louis Bossart 	sdw_intel_cleanup(ctx);
232d62a7d41SVinod Koul 	return NULL;
233d62a7d41SVinod Koul }
234d62a7d41SVinod Koul 
2356d2c6669SPierre-Louis Bossart static int
2366d2c6669SPierre-Louis Bossart sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
2376d2c6669SPierre-Louis Bossart {
2386d2c6669SPierre-Louis Bossart 	struct acpi_device *adev;
2396d2c6669SPierre-Louis Bossart 	struct sdw_intel_link_res *link;
2406d2c6669SPierre-Louis Bossart 	u32 caps;
2416d2c6669SPierre-Louis Bossart 	u32 link_mask;
2426d2c6669SPierre-Louis Bossart 	int i;
2436d2c6669SPierre-Louis Bossart 
2446d2c6669SPierre-Louis Bossart 	if (acpi_bus_get_device(ctx->handle, &adev))
2456d2c6669SPierre-Louis Bossart 		return -EINVAL;
2466d2c6669SPierre-Louis Bossart 
2476d2c6669SPierre-Louis Bossart 	/* Check SNDWLCAP.LCOUNT */
2486d2c6669SPierre-Louis Bossart 	caps = ioread32(ctx->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
2496d2c6669SPierre-Louis Bossart 	caps &= GENMASK(2, 0);
2506d2c6669SPierre-Louis Bossart 
2516d2c6669SPierre-Louis Bossart 	/* Check HW supported vs property value */
2526d2c6669SPierre-Louis Bossart 	if (caps < ctx->count) {
2536d2c6669SPierre-Louis Bossart 		dev_err(&adev->dev,
2546d2c6669SPierre-Louis Bossart 			"BIOS master count is larger than hardware capabilities\n");
2556d2c6669SPierre-Louis Bossart 		return -EINVAL;
2566d2c6669SPierre-Louis Bossart 	}
2576d2c6669SPierre-Louis Bossart 
2586d2c6669SPierre-Louis Bossart 	if (!ctx->links)
2596d2c6669SPierre-Louis Bossart 		return -EINVAL;
2606d2c6669SPierre-Louis Bossart 
2616d2c6669SPierre-Louis Bossart 	link = ctx->links;
2626d2c6669SPierre-Louis Bossart 	link_mask = ctx->link_mask;
2636d2c6669SPierre-Louis Bossart 
2646d2c6669SPierre-Louis Bossart 	/* Startup SDW Master devices */
2656d2c6669SPierre-Louis Bossart 	for (i = 0; i < ctx->count; i++, link++) {
2666d2c6669SPierre-Louis Bossart 		if (!(link_mask & BIT(i)))
2676d2c6669SPierre-Louis Bossart 			continue;
2686d2c6669SPierre-Louis Bossart 
2696d2c6669SPierre-Louis Bossart 		intel_master_startup(link->pdev);
2706d2c6669SPierre-Louis Bossart 	}
2716d2c6669SPierre-Louis Bossart 
2726d2c6669SPierre-Louis Bossart 	return 0;
2736d2c6669SPierre-Louis Bossart }
2746d2c6669SPierre-Louis Bossart 
275d62a7d41SVinod Koul static acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level,
276d62a7d41SVinod Koul 				     void *cdata, void **return_value)
277d62a7d41SVinod Koul {
2786d2c6669SPierre-Louis Bossart 	struct sdw_intel_acpi_info *info = cdata;
279d62a7d41SVinod Koul 	struct acpi_device *adev;
2806f11586fSPierre-Louis Bossart 	acpi_status status;
2816f11586fSPierre-Louis Bossart 	u64 adr;
2826f11586fSPierre-Louis Bossart 
2836f11586fSPierre-Louis Bossart 	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
2846f11586fSPierre-Louis Bossart 	if (ACPI_FAILURE(status))
2856f11586fSPierre-Louis Bossart 		return AE_OK; /* keep going */
286d62a7d41SVinod Koul 
287d62a7d41SVinod Koul 	if (acpi_bus_get_device(handle, &adev)) {
288e1c815f4SVinod Koul 		pr_err("%s: Couldn't find ACPI handle\n", __func__);
289d62a7d41SVinod Koul 		return AE_NOT_FOUND;
290d62a7d41SVinod Koul 	}
291d62a7d41SVinod Koul 
2926d2c6669SPierre-Louis Bossart 	info->handle = handle;
2936f11586fSPierre-Louis Bossart 
2946f11586fSPierre-Louis Bossart 	/*
2956f11586fSPierre-Louis Bossart 	 * On some Intel platforms, multiple children of the HDAS
2966f11586fSPierre-Louis Bossart 	 * device can be found, but only one of them is the SoundWire
2976f11586fSPierre-Louis Bossart 	 * controller. The SNDW device is always exposed with
2986f11586fSPierre-Louis Bossart 	 * Name(_ADR, 0x40000000), with bits 31..28 representing the
2996f11586fSPierre-Louis Bossart 	 * SoundWire link so filter accordingly
3006f11586fSPierre-Louis Bossart 	 */
3016f11586fSPierre-Louis Bossart 	if ((adr & GENMASK(31, 28)) >> 28 != SDW_LINK_TYPE)
3026f11586fSPierre-Louis Bossart 		return AE_OK; /* keep going */
3036f11586fSPierre-Louis Bossart 
3046f11586fSPierre-Louis Bossart 	/* device found, stop namespace walk */
3056f11586fSPierre-Louis Bossart 	return AE_CTRL_TERMINATE;
306d62a7d41SVinod Koul }
307d62a7d41SVinod Koul 
308d62a7d41SVinod Koul /**
3096d2c6669SPierre-Louis Bossart  * sdw_intel_acpi_scan() - SoundWire Intel init routine
310d62a7d41SVinod Koul  * @parent_handle: ACPI parent handle
3116d2c6669SPierre-Louis Bossart  * @info: description of what firmware/DSDT tables expose
312d62a7d41SVinod Koul  *
3136d2c6669SPierre-Louis Bossart  * This scans the namespace and queries firmware to figure out which
3146d2c6669SPierre-Louis Bossart  * links to enable. A follow-up use of sdw_intel_probe() and
3156d2c6669SPierre-Louis Bossart  * sdw_intel_startup() is required for creation of devices and bus
3166d2c6669SPierre-Louis Bossart  * startup
317d62a7d41SVinod Koul  */
3186d2c6669SPierre-Louis Bossart int sdw_intel_acpi_scan(acpi_handle *parent_handle,
3196d2c6669SPierre-Louis Bossart 			struct sdw_intel_acpi_info *info)
320d62a7d41SVinod Koul {
321d62a7d41SVinod Koul 	acpi_status status;
322d62a7d41SVinod Koul 
323d62a7d41SVinod Koul 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
324d62a7d41SVinod Koul 				     parent_handle, 1,
325d62a7d41SVinod Koul 				     sdw_intel_acpi_cb,
3266d2c6669SPierre-Louis Bossart 				     NULL, info, NULL);
327d62a7d41SVinod Koul 	if (ACPI_FAILURE(status))
3286d2c6669SPierre-Louis Bossart 		return -ENODEV;
329d62a7d41SVinod Koul 
3306d2c6669SPierre-Louis Bossart 	return sdw_intel_scan_controller(info);
331d62a7d41SVinod Koul }
3326d2c6669SPierre-Louis Bossart EXPORT_SYMBOL(sdw_intel_acpi_scan);
333d62a7d41SVinod Koul 
334d62a7d41SVinod Koul /**
3356d2c6669SPierre-Louis Bossart  * sdw_intel_probe() - SoundWire Intel probe routine
3366d2c6669SPierre-Louis Bossart  * @res: resource data
3376d2c6669SPierre-Louis Bossart  *
3386d2c6669SPierre-Louis Bossart  * This registers a platform device for each Master handled by the controller,
3396d2c6669SPierre-Louis Bossart  * and SoundWire Master and Slave devices will be created by the platform
3406d2c6669SPierre-Louis Bossart  * device probe. All the information necessary is stored in the context, and
3416d2c6669SPierre-Louis Bossart  * the res argument pointer can be freed after this step.
3426d2c6669SPierre-Louis Bossart  * This function will be called after sdw_intel_acpi_scan() by SOF probe.
3436d2c6669SPierre-Louis Bossart  */
3446d2c6669SPierre-Louis Bossart struct sdw_intel_ctx
3456d2c6669SPierre-Louis Bossart *sdw_intel_probe(struct sdw_intel_res *res)
3466d2c6669SPierre-Louis Bossart {
3476d2c6669SPierre-Louis Bossart 	return sdw_intel_probe_controller(res);
3486d2c6669SPierre-Louis Bossart }
3496d2c6669SPierre-Louis Bossart EXPORT_SYMBOL(sdw_intel_probe);
3506d2c6669SPierre-Louis Bossart 
3516d2c6669SPierre-Louis Bossart /**
3526d2c6669SPierre-Louis Bossart  * sdw_intel_startup() - SoundWire Intel startup
3536d2c6669SPierre-Louis Bossart  * @ctx: SoundWire context allocated in the probe
3546d2c6669SPierre-Louis Bossart  *
3556d2c6669SPierre-Louis Bossart  * Startup Intel SoundWire controller. This function will be called after
3566d2c6669SPierre-Louis Bossart  * Intel Audio DSP is powered up.
3576d2c6669SPierre-Louis Bossart  */
3586d2c6669SPierre-Louis Bossart int sdw_intel_startup(struct sdw_intel_ctx *ctx)
3596d2c6669SPierre-Louis Bossart {
3606d2c6669SPierre-Louis Bossart 	return sdw_intel_startup_controller(ctx);
3616d2c6669SPierre-Louis Bossart }
3626d2c6669SPierre-Louis Bossart EXPORT_SYMBOL(sdw_intel_startup);
3636d2c6669SPierre-Louis Bossart /**
364d62a7d41SVinod Koul  * sdw_intel_exit() - SoundWire Intel exit
3656d2c6669SPierre-Louis Bossart  * @ctx: SoundWire context allocated in the probe
366d62a7d41SVinod Koul  *
367d62a7d41SVinod Koul  * Delete the controller instances created and cleanup
368d62a7d41SVinod Koul  */
369f98f690fSPierre-Louis Bossart void sdw_intel_exit(struct sdw_intel_ctx *ctx)
370d62a7d41SVinod Koul {
3716d2c6669SPierre-Louis Bossart 	sdw_intel_cleanup(ctx);
372d62a7d41SVinod Koul }
373d62a7d41SVinod Koul EXPORT_SYMBOL(sdw_intel_exit);
374d62a7d41SVinod Koul 
375d62a7d41SVinod Koul MODULE_LICENSE("Dual BSD/GPL");
376d62a7d41SVinod Koul MODULE_DESCRIPTION("Intel Soundwire Init Library");
377