-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
soundwire: amd: refactor amd soundwire manager device node creation
Refactor amd SoundWire manager device node creation logic and implement generic functions to have a common functionality for SoundWire manager platform device creation, start and exit sequence for both legacy(NO DSP) and SOF stack for AMD platforms. These functions will be invoked from legacy and SOF stack. Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com> Acked-by: Vinod Koul <vkoul@kernel.org> Link: https://msgid.link/r/20240129055147.1493853-4-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown <broonie@kernel.org>
- Loading branch information
Vijendar Mukunda
authored and
Mark Brown
committed
Jan 30, 2024
1 parent
a477464
commit ed5e874
Showing
5 changed files
with
220 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) | ||
/* | ||
* SoundWire AMD Manager Initialize routines | ||
* | ||
* Initializes and creates SDW devices based on ACPI and Hardware values | ||
* | ||
* Copyright 2024 Advanced Micro Devices, Inc. | ||
*/ | ||
|
||
#include <linux/acpi.h> | ||
#include <linux/export.h> | ||
#include <linux/io.h> | ||
#include <linux/module.h> | ||
#include <linux/platform_device.h> | ||
|
||
#include "amd_init.h" | ||
|
||
static int sdw_amd_cleanup(struct sdw_amd_ctx *ctx) | ||
{ | ||
int i; | ||
|
||
for (i = 0; i < ctx->count; i++) { | ||
if (!(ctx->link_mask & BIT(i))) | ||
continue; | ||
platform_device_unregister(ctx->pdev[i]); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res) | ||
{ | ||
struct sdw_amd_ctx *ctx; | ||
struct acpi_device *adev; | ||
struct resource *sdw_res; | ||
struct acp_sdw_pdata sdw_pdata[2]; | ||
struct platform_device_info pdevinfo[2]; | ||
u32 link_mask; | ||
int count, index; | ||
|
||
if (!res) | ||
return NULL; | ||
|
||
adev = acpi_fetch_acpi_dev(res->handle); | ||
if (!adev) | ||
return NULL; | ||
|
||
if (!res->count) | ||
return NULL; | ||
|
||
count = res->count; | ||
dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count); | ||
|
||
/* | ||
* we need to alloc/free memory manually and can't use devm: | ||
* this routine may be called from a workqueue, and not from | ||
* the parent .probe. | ||
* If devm_ was used, the memory might never be freed on errors. | ||
*/ | ||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
if (!ctx) | ||
return NULL; | ||
|
||
ctx->count = count; | ||
ctx->link_mask = res->link_mask; | ||
sdw_res = kzalloc(sizeof(*sdw_res), GFP_KERNEL); | ||
if (!sdw_res) { | ||
kfree(ctx); | ||
return NULL; | ||
} | ||
sdw_res->flags = IORESOURCE_MEM; | ||
sdw_res->start = res->addr; | ||
sdw_res->end = res->addr + res->reg_range; | ||
memset(&pdevinfo, 0, sizeof(pdevinfo)); | ||
link_mask = ctx->link_mask; | ||
for (index = 0; index < count; index++) { | ||
if (!(link_mask & BIT(index))) | ||
continue; | ||
|
||
sdw_pdata[index].instance = index; | ||
sdw_pdata[index].acp_sdw_lock = res->acp_lock; | ||
pdevinfo[index].name = "amd_sdw_manager"; | ||
pdevinfo[index].id = index; | ||
pdevinfo[index].parent = res->parent; | ||
pdevinfo[index].num_res = 1; | ||
pdevinfo[index].res = sdw_res; | ||
pdevinfo[index].data = &sdw_pdata[index]; | ||
pdevinfo[index].size_data = sizeof(struct acp_sdw_pdata); | ||
pdevinfo[index].fwnode = acpi_fwnode_handle(adev); | ||
ctx->pdev[index] = platform_device_register_full(&pdevinfo[index]); | ||
if (IS_ERR(ctx->pdev[index])) | ||
goto err; | ||
} | ||
kfree(sdw_res); | ||
return ctx; | ||
err: | ||
while (index--) { | ||
if (!(link_mask & BIT(index))) | ||
continue; | ||
|
||
platform_device_unregister(ctx->pdev[index]); | ||
} | ||
|
||
kfree(sdw_res); | ||
kfree(ctx); | ||
return NULL; | ||
} | ||
|
||
static int sdw_amd_startup(struct sdw_amd_ctx *ctx) | ||
{ | ||
struct amd_sdw_manager *amd_manager; | ||
int i, ret; | ||
|
||
/* Startup SDW Manager devices */ | ||
for (i = 0; i < ctx->count; i++) { | ||
if (!(ctx->link_mask & BIT(i))) | ||
continue; | ||
amd_manager = dev_get_drvdata(&ctx->pdev[i]->dev); | ||
ret = amd_sdw_manager_start(amd_manager); | ||
if (ret) | ||
return ret; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int sdw_amd_probe(struct sdw_amd_res *res, struct sdw_amd_ctx **sdw_ctx) | ||
{ | ||
*sdw_ctx = sdw_amd_probe_controller(res); | ||
if (!*sdw_ctx) | ||
return -ENODEV; | ||
|
||
return sdw_amd_startup(*sdw_ctx); | ||
} | ||
EXPORT_SYMBOL_NS(sdw_amd_probe, SOUNDWIRE_AMD_INIT); | ||
|
||
void sdw_amd_exit(struct sdw_amd_ctx *ctx) | ||
{ | ||
sdw_amd_cleanup(ctx); | ||
kfree(ctx->ids); | ||
kfree(ctx); | ||
} | ||
EXPORT_SYMBOL_NS(sdw_amd_exit, SOUNDWIRE_AMD_INIT); | ||
|
||
MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); | ||
MODULE_DESCRIPTION("AMD SoundWire Init Library"); | ||
MODULE_LICENSE("Dual BSD/GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ | ||
/* | ||
* Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. | ||
*/ | ||
|
||
#ifndef __AMD_INIT_H | ||
#define __AMD_INIT_H | ||
|
||
#include <linux/soundwire/sdw_amd.h> | ||
|
||
int amd_sdw_manager_start(struct amd_sdw_manager *amd_manager); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters