mirror of
https://github.com/patjak/facetimehd.git
synced 2026-04-09 19:10:01 +02:00
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:
12
bcwc_drv.c
12
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)
|
||||
|
||||
22
bcwc_isp.c
22
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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user