From 07686d56a1894f00e47279270e974a2543fd366a Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Thu, 29 Oct 2015 23:13:29 +0100 Subject: [PATCH] bcwc_pcie: power down hardware --- bcwc_drv.c | 1 + bcwc_isp.c | 38 ++++++++++++++++++++++++++++++++++++++ bcwc_isp.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/bcwc_drv.c b/bcwc_drv.c index c048661..2ea4548 100644 --- a/bcwc_drv.c +++ b/bcwc_drv.c @@ -309,6 +309,7 @@ static void bcwc_pci_remove(struct pci_dev *pdev) 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); diff --git a/bcwc_isp.c b/bcwc_isp.c index 0a12c8f..3aa8b2b 100644 --- a/bcwc_isp.c +++ b/bcwc_isp.c @@ -258,8 +258,46 @@ out: return -ENOMEM; } +static void bcwc_isp_powerdown(struct bcwc_private *dev_priv) +{ + struct isp_mem_obj *request; + struct isp_cmd_hdr *cmd; + + dev_info(&dev_priv->pdev->dev, "%s\n", __FUNCTION__); + + request = isp_mem_create(dev_priv, FTHD_MEM_CMD, sizeof(cmd)); + if (!request) { + dev_err(&dev_priv->pdev->dev, "failed to allocate cmd memory object\n"); + return; + } + + dev_info(&dev_priv->pdev->dev, "allocated request cmd buffer at offset %08lx\n", request->offset); + cmd = dev_priv->s2_mem + request->offset; + memset(cmd, 0, sizeof(*cmd)); + cmd->opcode = CISP_CMD_POWER_DOWN; + + bcwc_channel_ringbuf_send(dev_priv, dev_priv->channel_io, request->offset, 8, 8); + mdelay(100); + bcwc_channel_ringbuf_dump(dev_priv, dev_priv->channel_io); +} + int isp_uninit(struct bcwc_private *dev_priv) { + int retries; + u32 reg; + BCWC_ISP_REG_WRITE(0xf7fbdff9, 0xc3000); + bcwc_isp_powerdown(dev_priv); + for (retries = 0; retries < 1000; retries++) { + reg = BCWC_ISP_REG_READ(0xc3000); + if (reg == 0x8042006) + break; + mdelay(10); + } + + if (retries >= 1000) { + dev_info(&dev_priv->pdev->dev, "Deinit failed!\n"); + } + BCWC_ISP_REG_WRITE(0xffffffff, 0xc0008); BCWC_ISP_REG_WRITE(0xffffffff, 0xc000c); BCWC_ISP_REG_WRITE(0xffffffff, 0xc0010); diff --git a/bcwc_isp.h b/bcwc_isp.h index 5372f68..6d1fac7 100644 --- a/bcwc_isp.h +++ b/bcwc_isp.h @@ -35,6 +35,7 @@ enum bcwc_isp_cmds { CISP_CMD_START=0, CISP_CMD_STOP=1, CISP_CMD_PRINT_ENABLE=4, + CISP_CMD_POWER_DOWN=10, }; struct isp_mem_obj { @@ -72,6 +73,7 @@ struct isp_cmd_print_enable { #define to_isp_mem_obj(x) container_of((x), struct isp_mem_obj, base) extern int isp_init(struct bcwc_private *dev_priv); +extern int isp_uninit(struct bcwc_private *dev_priv); extern int isp_mem_init(struct bcwc_private *dev_priv); extern struct isp_mem_obj *isp_mem_create(struct bcwc_private *dev_priv,