Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: amd: ps: refactor acp child platform device creation code

Refactor ACP child platform device creation code based on acp config.
Use common SoundWire manager functions for device probe and exit
sequences.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://msgid.link/r/20240214104014.1144668-2-Vijendar.Mukunda@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Vijendar Mukunda and committed by
Mark Brown
eaf82503 0386d765

+120 -194
+13 -56
sound/soc/amd/ps/acp63.h
··· 11 11 #define ACP_DEVICE_ID 0x15E2 12 12 #define ACP63_REG_START 0x1240000 13 13 #define ACP63_REG_END 0x1250200 14 - #define ACP63_DEVS 5 15 14 16 15 #define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001 17 16 #define ACP_PGFSM_CNTL_POWER_ON_MASK 1 ··· 55 56 56 57 #define ACP_DMIC_DEV 2 57 58 58 - /* ACP63_PDM_MODE_DEVS corresponds to platform devices count for ACP PDM configuration */ 59 - #define ACP63_PDM_MODE_DEVS 3 60 - 61 - /* 62 - * ACP63_SDW0_MODE_DEVS corresponds to platform devices count for 63 - * SW0 SoundWire manager instance configuration 64 - */ 65 - #define ACP63_SDW0_MODE_DEVS 2 66 - 67 - /* 68 - * ACP63_SDW0_SDW1_MODE_DEVS corresponds to platform devices count for SW0 + SW1 SoundWire manager 69 - * instances configuration 70 - */ 71 - #define ACP63_SDW0_SDW1_MODE_DEVS 3 72 - 73 - /* 74 - * ACP63_SDW0_PDM_MODE_DEVS corresponds to platform devices count for SW0 manager 75 - * instance + ACP PDM controller configuration 76 - */ 77 - #define ACP63_SDW0_PDM_MODE_DEVS 4 78 - 79 - /* 80 - * ACP63_SDW0_SDW1_PDM_MODE_DEVS corresponds to platform devices count for 81 - * SW0 + SW1 SoundWire manager instances + ACP PDM controller configuration 82 - */ 83 - #define ACP63_SDW0_SDW1_PDM_MODE_DEVS 5 84 59 #define ACP63_DMIC_ADDR 2 85 60 #define ACP63_SDW_ADDR 5 86 61 #define AMD_SDW_MAX_MANAGERS 2 ··· 62 89 /* time in ms for acp timeout */ 63 90 #define ACP_TIMEOUT 500 64 91 65 - /* ACP63_PDM_DEV_CONFIG corresponds to platform device configuration for ACP PDM controller */ 66 - #define ACP63_PDM_DEV_CONFIG BIT(0) 67 - 68 - /* ACP63_SDW_DEV_CONFIG corresponds to platform device configuration for SDW manager instances */ 69 - #define ACP63_SDW_DEV_CONFIG BIT(1) 70 - 71 - /* 72 - * ACP63_SDW_PDM_DEV_CONFIG corresponds to platform device configuration for ACP PDM + SoundWire 73 - * manager instance combination. 74 - */ 75 - #define ACP63_SDW_PDM_DEV_CONFIG GENMASK(1, 0) 76 92 #define ACP_SDW0_STAT BIT(21) 77 93 #define ACP_SDW1_STAT BIT(2) 78 94 #define ACP_ERROR_IRQ BIT(29) ··· 216 254 * struct acp63_dev_data - acp pci driver context 217 255 * @acp63_base: acp mmio base 218 256 * @res: resource 219 - * @pdev: array of child platform device node structures 257 + * @pdm_dev: ACP PDM controller platform device 258 + * @dmic_codec: platform device for DMIC Codec 259 + * sdw_dma_dev: platform device for SoundWire DMA controller 220 260 * @acp_lock: used to protect acp common registers 221 - * @sdw_fw_node: SoundWire controller fw node handle 222 - * @pdev_config: platform device configuration 223 - * @pdev_count: platform devices count 224 - * @pdm_dev_index: pdm platform device index 225 - * @sdw_manager_count: SoundWire manager instance count 226 - * @sdw0_dev_index: SoundWire Manager-0 platform device index 227 - * @sdw1_dev_index: SoundWire Manager-1 platform device index 228 - * @sdw_dma_dev_index: SoundWire DMA controller platform device index 229 261 * @info: SoundWire AMD information found in ACPI tables 262 + * @sdw: SoundWire context for all SoundWire manager instances 230 263 * @is_sdw_dev: flag set to true when any SoundWire manager instances are available 231 264 * @is_pdm_dev: flag set to true when ACP PDM controller exists 232 265 * @is_pdm_config: flat set to true when PDM configuration is selected from BIOS 233 266 * @is_sdw_config: flag set to true when SDW configuration is selected from BIOS 267 + * @addr: pci ioremap address 268 + * @reg_range: ACP reigister range 234 269 * @sdw0-dma_intr_stat: DMA interrupt status array for SoundWire manager-SW0 instance 235 270 * @sdw_dma_intr_stat: DMA interrupt status array for SoundWire manager-SW1 instance 236 271 * @acp_reset: flag set to true when bus reset is applied across all ··· 237 278 struct acp63_dev_data { 238 279 void __iomem *acp63_base; 239 280 struct resource *res; 240 - struct platform_device *pdev[ACP63_DEVS]; 281 + struct platform_device *pdm_dev; 282 + struct platform_device *dmic_codec_dev; 283 + struct platform_device *sdw_dma_dev; 241 284 struct mutex acp_lock; /* protect shared registers */ 242 - struct fwnode_handle *sdw_fw_node; 243 - u16 pdev_config; 244 - u16 pdev_count; 245 - u16 pdm_dev_index; 246 - u8 sdw_manager_count; 247 - u16 sdw0_dev_index; 248 - u16 sdw1_dev_index; 249 - u16 sdw_dma_dev_index; 250 285 struct sdw_amd_acpi_info info; 286 + /* sdw context allocated by SoundWire driver */ 287 + struct sdw_amd_ctx *sdw; 251 288 bool is_sdw_dev; 252 289 bool is_pdm_dev; 253 290 bool is_pdm_config; 254 291 bool is_sdw_config; 292 + u32 addr; 293 + u32 reg_range; 255 294 u16 sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS]; 256 295 u16 sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; 257 296 bool acp_reset;
+107 -138
sound/soc/amd/ps/pci-ps.c
··· 104 104 struct sdw_dma_dev_data *sdw_dma_data; 105 105 struct acp63_dev_data *adata = context; 106 106 u32 stream_index; 107 - u16 pdev_index; 108 107 109 - pdev_index = adata->sdw_dma_dev_index; 110 - sdw_dma_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev); 108 + sdw_dma_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); 111 109 112 110 for (stream_index = 0; stream_index < ACP63_SDW0_DMA_MAX_STREAMS; stream_index++) { 113 111 if (adata->sdw0_dma_intr_stat[stream_index]) { ··· 133 135 u32 stream_id = 0; 134 136 u16 irq_flag = 0; 135 137 u16 sdw_dma_irq_flag = 0; 136 - u16 pdev_index; 137 138 u16 index; 138 139 139 140 adata = dev_id; ··· 146 149 ext_intr_stat = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT); 147 150 if (ext_intr_stat & ACP_SDW0_STAT) { 148 151 writel(ACP_SDW0_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT); 149 - pdev_index = adata->sdw0_dev_index; 150 - amd_manager = dev_get_drvdata(&adata->pdev[pdev_index]->dev); 152 + amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev); 151 153 if (amd_manager) 152 154 schedule_work(&amd_manager->amd_sdw_irq_thread); 153 155 irq_flag = 1; ··· 155 159 ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); 156 160 if (ext_intr_stat1 & ACP_SDW1_STAT) { 157 161 writel(ACP_SDW1_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); 158 - pdev_index = adata->sdw1_dev_index; 159 - amd_manager = dev_get_drvdata(&adata->pdev[pdev_index]->dev); 162 + amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev); 160 163 if (amd_manager) 161 164 schedule_work(&amd_manager->amd_sdw_irq_thread); 162 165 irq_flag = 1; ··· 171 176 } 172 177 173 178 if (ext_intr_stat & BIT(PDM_DMA_STAT)) { 174 - pdev_index = adata->pdm_dev_index; 175 - ps_pdm_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev); 179 + ps_pdm_data = dev_get_drvdata(&adata->pdm_dev->dev); 176 180 writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); 177 181 if (ps_pdm_data->capture_stream) 178 182 snd_pcm_period_elapsed(ps_pdm_data->capture_stream); ··· 249 255 acp_data->info.count = AMD_SDW_MAX_MANAGERS; 250 256 return amd_sdw_scan_controller(&acp_data->info); 251 257 } 258 + 259 + static int amd_sdw_probe(struct device *dev) 260 + { 261 + struct acp63_dev_data *acp_data; 262 + struct sdw_amd_res sdw_res; 263 + int ret; 264 + 265 + acp_data = dev_get_drvdata(dev); 266 + memset(&sdw_res, 0, sizeof(sdw_res)); 267 + sdw_res.addr = acp_data->addr; 268 + sdw_res.reg_range = acp_data->reg_range; 269 + sdw_res.handle = acp_data->info.handle; 270 + sdw_res.parent = dev; 271 + sdw_res.dev = dev; 272 + sdw_res.acp_lock = &acp_data->acp_lock; 273 + sdw_res.count = acp_data->info.count; 274 + sdw_res.mmio_base = acp_data->acp63_base; 275 + sdw_res.link_mask = acp_data->info.link_mask; 276 + ret = sdw_amd_probe(&sdw_res, &acp_data->sdw); 277 + if (ret) 278 + dev_err(dev, "error: SoundWire probe failed\n"); 279 + return ret; 280 + } 281 + 282 + static int amd_sdw_exit(struct acp63_dev_data *acp_data) 283 + { 284 + if (acp_data->sdw) 285 + sdw_amd_exit(acp_data->sdw); 286 + acp_data->sdw = NULL; 287 + 288 + return 0; 289 + } 252 290 #else 253 291 static int acp_scan_sdw_devices(struct device *dev, u64 addr) 292 + { 293 + return 0; 294 + } 295 + 296 + static int amd_sdw_probe(struct device *dev) 297 + { 298 + return 0; 299 + } 300 + 301 + static int amd_sdw_exit(struct acp63_dev_data *acp_data) 254 302 { 255 303 return 0; 256 304 } ··· 379 343 380 344 static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data *adata, u32 addr) 381 345 { 382 - struct acp_sdw_pdata *sdw_pdata; 383 - struct platform_device_info pdevinfo[ACP63_DEVS]; 346 + struct platform_device_info pdevinfo; 384 347 struct device *parent; 385 - int index; 386 348 int ret; 387 349 388 350 parent = &pci->dev; 389 - dev_dbg(&pci->dev, 390 - "%s pdev_config:0x%x pdev_count:0x%x\n", __func__, adata->pdev_config, 391 - adata->pdev_count); 392 - if (adata->pdev_config) { 351 + 352 + if (adata->is_sdw_dev || adata->is_pdm_dev) { 393 353 adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL); 394 354 if (!adata->res) { 395 355 ret = -ENOMEM; ··· 397 365 memset(&pdevinfo, 0, sizeof(pdevinfo)); 398 366 } 399 367 400 - switch (adata->pdev_config) { 401 - case ACP63_PDM_DEV_CONFIG: 402 - adata->pdm_dev_index = 0; 403 - acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma", 368 + if (adata->is_pdm_dev && adata->is_pdm_config) { 369 + acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "acp_ps_pdm_dma", 404 370 0, adata->res, 1, NULL, 0); 405 - acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "dmic-codec", 406 - 0, NULL, 0, NULL, 0); 407 - acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "acp_ps_mach", 408 - 0, NULL, 0, NULL, 0); 409 - break; 410 - case ACP63_SDW_DEV_CONFIG: 411 - if (adata->pdev_count == ACP63_SDW0_MODE_DEVS) { 412 - sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata), 413 - GFP_KERNEL); 414 - if (!sdw_pdata) { 415 - ret = -ENOMEM; 416 - goto de_init; 417 - } 418 371 419 - sdw_pdata->instance = 0; 420 - sdw_pdata->acp_sdw_lock = &adata->acp_lock; 421 - adata->sdw0_dev_index = 0; 422 - adata->sdw_dma_dev_index = 1; 423 - acp63_fill_platform_dev_info(&pdevinfo[0], parent, adata->sdw_fw_node, 424 - "amd_sdw_manager", 0, adata->res, 1, 425 - sdw_pdata, sizeof(struct acp_sdw_pdata)); 426 - acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "amd_ps_sdw_dma", 427 - 0, adata->res, 1, NULL, 0); 428 - } else if (adata->pdev_count == ACP63_SDW0_SDW1_MODE_DEVS) { 429 - sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata) * 2, 430 - GFP_KERNEL); 431 - if (!sdw_pdata) { 432 - ret = -ENOMEM; 433 - goto de_init; 434 - } 435 - 436 - sdw_pdata[0].instance = 0; 437 - sdw_pdata[1].instance = 1; 438 - sdw_pdata[0].acp_sdw_lock = &adata->acp_lock; 439 - sdw_pdata[1].acp_sdw_lock = &adata->acp_lock; 440 - sdw_pdata->acp_sdw_lock = &adata->acp_lock; 441 - adata->sdw0_dev_index = 0; 442 - adata->sdw1_dev_index = 1; 443 - adata->sdw_dma_dev_index = 2; 444 - acp63_fill_platform_dev_info(&pdevinfo[0], parent, adata->sdw_fw_node, 445 - "amd_sdw_manager", 0, adata->res, 1, 446 - &sdw_pdata[0], sizeof(struct acp_sdw_pdata)); 447 - acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node, 448 - "amd_sdw_manager", 1, adata->res, 1, 449 - &sdw_pdata[1], sizeof(struct acp_sdw_pdata)); 450 - acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "amd_ps_sdw_dma", 451 - 0, adata->res, 1, NULL, 0); 452 - } 453 - break; 454 - case ACP63_SDW_PDM_DEV_CONFIG: 455 - if (adata->pdev_count == ACP63_SDW0_PDM_MODE_DEVS) { 456 - sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata), 457 - GFP_KERNEL); 458 - if (!sdw_pdata) { 459 - ret = -ENOMEM; 460 - goto de_init; 461 - } 462 - 463 - sdw_pdata->instance = 0; 464 - sdw_pdata->acp_sdw_lock = &adata->acp_lock; 465 - adata->pdm_dev_index = 0; 466 - adata->sdw0_dev_index = 1; 467 - adata->sdw_dma_dev_index = 2; 468 - acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma", 469 - 0, adata->res, 1, NULL, 0); 470 - acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node, 471 - "amd_sdw_manager", 0, adata->res, 1, 472 - sdw_pdata, sizeof(struct acp_sdw_pdata)); 473 - acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "amd_ps_sdw_dma", 474 - 0, adata->res, 1, NULL, 0); 475 - acp63_fill_platform_dev_info(&pdevinfo[3], parent, NULL, "dmic-codec", 476 - 0, NULL, 0, NULL, 0); 477 - } else if (adata->pdev_count == ACP63_SDW0_SDW1_PDM_MODE_DEVS) { 478 - sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata) * 2, 479 - GFP_KERNEL); 480 - if (!sdw_pdata) { 481 - ret = -ENOMEM; 482 - goto de_init; 483 - } 484 - sdw_pdata[0].instance = 0; 485 - sdw_pdata[1].instance = 1; 486 - sdw_pdata[0].acp_sdw_lock = &adata->acp_lock; 487 - sdw_pdata[1].acp_sdw_lock = &adata->acp_lock; 488 - adata->pdm_dev_index = 0; 489 - adata->sdw0_dev_index = 1; 490 - adata->sdw1_dev_index = 2; 491 - adata->sdw_dma_dev_index = 3; 492 - acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma", 493 - 0, adata->res, 1, NULL, 0); 494 - acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node, 495 - "amd_sdw_manager", 0, adata->res, 1, 496 - &sdw_pdata[0], sizeof(struct acp_sdw_pdata)); 497 - acp63_fill_platform_dev_info(&pdevinfo[2], parent, adata->sdw_fw_node, 498 - "amd_sdw_manager", 1, adata->res, 1, 499 - &sdw_pdata[1], sizeof(struct acp_sdw_pdata)); 500 - acp63_fill_platform_dev_info(&pdevinfo[3], parent, NULL, "amd_ps_sdw_dma", 501 - 0, adata->res, 1, NULL, 0); 502 - acp63_fill_platform_dev_info(&pdevinfo[4], parent, NULL, "dmic-codec", 503 - 0, NULL, 0, NULL, 0); 504 - } 505 - break; 506 - default: 507 - dev_dbg(&pci->dev, "No PDM or SoundWire manager devices found\n"); 508 - return 0; 509 - } 510 - 511 - for (index = 0; index < adata->pdev_count; index++) { 512 - adata->pdev[index] = platform_device_register_full(&pdevinfo[index]); 513 - if (IS_ERR(adata->pdev[index])) { 372 + adata->pdm_dev = platform_device_register_full(&pdevinfo); 373 + if (IS_ERR(adata->pdm_dev)) { 514 374 dev_err(&pci->dev, 515 - "cannot register %s device\n", pdevinfo[index].name); 516 - ret = PTR_ERR(adata->pdev[index]); 517 - goto unregister_devs; 375 + "cannot register %s device\n", pdevinfo.name); 376 + ret = PTR_ERR(adata->pdm_dev); 377 + goto de_init; 378 + } 379 + memset(&pdevinfo, 0, sizeof(pdevinfo)); 380 + acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "dmic-codec", 381 + 0, NULL, 0, NULL, 0); 382 + adata->dmic_codec_dev = platform_device_register_full(&pdevinfo); 383 + if (IS_ERR(adata->dmic_codec_dev)) { 384 + dev_err(&pci->dev, 385 + "cannot register %s device\n", pdevinfo.name); 386 + ret = PTR_ERR(adata->dmic_codec_dev); 387 + goto unregister_pdm_dev; 518 388 } 519 389 } 390 + if (adata->is_sdw_dev && adata->is_sdw_config) { 391 + ret = amd_sdw_probe(&pci->dev); 392 + if (ret) { 393 + if (adata->is_pdm_dev) 394 + goto unregister_dmic_codec_dev; 395 + else 396 + goto de_init; 397 + } 398 + memset(&pdevinfo, 0, sizeof(pdevinfo)); 399 + acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "amd_ps_sdw_dma", 400 + 0, adata->res, 1, NULL, 0); 401 + 402 + adata->sdw_dma_dev = platform_device_register_full(&pdevinfo); 403 + if (IS_ERR(adata->sdw_dma_dev)) { 404 + dev_err(&pci->dev, 405 + "cannot register %s device\n", pdevinfo.name); 406 + ret = PTR_ERR(adata->sdw_dma_dev); 407 + if (adata->is_pdm_dev) 408 + goto unregister_dmic_codec_dev; 409 + else 410 + goto de_init; 411 + } 412 + } 413 + 520 414 return 0; 521 - unregister_devs: 522 - for (--index; index >= 0; index--) 523 - platform_device_unregister(adata->pdev[index]); 415 + unregister_dmic_codec_dev: 416 + platform_device_unregister(adata->dmic_codec_dev); 417 + unregister_pdm_dev: 418 + platform_device_unregister(adata->pdm_dev); 524 419 de_init: 525 420 if (acp63_deinit(adata->acp63_base, &pci->dev)) 526 421 dev_err(&pci->dev, "ACP de-init failed\n"); ··· 501 542 ret = -ENOMEM; 502 543 goto release_regions; 503 544 } 545 + adata->addr = addr; 546 + adata->reg_range = ACP63_REG_END - ACP63_REG_START; 504 547 /* 505 548 * By default acp_reset flag is set to true. i.e acp_deinit() and acp_init() 506 549 * will be invoked for all ACP configurations during suspend/resume callbacks. ··· 533 572 dev_err(&pci->dev, "ACP platform devices creation failed\n"); 534 573 goto de_init; 535 574 } 575 + 536 576 skip_pdev_creation: 537 577 device_set_wakeup_enable(&pci->dev, true); 538 578 pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS); ··· 588 626 static void snd_acp63_remove(struct pci_dev *pci) 589 627 { 590 628 struct acp63_dev_data *adata; 591 - int ret, index; 629 + int ret; 592 630 593 631 adata = pci_get_drvdata(pci); 594 - for (index = 0; index < adata->pdev_count; index++) 595 - platform_device_unregister(adata->pdev[index]); 632 + if (adata->sdw) { 633 + amd_sdw_exit(adata); 634 + platform_device_unregister(adata->sdw_dma_dev); 635 + } 636 + if (adata->is_pdm_dev) { 637 + platform_device_unregister(adata->pdm_dev); 638 + platform_device_unregister(adata->dmic_codec_dev); 639 + } 596 640 ret = acp63_deinit(adata->acp63_base, &pci->dev); 597 641 if (ret) 598 642 dev_err(&pci->dev, "ACP de-init failed\n"); ··· 631 663 MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); 632 664 MODULE_AUTHOR("Syed.SabaKareem@amd.com"); 633 665 MODULE_DESCRIPTION("AMD ACP Pink Sardine PCI driver"); 666 + MODULE_IMPORT_NS(SOUNDWIRE_AMD_INIT); 634 667 MODULE_IMPORT_NS(SND_AMD_SOUNDWIRE_ACPI); 635 668 MODULE_LICENSE("GPL v2");