Commit 25bccb98 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

media: atomisp: free PCI resources when probing fail

The atomisp probe error logic is incomplete. Add the missing
bits to return the PCI device to its original state.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 33c24f8f
...@@ -1576,7 +1576,7 @@ static int atomisp_pci_probe(struct pci_dev *dev, ...@@ -1576,7 +1576,7 @@ static int atomisp_pci_probe(struct pci_dev *dev,
if (!pdata) if (!pdata)
dev_warn(&dev->dev, "no platform data available\n"); dev_warn(&dev->dev, "no platform data available\n");
err = pcim_enable_device(dev); err = pci_enable_device(dev);
if (err) { if (err) {
dev_err(&dev->dev, "Failed to enable CI ISP device (%d)\n", dev_err(&dev->dev, "Failed to enable CI ISP device (%d)\n",
err); err);
...@@ -1590,7 +1590,7 @@ static int atomisp_pci_probe(struct pci_dev *dev, ...@@ -1590,7 +1590,7 @@ static int atomisp_pci_probe(struct pci_dev *dev,
if (err) { if (err) {
dev_err(&dev->dev, "Failed to I/O memory remapping (%d)\n", dev_err(&dev->dev, "Failed to I/O memory remapping (%d)\n",
err); err);
return err; goto ioremap_fail;
} }
base = pcim_iomap_table(dev)[ATOM_ISP_PCI_BAR]; base = pcim_iomap_table(dev)[ATOM_ISP_PCI_BAR];
...@@ -1602,8 +1602,8 @@ static int atomisp_pci_probe(struct pci_dev *dev, ...@@ -1602,8 +1602,8 @@ static int atomisp_pci_probe(struct pci_dev *dev,
isp = devm_kzalloc(&dev->dev, sizeof(struct atomisp_device), GFP_KERNEL); isp = devm_kzalloc(&dev->dev, sizeof(struct atomisp_device), GFP_KERNEL);
if (!isp) { if (!isp) {
dev_err(&dev->dev, "Failed to alloc CI ISP structure\n"); err = -ENOMEM;
return -ENOMEM; goto atomisp_dev_alloc_fail;
} }
isp->pdev = dev; isp->pdev = dev;
isp->dev = &dev->dev; isp->dev = &dev->dev;
...@@ -1722,7 +1722,8 @@ static int atomisp_pci_probe(struct pci_dev *dev, ...@@ -1722,7 +1722,8 @@ static int atomisp_pci_probe(struct pci_dev *dev,
break; break;
default: default:
dev_err(&dev->dev, "un-supported IUNIT device\n"); dev_err(&dev->dev, "un-supported IUNIT device\n");
return -ENODEV; err = -ENODEV;
goto atomisp_dev_alloc_fail;
} }
dev_info(&dev->dev, "ISP HPLL frequency base = %d MHz\n", dev_info(&dev->dev, "ISP HPLL frequency base = %d MHz\n",
...@@ -1735,6 +1736,7 @@ static int atomisp_pci_probe(struct pci_dev *dev, ...@@ -1735,6 +1736,7 @@ static int atomisp_pci_probe(struct pci_dev *dev,
isp->firmware = atomisp_load_firmware(isp); isp->firmware = atomisp_load_firmware(isp);
if (!isp->firmware) { if (!isp->firmware) {
err = -ENOENT; err = -ENOENT;
dev_dbg(&dev->dev, "Firmware load failed\n");
goto load_fw_fail; goto load_fw_fail;
} }
...@@ -1743,6 +1745,8 @@ static int atomisp_pci_probe(struct pci_dev *dev, ...@@ -1743,6 +1745,8 @@ static int atomisp_pci_probe(struct pci_dev *dev,
dev_dbg(&dev->dev, "Firmware version check failed\n"); dev_dbg(&dev->dev, "Firmware version check failed\n");
goto fw_validation_fail; goto fw_validation_fail;
} }
} else {
dev_info(&dev->dev, "Firmware load will be deferred\n");
} }
pci_set_master(dev); pci_set_master(dev);
...@@ -1870,7 +1874,9 @@ static int atomisp_pci_probe(struct pci_dev *dev, ...@@ -1870,7 +1874,9 @@ static int atomisp_pci_probe(struct pci_dev *dev,
initialize_modules_fail: initialize_modules_fail:
cpu_latency_qos_remove_request(&isp->pm_qos); cpu_latency_qos_remove_request(&isp->pm_qos);
atomisp_msi_irq_uninit(isp, dev); atomisp_msi_irq_uninit(isp, dev);
pci_disable_msi(dev);
enable_msi_fail: enable_msi_fail:
pci_disable_device(dev);
fw_validation_fail: fw_validation_fail:
release_firmware(isp->firmware); release_firmware(isp->firmware);
load_fw_fail: load_fw_fail:
...@@ -1896,6 +1902,11 @@ static int atomisp_pci_probe(struct pci_dev *dev, ...@@ -1896,6 +1902,11 @@ static int atomisp_pci_probe(struct pci_dev *dev,
/* Address later when we worry about the ...field chips */ /* Address later when we worry about the ...field chips */
if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power_down(isp)) if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power_down(isp))
dev_err(&dev->dev, "Failed to switch off ISP\n"); dev_err(&dev->dev, "Failed to switch off ISP\n");
atomisp_dev_alloc_fail:
pcim_iounmap_regions(dev, 1 << ATOM_ISP_PCI_BAR);
ioremap_fail:
return err; return err;
} }
...@@ -1904,6 +1915,8 @@ static void atomisp_pci_remove(struct pci_dev *dev) ...@@ -1904,6 +1915,8 @@ static void atomisp_pci_remove(struct pci_dev *dev)
struct atomisp_device *isp = (struct atomisp_device *) struct atomisp_device *isp = (struct atomisp_device *)
pci_get_drvdata(dev); pci_get_drvdata(dev);
dev_info(&dev->dev, "Removing atomisp driver\n");
atomisp_drvfs_exit(); atomisp_drvfs_exit();
atomisp_acc_cleanup(isp); atomisp_acc_cleanup(isp);
...@@ -1924,6 +1937,8 @@ static void atomisp_pci_remove(struct pci_dev *dev) ...@@ -1924,6 +1937,8 @@ static void atomisp_pci_remove(struct pci_dev *dev)
release_firmware(isp->firmware); release_firmware(isp->firmware);
hmm_pool_unregister(HMM_POOL_TYPE_RESERVED); hmm_pool_unregister(HMM_POOL_TYPE_RESERVED);
pci_disable_device(dev);
} }
static const struct pci_device_id atomisp_pci_tbl[] = { static const struct pci_device_id atomisp_pci_tbl[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment