MLK-11360-01 crypto: caam_snvs: add snvs clock management

caam_snvs driver involves snvs HP registers access that needs to
enable snvs clock source. The patch add the clock management.

Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Dan Douglass <dan.douglass@freescale.com>
(Vipul: Fixed merge conflicts)
Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>
This commit is contained in:
Fugang Duan 2015-08-14 14:46:23 +08:00 committed by Leonard Crestez
parent 07566f42a4
commit 3ac6edcd92
3 changed files with 26 additions and 13 deletions

View File

@ -456,18 +456,14 @@ Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node
value type: <u32>
Definition: LP register offset. default it is 0x34.
- clocks
Usage: optional, required if SNVS LP RTC requires explicit
enablement of clocks
Value type: <prop_encoded-array>
Definition: a clock specifier describing the clock required for
enabling and disabling SNVS LP RTC.
- clock-names
Usage: optional, required if SNVS LP RTC requires explicit
enablement of clocks
Value type: <string>
Definition: clock name string should be "snvs-rtc".
- clocks
Usage: optional
Value type: <prop-encoded-array>
Definition: A standard property. Specifies the source clock for
snvs register access. If i.MX clk driver defines the clock node,
it needs user to specify the clocks in device tree for all modules
with snvs LP/HP registers access. The modules involved snvs LP/HP
registers access are snvs-power key, snvs-rtc, and caam.
EXAMPLE
sec_mon_rtc_lp@1 {

View File

@ -51,12 +51,15 @@ static irqreturn_t snvs_secvio_interrupt(int irq, void *snvsdev)
struct device *dev = snvsdev;
struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev);
clk_enable(svpriv->clk);
/* Check the HP secvio status register */
svpriv->irqcause = rd_reg32(&svpriv->svregs->hp.secvio_status) &
HP_SECVIOST_SECVIOMASK;
if (!svpriv->irqcause)
if (!svpriv->irqcause) {
clk_disable(svpriv->clk);
return IRQ_NONE;
}
/* Now ACK cause */
clrsetbits_32(&svpriv->svregs->hp.secvio_status, 0, svpriv->irqcause);
@ -66,6 +69,8 @@ static irqreturn_t snvs_secvio_interrupt(int irq, void *snvsdev)
tasklet_schedule(&svpriv->irqtask[smp_processor_id()]);
preempt_enable();
clk_disable(svpriv->clk);
return IRQ_HANDLED;
}
@ -176,6 +181,7 @@ static int snvs_secvio_remove(struct platform_device *pdev)
svdev = &pdev->dev;
svpriv = dev_get_drvdata(svdev);
clk_enable(svpriv->clk);
/* Set all sources to nonfatal */
wr_reg32(&svpriv->svregs->hp.secvio_intcfg, 0);
@ -183,6 +189,7 @@ static int snvs_secvio_remove(struct platform_device *pdev)
for_each_possible_cpu(i)
tasklet_kill(&svpriv->irqtask[i]);
clk_disable_unprepare(svpriv->clk);
free_irq(svpriv->irq, svdev);
iounmap(svpriv->svregs);
kfree(svpriv);
@ -227,6 +234,12 @@ static int snvs_secvio_probe(struct platform_device *pdev)
}
svpriv->svregs = (struct snvs_full __force *)snvsregs;
svpriv->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(svpriv->clk)) {
dev_err(&pdev->dev, "can't get snvs clock\n");
svpriv->clk = NULL;
}
/* Device data set up. Now init interrupt source descriptions */
for (i = 0; i < MAX_SECVIO_SOURCES; i++) {
svpriv->intsrc[i].intname = violation_src_name[i];
@ -248,6 +261,7 @@ static int snvs_secvio_probe(struct platform_device *pdev)
return -EINVAL;
}
clk_prepare_enable(svpriv->clk);
/*
* Configure all sources as fatal violations except LP section,
* source #5 (typically used as an external tamper detect), and
@ -263,6 +277,8 @@ static int snvs_secvio_probe(struct platform_device *pdev)
dev_info(svdev, "violation handlers armed - %s state\n",
snvs_ssm_state_name[hpstate]);
clk_disable(svpriv->clk);
return 0;
}

View File

@ -55,6 +55,7 @@ struct snvs_secvio_drv_private {
spinlock_t svlock ____cacheline_aligned;
struct tasklet_struct irqtask[NR_CPUS];
struct snvs_full __iomem *svregs; /* both HP and LP domains */
struct clk *clk;
int irq;
u32 irqcause; /* stashed cause of violation interrupt */