From: Hongzhang Yang Date: Fri, 16 Aug 2013 02:33:41 +0000 (+0800) Subject: ENGR00275473-2 Support PU regulator on/off in VPU driver X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=156f63c769e7beac75f9580b81aab6f46131a45d;p=karo-tx-linux.git ENGR00275473-2 Support PU regulator on/off in VPU driver Add functions to hide different implemention for different kernel - vpu_power_get: get/put power/regulator - vpu_power_up: enable/disable power/regulator - vpu_reset Implement regulator operations for Linux 3.10 - find regulator from VPU device node property pu-supply Replace printk/pr_xxx with dev_xxx Signed-off-by: Hongzhang Yang --- diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c index 9baeeb4e3a51..ecd286b8b825 100644 --- a/drivers/mxc/vpu/mxc_vpu.c +++ b/drivers/mxc/vpu/mxc_vpu.c @@ -122,9 +122,7 @@ static phys_addr_t top_address_DRAM; static struct mxc_vpu_platform_data *vpu_plat; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) -static struct platform_device *vpu_pdev; -#endif +static struct device *vpu_dev; /* IRAM setting */ static struct iram_setting iram; @@ -143,7 +141,7 @@ static int vpu_jpu_irq; #endif static unsigned int regBk[64]; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) static struct regulator *vpu_regulator; #endif static unsigned int pc_before_suspend; @@ -169,16 +167,63 @@ static int cpu_is_mx6q(void) } #endif +static void vpu_reset(void) +{ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) -static void imx_src_reset_vpu(void) + device_reset(vpu_dev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) + imx_src_reset_vpu(); +#else + if (vpu_plat->reset) + vpu_plat->reset(); +#endif +} + +static long vpu_power_get(bool on) { - device_reset(&vpu_pdev->dev); + long ret = 0; + + if (on) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) + vpu_regulator = regulator_get(NULL, "cpu_vddvpu"); + ret = IS_ERR(vpu_regulator); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) + vpu_regulator = devm_regulator_get(vpu_dev, "pu"); + ret = IS_ERR(vpu_regulator); +#endif + } else { +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) + if (!IS_ERR(vpu_regulator)) + regulator_put(vpu_regulator); +#endif + } + return ret; } -static void imx_gpc_power_up_pu(int on) +static void vpu_power_up(bool on) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) + int ret = 0; + + if (on) { + if (!IS_ERR(vpu_regulator)) { + ret = regulator_enable(vpu_regulator); + if (ret) + dev_err(vpu_dev, "failed to power up vpu\n"); + } + } else { + if (!IS_ERR(vpu_regulator)) { + ret = regulator_disable(vpu_regulator); + if (ret) + dev_err(vpu_dev, "failed to power down vpu\n"); + } + } +#else + imx_gpc_power_up_pu(on); +#endif } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) static void request_bus_freq(int freq) { } @@ -212,9 +257,9 @@ static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem) dma_alloc_coherent(NULL, PAGE_ALIGN(mem->size), (dma_addr_t *) (&mem->phy_addr), GFP_DMA | GFP_KERNEL); - pr_debug("[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr); + dev_dbg(vpu_dev, "[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr); if ((void *)(mem->cpu_addr) == NULL) { - printk(KERN_ERR "Physical memory allocation error!\n"); + dev_err(vpu_dev, "Physical memory allocation error!\n"); return -1; } return 0; @@ -244,7 +289,7 @@ static int vpu_free_buffers(void) mem = rec->mem; if (mem.cpu_addr != 0) { vpu_free_dma_buffer(&mem); - pr_debug("[FREE] freed paddr=0x%08X\n", mem.phy_addr); + dev_dbg(vpu_dev, "[FREE] freed paddr=0x%08X\n", mem.phy_addr); /* delete from list */ list_del(&rec->list); kfree(rec); @@ -338,19 +383,17 @@ static int vpu_open(struct inode *inode, struct file *filp) mutex_lock(&vpu_data.lock); if (open_count++ == 0) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) - if (!IS_ERR(vpu_regulator)) - regulator_enable(vpu_regulator); -#else - pm_runtime_get_sync(&vpu_pdev->dev); - imx_gpc_power_up_pu(true); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) + pm_runtime_get_sync(vpu_dev); #endif + vpu_power_up(true); #ifdef CONFIG_SOC_IMX6Q clk_prepare(vpu_clk); clk_enable(vpu_clk); if (READ_REG(BIT_CUR_PC)) - pr_debug("Not power off before vpu open!\n"); + dev_dbg(vpu_dev, "Not power off before vpu open!\n"); clk_disable(vpu_clk); clk_unprepare(vpu_clk); #endif @@ -388,14 +431,14 @@ static long vpu_ioctl(struct file *filp, u_int cmd, return -EFAULT; } - pr_debug("[ALLOC] mem alloc size = 0x%x\n", + dev_dbg(vpu_dev, "[ALLOC] mem alloc size = 0x%x\n", rec->mem.size); ret = vpu_alloc_dma_buffer(&(rec->mem)); if (ret == -1) { kfree(rec); - printk(KERN_ERR - "Physical memory allocation error!\n"); + dev_err(vpu_dev, + "Physical memory allocation error!\n"); break; } ret = copy_to_user((void __user *)arg, &(rec->mem), @@ -423,7 +466,7 @@ static long vpu_ioctl(struct file *filp, u_int cmd, if (ret) return -EACCES; - pr_debug("[FREE] mem freed cpu_addr = 0x%x\n", + dev_dbg(vpu_dev, "[FREE] mem freed cpu_addr = 0x%x\n", vpu_mem.cpu_addr); if ((void *)vpu_mem.cpu_addr != NULL) vpu_free_dma_buffer(&vpu_mem); @@ -447,11 +490,10 @@ static long vpu_ioctl(struct file *filp, u_int cmd, if (!wait_event_interruptible_timeout (vpu_queue, irq_status != 0, msecs_to_jiffies(timeout))) { - printk(KERN_WARNING "VPU blocking: timeout.\n"); + dev_warn(vpu_dev, "VPU blocking: timeout.\n"); ret = -ETIME; } else if (signal_pending(current)) { - printk(KERN_WARNING - "VPU interrupt received.\n"); + dev_warn(vpu_dev, "VPU interrupt received.\n"); ret = -ERESTARTSYS; } else irq_status = 0; @@ -590,13 +632,7 @@ static long vpu_ioctl(struct file *filp, u_int cmd, } case VPU_IOC_SYS_SW_RESET: { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) - imx_src_reset_vpu(); -#else - if (vpu_plat->reset) - vpu_plat->reset(); -#endif - + vpu_reset(); break; } case VPU_IOC_REG_DUMP: @@ -610,13 +646,13 @@ static long vpu_ioctl(struct file *filp, u_int cmd, (void __user *)arg, sizeof(struct vpu_mem_desc)); if (ret != 0) { - printk(KERN_ERR "copy from user failure:%d\n", ret); + dev_err(vpu_dev, "copy from user failure:%d\n", ret); ret = -EFAULT; break; } ret = vpu_is_valid_phy_memory((u32)check_memory.phy_addr); - pr_debug("vpu: memory phy:0x%x %s phy memory\n", + dev_dbg(vpu_dev, "vpu: memory phy:0x%x %s phy memory\n", check_memory.phy_addr, (ret ? "is" : "isn't")); /* borrow .size to pass back the result. */ check_memory.size = ret; @@ -644,7 +680,7 @@ static long vpu_ioctl(struct file *filp, u_int cmd, } default: { - printk(KERN_ERR "No such IOCTL, cmd is %d\n", cmd); + dev_err(vpu_dev, "No such IOCTL, cmd is %d\n", cmd); ret = -EINVAL; break; } @@ -674,7 +710,7 @@ static int vpu_release(struct inode *inode, struct file *filp) while (READ_REG(BIT_BUSY_FLAG)) { msleep(1); if (time_after(jiffies, timeout)) { - printk(KERN_WARNING "VPU timeout during release\n"); + dev_warn(vpu_dev, "VPU timeout during release\n"); break; } } @@ -691,7 +727,7 @@ static int vpu_release(struct inode *inode, struct file *filp) if (READ_REG(BIT_BUSY_FLAG)) { if (cpu_is_mx51() || cpu_is_mx53()) { - printk(KERN_ERR + dev_err(vpu_dev, "fatal error: can't gate/power off when VPU is busy\n"); clk_disable(vpu_clk); clk_unprepare(vpu_clk); @@ -710,21 +746,15 @@ static int vpu_release(struct inode *inode, struct file *filp) } if (READ_REG(0x10F4) != 0x77) { - printk(KERN_ERR + dev_err(vpu_dev, "fatal error: can't gate/power off when VPU is busy\n"); WRITE_REG(0x0, 0x10F0); clk_disable(vpu_clk); clk_unprepare(vpu_clk); mutex_unlock(&vpu_data.lock); return -EFAULT; - } else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) - imx_src_reset_vpu(); -#else - if (vpu_plat->reset) - vpu_plat->reset(); -#endif - } + } else + vpu_reset(); } #endif } @@ -747,12 +777,9 @@ static int vpu_release(struct inode *inode, struct file *filp) atomic_dec(&clk_cnt_from_ioc); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) - if (!IS_ERR(vpu_regulator)) - regulator_disable(vpu_regulator); -#else - imx_gpc_power_up_pu(false); - pm_runtime_put_sync_suspend(&vpu_pdev->dev); + vpu_power_up(false); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) + pm_runtime_put_sync_suspend(vpu_dev); #endif } @@ -788,7 +815,7 @@ static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm) */ vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot); pfn = phy_vpu_base_addr >> PAGE_SHIFT; - pr_debug("size=0x%x, page no.=0x%x\n", + dev_dbg(vpu_dev, "size=0x%x, page no.=0x%x\n", (int)(vm->vm_end - vm->vm_start), (int)pfn); return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end - vm->vm_start, vm->vm_page_prot) ? -EAGAIN : 0; @@ -803,7 +830,7 @@ static int vpu_map_dma_mem(struct file *fp, struct vm_area_struct *vm) int request_size; request_size = vm->vm_end - vm->vm_start; - pr_debug(" start=0x%x, pgoff=0x%x, size=0x%x\n", + dev_dbg(vpu_dev, "start=0x%x, pgoff=0x%x, size=0x%x\n", (unsigned int)(vm->vm_start), (unsigned int)(vm->vm_pgoff), request_size); @@ -877,13 +904,13 @@ static int vpu_dev_probe(struct platform_device *pdev) { iram_pool = of_get_named_gen_pool(np, "iram", 0); if (!iram_pool) { - printk(KERN_ERR "iram pool not available\n"); + dev_err(&pdev->dev, "iram pool not available\n"); return -ENOMEM; } iram_base = gen_pool_alloc(iram_pool, iramsize); if (!iram_base) { - printk(KERN_ERR "unable to alloc iram\n"); + dev_err(&pdev->dev, "unable to alloc iram\n"); return -ENOMEM; } @@ -898,8 +925,6 @@ static int vpu_dev_probe(struct platform_device *pdev) iram.start = addr; iram.end = addr + iramsize - 1; } - - vpu_pdev = pdev; #else vpu_plat = pdev->dev.platform_data; @@ -914,9 +939,11 @@ static int vpu_dev_probe(struct platform_device *pdev) } #endif + vpu_dev = &pdev->dev; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu_regs"); if (!res) { - printk(KERN_ERR "vpu: unable to get vpu base addr\n"); + dev_err(vpu_dev, "vpu: unable to get vpu base addr\n"); return -ENODEV; } phy_vpu_base_addr = res->start; @@ -924,7 +951,7 @@ static int vpu_dev_probe(struct platform_device *pdev) vpu_major = register_chrdev(vpu_major, "mxc_vpu", &vpu_fops); if (vpu_major < 0) { - printk(KERN_ERR "vpu: unable to get a major for VPU\n"); + dev_err(vpu_dev, "vpu: unable to get a major for VPU\n"); err = -EBUSY; goto error; } @@ -950,7 +977,7 @@ static int vpu_dev_probe(struct platform_device *pdev) vpu_ipi_irq = platform_get_irq_byname(pdev, "vpu_ipi_irq"); if (vpu_ipi_irq < 0) { - printk(KERN_ERR "vpu: unable to get vpu interrupt\n"); + dev_err(vpu_dev, "vpu: unable to get vpu interrupt\n"); err = -ENXIO; goto err_out_class; } @@ -958,26 +985,21 @@ static int vpu_dev_probe(struct platform_device *pdev) (void *)(&vpu_data)); if (err) goto err_out_class; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) - vpu_regulator = regulator_get(NULL, "cpu_vddvpu"); - if (IS_ERR(vpu_regulator)) { + if (vpu_power_get(true)) { if (!(cpu_is_mx51() || cpu_is_mx53())) { - printk(KERN_ERR - "%s: failed to get vpu regulator\n", __func__); + dev_err(vpu_dev, "failed to get vpu power\n"); goto err_out_class; } else { /* regulator_get will return error on MX5x, * just igore it everywhere*/ - printk(KERN_WARNING - "%s: failed to get vpu regulator\n", __func__); + dev_warn(vpu_dev, "failed to get vpu power\n"); } } -#endif #ifdef MXC_VPU_HAS_JPU vpu_jpu_irq = platform_get_irq_byname(pdev, "vpu_jpu_irq"); if (vpu_jpu_irq < 0) { - printk(KERN_ERR "vpu: unable to get vpu jpu interrupt\n"); + dev_err(vpu_dev, "vpu: unable to get vpu jpu interrupt\n"); err = -ENXIO; free_irq(vpu_ipi_irq, &vpu_data); goto err_out_class; @@ -997,7 +1019,7 @@ static int vpu_dev_probe(struct platform_device *pdev) vpu_data.workqueue = create_workqueue("vpu_wq"); INIT_WORK(&vpu_data.work, vpu_worker_callback); mutex_init(&vpu_data.lock); - printk(KERN_INFO "VPU initialized\n"); + dev_info(vpu_dev, "VPU initialized\n"); goto out; err_out_class: @@ -1034,10 +1056,7 @@ static int vpu_dev_remove(struct platform_device *pdev) iram_free(iram.start, vpu_plat->iram_size); #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) - if (!IS_ERR(vpu_regulator)) - regulator_put(vpu_regulator); -#endif + vpu_power_get(false); return 0; } @@ -1111,12 +1130,7 @@ static int vpu_suspend(struct platform_device *pdev, pm_message_t state) /* If VPU is working before suspend, disable * regulator to make usecount right. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) - if (!IS_ERR(vpu_regulator)) - regulator_disable(vpu_regulator); -#else - imx_gpc_power_up_pu(false); -#endif + vpu_power_up(false); } mutex_unlock(&vpu_data.lock); @@ -1147,16 +1161,12 @@ static int vpu_resume(struct platform_device *pdev) if (cpu_is_mx53()) goto recover_clk; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) /* If VPU is working before suspend, enable * regulator to make usecount right. */ - if (!IS_ERR(vpu_regulator)) - regulator_enable(vpu_regulator); - + vpu_power_up(true); +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) if (vpu_plat->pg) vpu_plat->pg(0); -#else - imx_gpc_power_up_pu(true); #endif if (bitwork_mem.cpu_addr != 0) { @@ -1170,7 +1180,7 @@ static int vpu_resume(struct platform_device *pdev) pc = READ_REG(BIT_CUR_PC); if (pc) { - printk(KERN_WARNING "Not power off after suspend (PC=0x%x)\n", pc); + dev_warn(vpu_dev, "Not power off after suspend (PC=0x%x)\n", pc); clk_disable(vpu_clk); clk_unprepare(vpu_clk); goto recover_clk; @@ -1214,7 +1224,7 @@ static int vpu_resume(struct platform_device *pdev) while (READ_REG(BIT_BUSY_FLAG)) ; } else { - printk(KERN_WARNING "PC=0 before suspend\n"); + dev_warn(vpu_dev, "PC=0 before suspend\n"); } clk_disable(vpu_clk); clk_unprepare(vpu_clk); @@ -1314,26 +1324,13 @@ static void __exit vpu_exit(void) vpu_free_dma_buffer(&user_data_mem); /* reset VPU state */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) - if (!IS_ERR(vpu_regulator)) - regulator_enable(vpu_regulator); + vpu_power_up(true); clk_prepare(vpu_clk); clk_enable(vpu_clk); - if (vpu_plat->reset) - vpu_plat->reset(); + vpu_reset(); clk_disable(vpu_clk); clk_unprepare(vpu_clk); - if (!IS_ERR(vpu_regulator)) - regulator_disable(vpu_regulator); -#else - imx_gpc_power_up_pu(true); - clk_prepare(vpu_clk); - clk_enable(vpu_clk); - imx_src_reset_vpu(); - clk_disable(vpu_clk); - clk_unprepare(vpu_clk); - imx_gpc_power_up_pu(false); -#endif + vpu_power_up(false); clk_put(vpu_clk);