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.

dmaengine: ti: k3-udma: Add system suspend/resume support

The K3 platforms configure the DMA resources with the
help of the TI's System Firmware's Device Manager(DM)
over TISCI. The group of DMA related Resource Manager[1]
TISCI messages includes: INTA, RINGACC, UDMAP, and PSI-L.
This configuration however, does not persist in the DM
after leaving from Suspend-to-RAM state. We have to restore
the DMA channel configuration over TISCI for all configured
channels when returning from suspend.

The TISCI resource management calls for each DMA type (UDMA,
PKTDMA, BCDMA) happen in device_free_chan_resources() and
device_alloc_chan_resources(). In pm_suspend() we store
the current udma_chan_config for channels that still have
attached clients and call device_free_chan_resources().
In pm_resume() restore the udma_channel_config from backup
and call device_alloc_chan_resources() for those channels.

Drivers like CPSW that use k3-udma-glue already do their own
DMA resource management so use the late system suspend/resume hooks.

[1] https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/index.html#resource-management-rm

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
[g-vlaev@ti.com: Add patch description and config backup]
[g-vlaev@ti.com: Supend only channels with clients]
Signed-off-by: Georgi Vlaev <g-vlaev@ti.com>
Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
Link: https://lore.kernel.org/r/20230329155349.2566010-1-vigneshr@ti.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Vignesh Raghavendra and committed by
Vinod Koul
fbe05149 7511f287

+54
+54
drivers/dma/ti/k3-udma.c
··· 305 305 306 306 /* Channel configuration parameters */ 307 307 struct udma_chan_config config; 308 + /* Channel configuration parameters (backup) */ 309 + struct udma_chan_config backup_config; 308 310 309 311 /* dmapool for packet mode descriptors */ 310 312 bool use_dma_pool; ··· 5524 5522 return ret; 5525 5523 } 5526 5524 5525 + static int udma_pm_suspend(struct device *dev) 5526 + { 5527 + struct udma_dev *ud = dev_get_drvdata(dev); 5528 + struct dma_device *dma_dev = &ud->ddev; 5529 + struct dma_chan *chan; 5530 + struct udma_chan *uc; 5531 + 5532 + list_for_each_entry(chan, &dma_dev->channels, device_node) { 5533 + if (chan->client_count) { 5534 + uc = to_udma_chan(chan); 5535 + /* backup the channel configuration */ 5536 + memcpy(&uc->backup_config, &uc->config, 5537 + sizeof(struct udma_chan_config)); 5538 + dev_dbg(dev, "Suspending channel %s\n", 5539 + dma_chan_name(chan)); 5540 + ud->ddev.device_free_chan_resources(chan); 5541 + } 5542 + } 5543 + 5544 + return 0; 5545 + } 5546 + 5547 + static int udma_pm_resume(struct device *dev) 5548 + { 5549 + struct udma_dev *ud = dev_get_drvdata(dev); 5550 + struct dma_device *dma_dev = &ud->ddev; 5551 + struct dma_chan *chan; 5552 + struct udma_chan *uc; 5553 + int ret; 5554 + 5555 + list_for_each_entry(chan, &dma_dev->channels, device_node) { 5556 + if (chan->client_count) { 5557 + uc = to_udma_chan(chan); 5558 + /* restore the channel configuration */ 5559 + memcpy(&uc->config, &uc->backup_config, 5560 + sizeof(struct udma_chan_config)); 5561 + dev_dbg(dev, "Resuming channel %s\n", 5562 + dma_chan_name(chan)); 5563 + ret = ud->ddev.device_alloc_chan_resources(chan); 5564 + if (ret) 5565 + return ret; 5566 + } 5567 + } 5568 + 5569 + return 0; 5570 + } 5571 + 5572 + static const struct dev_pm_ops udma_pm_ops = { 5573 + SET_LATE_SYSTEM_SLEEP_PM_OPS(udma_pm_suspend, udma_pm_resume) 5574 + }; 5575 + 5527 5576 static struct platform_driver udma_driver = { 5528 5577 .driver = { 5529 5578 .name = "ti-udma", 5530 5579 .of_match_table = udma_of_match, 5531 5580 .suppress_bind_attrs = true, 5581 + .pm = &udma_pm_ops, 5532 5582 }, 5533 5583 .probe = udma_probe, 5534 5584 };