diff options
Diffstat (limited to 'drivers/soc/aspeed/aspeed-lpc-ctrl.c')
-rw-r--r-- | drivers/soc/aspeed/aspeed-lpc-ctrl.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/soc/aspeed/aspeed-lpc-ctrl.c b/drivers/soc/aspeed/aspeed-lpc-ctrl.c index c557ffd0992c..72771e018c42 100644 --- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c +++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c @@ -37,6 +37,7 @@ struct aspeed_lpc_ctrl { u32 pnor_size; u32 pnor_base; bool fwh2ahb; + struct regmap *scu; }; static struct aspeed_lpc_ctrl *file_aspeed_lpc_ctrl(struct file *file) @@ -51,7 +52,7 @@ static int aspeed_lpc_ctrl_mmap(struct file *file, struct vm_area_struct *vma) unsigned long vsize = vma->vm_end - vma->vm_start; pgprot_t prot = vma->vm_page_prot; - if (vma->vm_pgoff + vsize > lpc_ctrl->mem_base + lpc_ctrl->mem_size) + if (vma->vm_pgoff + vma_pages(vma) > lpc_ctrl->mem_size >> PAGE_SHIFT) return -EINVAL; /* ast2400/2500 AHB accesses are not cache coherent */ @@ -183,13 +184,22 @@ static long aspeed_lpc_ctrl_ioctl(struct file *file, unsigned int cmd, /* * Switch to FWH2AHB mode, AST2600 only. - * - * The other bits in this register are interrupt status bits - * that are cleared by writing 1. As we don't want to clear - * them, set only the bit of interest. */ - if (lpc_ctrl->fwh2ahb) + if (lpc_ctrl->fwh2ahb) { + /* + * Enable FWH2AHB in SCU debug control register 2. This + * does not turn it on, but makes it available for it + * to be configured in HICR6. + */ + regmap_update_bits(lpc_ctrl->scu, 0x0D8, BIT(2), 0); + + /* + * The other bits in this register are interrupt status bits + * that are cleared by writing 1. As we don't want to clear + * them, set only the bit of interest. + */ regmap_write(lpc_ctrl->regmap, HICR6, SW_FWH2AHB); + } /* * Enable LPC FHW cycles. This is required for the host to @@ -285,6 +295,16 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev) return -ENODEV; } + if (of_device_is_compatible(dev->of_node, "aspeed,ast2600-lpc-ctrl")) { + lpc_ctrl->fwh2ahb = true; + + lpc_ctrl->scu = syscon_regmap_lookup_by_compatible("aspeed,ast2600-scu"); + if (IS_ERR(lpc_ctrl->scu)) { + dev_err(dev, "couldn't find scu\n"); + return PTR_ERR(lpc_ctrl->scu); + } + } + lpc_ctrl->clk = devm_clk_get(dev, NULL); if (IS_ERR(lpc_ctrl->clk)) { dev_err(dev, "couldn't get clock\n"); @@ -296,9 +316,6 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev) return rc; } - if (of_device_is_compatible(dev->of_node, "aspeed,ast2600-lpc-ctrl")) - lpc_ctrl->fwh2ahb = true; - lpc_ctrl->miscdev.minor = MISC_DYNAMIC_MINOR; lpc_ctrl->miscdev.name = DEVICE_NAME; lpc_ctrl->miscdev.fops = &aspeed_lpc_ctrl_fops; |