Commit cc4e8c3d authored by Sifan Naeem's avatar Sifan Naeem Committed by Mauro Carvalho Chehab

[media] rc: img-ir: Add and enable sys clock for img-ir

Gets a handle to the system clock, already described in the binding
document, and calls the appropriate common clock framework functions
to mark it prepared/enabled, the common clock framework initially
enables the clock and doesn't disable it at least until the
device/driver is removed.
It's important the systen clock is enabled before register interface is
accessed by the driver.
The system clock to IR is needed for the driver to communicate with the
IR hardware via MMIO accesses on the system bus, so it must not be
disabled during use or the driver will malfunction.
Signed-off-by: default avatarSifan Naeem <sifan.naeem@imgtec.com>
Acked-by: default avatarJames Hogan <james.hogan@imgtec.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent a2bbf5d0
...@@ -110,16 +110,32 @@ static int img_ir_probe(struct platform_device *pdev) ...@@ -110,16 +110,32 @@ static int img_ir_probe(struct platform_device *pdev)
priv->clk = devm_clk_get(&pdev->dev, "core"); priv->clk = devm_clk_get(&pdev->dev, "core");
if (IS_ERR(priv->clk)) if (IS_ERR(priv->clk))
dev_warn(&pdev->dev, "cannot get core clock resource\n"); dev_warn(&pdev->dev, "cannot get core clock resource\n");
/* Get sys clock */
priv->sys_clk = devm_clk_get(&pdev->dev, "sys");
if (IS_ERR(priv->sys_clk))
dev_warn(&pdev->dev, "cannot get sys clock resource\n");
/* /*
* The driver doesn't need to know about the system ("sys") or power * Enabling the system clock before the register interface is
* modulation ("mod") clocks yet * accessed. ISR shouldn't get called with Sys Clock disabled,
* hence exiting probe with an error.
*/ */
if (!IS_ERR(priv->sys_clk)) {
error = clk_prepare_enable(priv->sys_clk);
if (error) {
dev_err(&pdev->dev, "cannot enable sys clock\n");
return error;
}
}
/* Set up raw & hw decoder */ /* Set up raw & hw decoder */
error = img_ir_probe_raw(priv); error = img_ir_probe_raw(priv);
error2 = img_ir_probe_hw(priv); error2 = img_ir_probe_hw(priv);
if (error && error2) if (error && error2) {
return (error == -ENODEV) ? error2 : error; if (error == -ENODEV)
error = error2;
goto err_probe;
}
/* Get the IRQ */ /* Get the IRQ */
priv->irq = irq; priv->irq = irq;
...@@ -139,6 +155,9 @@ static int img_ir_probe(struct platform_device *pdev) ...@@ -139,6 +155,9 @@ static int img_ir_probe(struct platform_device *pdev)
err_irq: err_irq:
img_ir_remove_hw(priv); img_ir_remove_hw(priv);
img_ir_remove_raw(priv); img_ir_remove_raw(priv);
err_probe:
if (!IS_ERR(priv->sys_clk))
clk_disable_unprepare(priv->sys_clk);
return error; return error;
} }
...@@ -152,6 +171,8 @@ static int img_ir_remove(struct platform_device *pdev) ...@@ -152,6 +171,8 @@ static int img_ir_remove(struct platform_device *pdev)
if (!IS_ERR(priv->clk)) if (!IS_ERR(priv->clk))
clk_disable_unprepare(priv->clk); clk_disable_unprepare(priv->clk);
if (!IS_ERR(priv->sys_clk))
clk_disable_unprepare(priv->sys_clk);
return 0; return 0;
} }
......
...@@ -138,6 +138,7 @@ struct clk; ...@@ -138,6 +138,7 @@ struct clk;
* @dev: Platform device. * @dev: Platform device.
* @irq: IRQ number. * @irq: IRQ number.
* @clk: Input clock. * @clk: Input clock.
* @sys_clk: System clock.
* @reg_base: Iomem base address of IR register block. * @reg_base: Iomem base address of IR register block.
* @lock: Protects IR registers and variables in this struct. * @lock: Protects IR registers and variables in this struct.
* @raw: Driver data for raw decoder. * @raw: Driver data for raw decoder.
...@@ -147,6 +148,7 @@ struct img_ir_priv { ...@@ -147,6 +148,7 @@ struct img_ir_priv {
struct device *dev; struct device *dev;
int irq; int irq;
struct clk *clk; struct clk *clk;
struct clk *sys_clk;
void __iomem *reg_base; void __iomem *reg_base;
spinlock_t lock; spinlock_t lock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment