bcwc_pcie: Fix removal of module

the IRQ workqueue was called after channel info was freed, which was
crashing the kernel sometimes. Also fix the isp powerdown sequence,
to stop ISP properly if firmware crashes.
This commit is contained in:
Sven Schnelle
2015-11-14 20:56:21 +01:00
parent 44ae35299e
commit 703c02342c
3 changed files with 25 additions and 10 deletions

View File

@@ -332,12 +332,16 @@ static void bcwc_pci_remove(struct pci_dev *pdev)
struct bcwc_private *dev_priv;
dev_priv = pci_get_drvdata(pdev);
bcwc_isp_cmd_stop(dev_priv);
isp_uninit(dev_priv);
bcwc_hw_deinit(dev_priv);
if (dev_priv) {
isp_mem_destroy(dev_priv->firmware);
bcwc_isp_cmd_stop(dev_priv);
isp_powerdown(dev_priv);
bcwc_irq_disable(dev_priv);
cancel_work_sync(&dev_priv->irq_work);
isp_uninit(dev_priv);
bcwc_hw_deinit(dev_priv);
isp_mem_destroy(dev_priv->firmware);
bcwc_buffer_exit(dev_priv);
pci_disable_msi(pdev);
if (dev_priv->s2_io)

View File

@@ -348,12 +348,15 @@ static void isp_free_set_file(struct bcwc_private *dev_priv)
{
isp_mem_destroy(dev_priv->set_file);
}
int isp_uninit(struct bcwc_private *dev_priv)
int isp_powerdown(struct bcwc_private *dev_priv)
{
int retries;
u32 reg;
BCWC_ISP_REG_WRITE(0xf7fbdff9, 0xc3000);
bcwc_isp_cmd_powerdown(dev_priv);
for (retries = 0; retries < 1000; retries++) {
reg = BCWC_ISP_REG_READ(0xc3000);
if (reg == 0x8042006)
@@ -363,16 +366,23 @@ int isp_uninit(struct bcwc_private *dev_priv)
if (retries >= 1000) {
dev_info(&dev_priv->pdev->dev, "deinit failed!\n");
return -EIO;
}
return 0;
}
int isp_uninit(struct bcwc_private *dev_priv)
{
BCWC_ISP_REG_WRITE(0x00000000, 0x40004);
BCWC_ISP_REG_WRITE(0x00000000, 0x41004);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc0008);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc000c);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc0010);
BCWC_ISP_REG_WRITE(0, 0xc0c04);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc0c0c);
BCWC_ISP_REG_WRITE(0, 0xc0c14);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc0c1c);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc0c24);
BCWC_ISP_REG_WRITE(0x00000000, 0xc1004);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc100c);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc1014);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc101c);
BCWC_ISP_REG_WRITE(0xffffffff, 0xc1024);
mdelay(1);
BCWC_ISP_REG_WRITE(0, 0xc0000);

View File

@@ -572,6 +572,7 @@ extern struct isp_mem_obj *isp_mem_create(struct bcwc_private *dev_priv,
extern int isp_mem_destroy(struct isp_mem_obj *obj);
extern int bcwc_isp_cmd_start(struct bcwc_private *dev_priv);
extern int bcwc_isp_cmd_stop(struct bcwc_private *dev_priv);
extern int isp_powerdown(struct bcwc_private *dev_priv);
extern int bcwc_isp_cmd_print_enable(struct bcwc_private *dev_priv, int enable);
extern int bcwc_isp_cmd_set_loadfile(struct bcwc_private *dev_priv);
extern int bcwc_isp_cmd_channel_info(struct bcwc_private *dev_priv);