Skip to content

Commit

Permalink
[media] rc: img-ir: Add and enable sys clock for img-ir
Browse files Browse the repository at this point in the history
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: Sifan Naeem <sifan.naeem@imgtec.com>
Acked-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  • Loading branch information
Sifan Naeem authored and Mauro Carvalho Chehab committed Apr 8, 2015
1 parent a2bbf5d commit cc4e8c3
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
29 changes: 25 additions & 4 deletions drivers/media/rc/img-ir/img-ir-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,32 @@ static int img_ir_probe(struct platform_device *pdev)
priv->clk = devm_clk_get(&pdev->dev, "core");
if (IS_ERR(priv->clk))
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
* modulation ("mod") clocks yet
* Enabling the system clock before the register interface is
* 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 */
error = img_ir_probe_raw(priv);
error2 = img_ir_probe_hw(priv);
if (error && error2)
return (error == -ENODEV) ? error2 : error;
if (error && error2) {
if (error == -ENODEV)
error = error2;
goto err_probe;
}

/* Get the IRQ */
priv->irq = irq;
Expand All @@ -139,6 +155,9 @@ static int img_ir_probe(struct platform_device *pdev)
err_irq:
img_ir_remove_hw(priv);
img_ir_remove_raw(priv);
err_probe:
if (!IS_ERR(priv->sys_clk))
clk_disable_unprepare(priv->sys_clk);
return error;
}

Expand All @@ -152,6 +171,8 @@ static int img_ir_remove(struct platform_device *pdev)

if (!IS_ERR(priv->clk))
clk_disable_unprepare(priv->clk);
if (!IS_ERR(priv->sys_clk))
clk_disable_unprepare(priv->sys_clk);
return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/media/rc/img-ir/img-ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ struct clk;
* @dev: Platform device.
* @irq: IRQ number.
* @clk: Input clock.
* @sys_clk: System clock.
* @reg_base: Iomem base address of IR register block.
* @lock: Protects IR registers and variables in this struct.
* @raw: Driver data for raw decoder.
Expand All @@ -147,6 +148,7 @@ struct img_ir_priv {
struct device *dev;
int irq;
struct clk *clk;
struct clk *sys_clk;
void __iomem *reg_base;
spinlock_t lock;

Expand Down

0 comments on commit cc4e8c3

Please sign in to comment.