[bug report] drm/amdgpu: create I2S platform devices for Jadeite platform
Dan Carpenter
dan.carpenter at oracle.com
Tue Jul 26 15:17:22 UTC 2022
Hello Vijendar Mukunda,
The patch 4c33e5179ff1: "drm/amdgpu: create I2S platform devices for
Jadeite platform" from Jun 30, 2022, leads to the following Smatch
static checker warning:
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:393 acp_hw_init()
error: buffer overflow 'i2s_pdata' 3 <= 3
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:396 acp_hw_init()
error: buffer overflow 'i2s_pdata' 3 <= 3
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
225 static int acp_hw_init(void *handle)
226 {
227 int r;
228 u64 acp_base;
229 u32 val = 0;
230 u32 count = 0;
231 struct i2s_platform_data *i2s_pdata = NULL;
232
233 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
234
235 const struct amdgpu_ip_block *ip_block =
236 amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_ACP);
237
238 if (!ip_block)
239 return -EINVAL;
240
241 r = amd_acp_hw_init(adev->acp.cgs_device,
242 ip_block->version->major, ip_block->version->minor);
243 /* -ENODEV means board uses AZ rather than ACP */
244 if (r == -ENODEV) {
245 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
246 return 0;
247 } else if (r) {
248 return r;
249 }
250
251 if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289)
252 return -EINVAL;
253
254 acp_base = adev->rmmio_base;
255 adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);
256 if (!adev->acp.acp_genpd)
257 return -ENOMEM;
258
259 adev->acp.acp_genpd->gpd.name = "ACP_AUDIO";
260 adev->acp.acp_genpd->gpd.power_off = acp_poweroff;
261 adev->acp.acp_genpd->gpd.power_on = acp_poweron;
262 adev->acp.acp_genpd->adev = adev;
263
264 pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false);
265 dmi_check_system(acp_quirk_table);
266 switch (acp_machine_id) {
267 case ST_JADEITE:
268 {
269 adev->acp.acp_cell = kcalloc(2, sizeof(struct mfd_cell),
270 GFP_KERNEL);
271 if (!adev->acp.acp_cell) {
272 r = -ENOMEM;
273 goto failure;
274 }
275
276 adev->acp.acp_res = kcalloc(3, sizeof(struct resource), GFP_KERNEL);
277 if (!adev->acp.acp_res) {
278 r = -ENOMEM;
279 goto failure;
280 }
281
282 i2s_pdata = kcalloc(1, sizeof(struct i2s_platform_data), GFP_KERNEL);
283 if (!i2s_pdata) {
284 r = -ENOMEM;
285 goto failure;
286 }
287
288 i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
289 DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
290 i2s_pdata[0].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;
291 i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
292 i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
293 i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;
294
295 adev->acp.acp_res[0].name = "acp2x_dma";
296 adev->acp.acp_res[0].flags = IORESOURCE_MEM;
297 adev->acp.acp_res[0].start = acp_base;
298 adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;
299
300 adev->acp.acp_res[1].name = "acp2x_dw_i2s_play_cap";
301 adev->acp.acp_res[1].flags = IORESOURCE_MEM;
302 adev->acp.acp_res[1].start = acp_base + ACP_I2S_CAP_REGS_START;
303 adev->acp.acp_res[1].end = acp_base + ACP_I2S_CAP_REGS_END;
304
305 adev->acp.acp_res[2].name = "acp2x_dma_irq";
306 adev->acp.acp_res[2].flags = IORESOURCE_IRQ;
307 adev->acp.acp_res[2].start = amdgpu_irq_create_mapping(adev, 162);
308 adev->acp.acp_res[2].end = adev->acp.acp_res[2].start;
309
310 adev->acp.acp_cell[0].name = "acp_audio_dma";
311 adev->acp.acp_cell[0].num_resources = 3;
312 adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
313 adev->acp.acp_cell[0].platform_data = &adev->asic_type;
314 adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
315
316 adev->acp.acp_cell[1].name = "designware-i2s";
317 adev->acp.acp_cell[1].num_resources = 1;
318 adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];
319 adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];
320 adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);
321 r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, 2);
322 if (r)
323 goto failure;
324 r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
325 acp_genpd_add_device);
326 if (r)
327 goto failure;
328 break;
329 }
330 default:
331 adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
332 GFP_KERNEL);
333
334 if (!adev->acp.acp_cell) {
335 r = -ENOMEM;
336 goto failure;
337 }
338
339 adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
340 if (!adev->acp.acp_res) {
341 r = -ENOMEM;
342 goto failure;
343 }
344
345 i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
^
3 elements
346 if (!i2s_pdata) {
347 r = -ENOMEM;
348 goto failure;
349 }
350
351 switch (adev->asic_type) {
352 case CHIP_STONEY:
353 i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
354 DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
355 break;
356 default:
357 i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
358 }
359 i2s_pdata[0].cap = DWC_I2S_PLAY;
360 i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
361 i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET;
362 i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET;
363 switch (adev->asic_type) {
364 case CHIP_STONEY:
365 i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
366 DW_I2S_QUIRK_COMP_PARAM1 |
367 DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
368 break;
369 default:
370 i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
371 DW_I2S_QUIRK_COMP_PARAM1;
372 }
373
374 i2s_pdata[1].cap = DWC_I2S_RECORD;
375 i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000;
376 i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
377 i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;
378
379 i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
380 switch (adev->asic_type) {
381 case CHIP_STONEY:
382 i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
383 break;
384 default:
385 break;
386 }
387
388 i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;
389 i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000;
390 i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;
391 i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;
392
--> 393 i2s_pdata[3].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
^^^^^^^^^^^^
394 switch (adev->asic_type) {
395 case CHIP_STONEY:
396 i2s_pdata[3].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
^^^^^^^^^^^^
Out of boundses.
397 break;
398 default:
399 break;
400 }
401 adev->acp.acp_res[0].name = "acp2x_dma";
402 adev->acp.acp_res[0].flags = IORESOURCE_MEM;
403 adev->acp.acp_res[0].start = acp_base;
404 adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;
405
406 adev->acp.acp_res[1].name = "acp2x_dw_i2s_play";
407 adev->acp.acp_res[1].flags = IORESOURCE_MEM;
408 adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START;
409 adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END;
410
411 adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap";
412 adev->acp.acp_res[2].flags = IORESOURCE_MEM;
413 adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START;
414 adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END;
415
416 adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap";
417 adev->acp.acp_res[3].flags = IORESOURCE_MEM;
418 adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START;
419 adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END;
420
421 adev->acp.acp_res[4].name = "acp2x_dma_irq";
422 adev->acp.acp_res[4].flags = IORESOURCE_IRQ;
423 adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162);
424 adev->acp.acp_res[4].end = adev->acp.acp_res[4].start;
425
426 adev->acp.acp_cell[0].name = "acp_audio_dma";
427 adev->acp.acp_cell[0].num_resources = 5;
428 adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
429 adev->acp.acp_cell[0].platform_data = &adev->asic_type;
430 adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
431
432 adev->acp.acp_cell[1].name = "designware-i2s";
433 adev->acp.acp_cell[1].num_resources = 1;
434 adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];
435 adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];
436 adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);
437
438 adev->acp.acp_cell[2].name = "designware-i2s";
439 adev->acp.acp_cell[2].num_resources = 1;
440 adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2];
441 adev->acp.acp_cell[2].platform_data = &i2s_pdata[1];
442 adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data);
443
444 adev->acp.acp_cell[3].name = "designware-i2s";
445 adev->acp.acp_cell[3].num_resources = 1;
446 adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3];
447 adev->acp.acp_cell[3].platform_data = &i2s_pdata[2];
448 adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data);
449
450 r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, ACP_DEVS);
451 if (r)
452 goto failure;
453
454 r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
455 acp_genpd_add_device);
456 if (r)
457 goto failure;
458 }
459
460 /* Assert Soft reset of ACP */
461 val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
462
463 val |= ACP_SOFT_RESET__SoftResetAud_MASK;
464 cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
465
466 count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;
467 while (true) {
468 val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
469 if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==
470 (val & ACP_SOFT_RESET__SoftResetAudDone_MASK))
471 break;
472 if (--count == 0) {
473 dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
474 r = -ETIMEDOUT;
475 goto failure;
476 }
477 udelay(100);
478 }
479 /* Enable clock to ACP and wait until the clock is enabled */
480 val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL);
481 val = val | ACP_CONTROL__ClkEn_MASK;
482 cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val);
483
484 count = ACP_CLOCK_EN_TIME_OUT_VALUE;
485
486 while (true) {
487 val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS);
488 if (val & (u32) 0x1)
489 break;
490 if (--count == 0) {
491 dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
492 r = -ETIMEDOUT;
493 goto failure;
494 }
495 udelay(100);
496 }
497 /* Deassert the SOFT RESET flags */
498 val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
499 val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
500 cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
501 return 0;
502
503 failure:
504 kfree(i2s_pdata);
505 kfree(adev->acp.acp_res);
506 kfree(adev->acp.acp_cell);
507 kfree(adev->acp.acp_genpd);
508 return r;
509 }
regards,
dan carpenter
More information about the amd-gfx
mailing list