diff --git a/bcwc_drv.c b/bcwc_drv.c index e10c5bf..8a8ee8e 100644 --- a/bcwc_drv.c +++ b/bcwc_drv.c @@ -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) diff --git a/bcwc_isp.c b/bcwc_isp.c index c0a6bc4..9ac71fd 100644 --- a/bcwc_isp.c +++ b/bcwc_isp.c @@ -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); diff --git a/bcwc_isp.h b/bcwc_isp.h index 58e3335..8408bf2 100644 --- a/bcwc_isp.h +++ b/bcwc_isp.h @@ -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);