Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00d67f54 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Greg Kroah-Hartman
Browse files

spi: pxa2xx-pci: Balance reference count for PCI DMA device



[ Upstream commit 609d7ffdc42199a0ec949db057e3b4be6745d6c5 ]

The pci_get_slot() increases its reference count, the caller
must decrement the reference count by calling pci_dev_put().

Fixes: 743485ea ("spi: pxa2xx-pci: Do a specific setup in a separate function")
Fixes: 25014521 ("spi: pxa2xx-pci: Enable DMA for Intel Merrifield")
Reported-by: default avatarWang Qing <wangqing@vivo.com>
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20220223191637.31147-1-andriy.shevchenko@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 40e6d5d1
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -74,14 +74,23 @@ static bool lpss_dma_filter(struct dma_chan *chan, void *param)
	return true;
}

static void lpss_dma_put_device(void *dma_dev)
{
	pci_dev_put(dma_dev);
}

static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
{
	struct pci_dev *dma_dev;
	int ret;

	c->num_chipselect = 1;
	c->max_clk_rate = 50000000;

	dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
	ret = devm_add_action_or_reset(&dev->dev, lpss_dma_put_device, dma_dev);
	if (ret)
		return ret;

	if (c->tx_param) {
		struct dw_dma_slave *slave = c->tx_param;
@@ -105,8 +114,9 @@ static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)

static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
{
	struct pci_dev *dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(21, 0));
	struct dw_dma_slave *tx, *rx;
	struct pci_dev *dma_dev;
	int ret;

	switch (PCI_FUNC(dev->devfn)) {
	case 0:
@@ -131,6 +141,11 @@ static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
		return -ENODEV;
	}

	dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(21, 0));
	ret = devm_add_action_or_reset(&dev->dev, lpss_dma_put_device, dma_dev);
	if (ret)
		return ret;

	tx = c->tx_param;
	tx->dma_dev = &dma_dev->dev;