lkml.org 
[lkml]   [2012]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 2/2] hw_random: mxc-rnga: Access data via structure
    Date
    In current driver, everytime we need to access the rng clock (,ie to enable or disable it) a call to clk_get is done.

    This is not correct and the preferred way is to provide a rng data structure that could be used for accessing rng resources.

    Cc: Theodore Ts'o <tytso@mit.edu>
    Cc: Herbert Xu <herbert@gondor.apana.org.au>
    Cc: <linux-kernel@vger.kernel.org>
    Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
    ---
    Changes since v1:
    - No changes. Newly introduced in this version
    drivers/char/hw_random/mxc-rnga.c | 108 +++++++++++++++++-------------------
    1 files changed, 51 insertions(+), 57 deletions(-)

    diff --git a/drivers/char/hw_random/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c
    index 62c7efe..f05d857 100644
    --- a/drivers/char/hw_random/mxc-rnga.c
    +++ b/drivers/char/hw_random/mxc-rnga.c
    @@ -59,16 +59,21 @@
    #define RNGA_STATUS_LAST_READ_STATUS 0x00000002
    #define RNGA_STATUS_SECURITY_VIOLATION 0x00000001

    -static struct platform_device *rng_dev;
    +struct mxc_rng {
    + struct device *dev;
    + struct hwrng rng;
    + void __iomem *mem;
    + struct clk *clk;
    +};

    static int mxc_rnga_data_present(struct hwrng *rng, int wait)
    {
    - void __iomem *rng_base = (void __iomem *)rng->priv;
    int i;
    + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);

    for (i = 0; i < 20; i++) {
    /* how many random numbers are in FIFO? [0-16] */
    - int level = (__raw_readl(rng_base + RNGA_STATUS) &
    + int level = (__raw_readl(mxc_rng->mem + RNGA_STATUS) &
    RNGA_STATUS_LEVEL_MASK) >> 8;
    if (level || !wait)
    return !!level;
    @@ -81,20 +86,20 @@ static int mxc_rnga_data_read(struct hwrng *rng, u32 * data)
    {
    int err;
    u32 ctrl;
    - void __iomem *rng_base = (void __iomem *)rng->priv;
    + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);

    /* retrieve a random number from FIFO */
    - *data = __raw_readl(rng_base + RNGA_OUTPUT_FIFO);
    + *data = __raw_readl(mxc_rng->mem + RNGA_OUTPUT_FIFO);

    /* some error while reading this random number? */
    - err = __raw_readl(rng_base + RNGA_STATUS) & RNGA_STATUS_ERROR_INT;
    + err = __raw_readl(mxc_rng->mem + RNGA_STATUS) & RNGA_STATUS_ERROR_INT;

    /* if error: clear error interrupt, but doesn't return random number */
    if (err) {
    - dev_dbg(&rng_dev->dev, "Error while reading random number!\n");
    - ctrl = __raw_readl(rng_base + RNGA_CONTROL);
    + dev_dbg(mxc_rng->dev, "Error while reading random number!\n");
    + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
    __raw_writel(ctrl | RNGA_CONTROL_CLEAR_INT,
    - rng_base + RNGA_CONTROL);
    + mxc_rng->mem + RNGA_CONTROL);
    return 0;
    } else
    return 4;
    @@ -103,22 +108,22 @@ static int mxc_rnga_data_read(struct hwrng *rng, u32 * data)
    static int mxc_rnga_init(struct hwrng *rng)
    {
    u32 ctrl, osc;
    - void __iomem *rng_base = (void __iomem *)rng->priv;
    + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);

    /* wake up */
    - ctrl = __raw_readl(rng_base + RNGA_CONTROL);
    - __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, rng_base + RNGA_CONTROL);
    + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
    + __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, mxc_rng->mem + RNGA_CONTROL);

    /* verify if oscillator is working */
    - osc = __raw_readl(rng_base + RNGA_STATUS);
    + osc = __raw_readl(mxc_rng->mem + RNGA_STATUS);
    if (osc & RNGA_STATUS_OSC_DEAD) {
    - dev_err(&rng_dev->dev, "RNGA Oscillator is dead!\n");
    + dev_err(mxc_rng->dev, "RNGA Oscillator is dead!\n");
    return -ENODEV;
    }

    /* go running */
    - ctrl = __raw_readl(rng_base + RNGA_CONTROL);
    - __raw_writel(ctrl | RNGA_CONTROL_GO, rng_base + RNGA_CONTROL);
    + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
    + __raw_writel(ctrl | RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL);

    return 0;
    }
    @@ -126,40 +131,40 @@ static int mxc_rnga_init(struct hwrng *rng)
    static void mxc_rnga_cleanup(struct hwrng *rng)
    {
    u32 ctrl;
    - void __iomem *rng_base = (void __iomem *)rng->priv;
    + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);

    - ctrl = __raw_readl(rng_base + RNGA_CONTROL);
    + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);

    /* stop rnga */
    - __raw_writel(ctrl & ~RNGA_CONTROL_GO, rng_base + RNGA_CONTROL);
    + __raw_writel(ctrl & ~RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL);
    }

    -static struct hwrng mxc_rnga = {
    - .name = "mxc-rnga",
    - .init = mxc_rnga_init,
    - .cleanup = mxc_rnga_cleanup,
    - .data_present = mxc_rnga_data_present,
    - .data_read = mxc_rnga_data_read
    -};
    -
    static int __init mxc_rnga_probe(struct platform_device *pdev)
    {
    int err = -ENODEV;
    - struct clk *clk;
    struct resource *res, *mem;
    - void __iomem *rng_base = NULL;
    -
    - if (rng_dev)
    - return -EBUSY;
    -
    - clk = clk_get(&pdev->dev, NULL);
    - if (IS_ERR(clk)) {
    + struct mxc_rng *mxc_rng;
    +
    + mxc_rng = devm_kzalloc(&pdev->dev, sizeof(struct mxc_rng),
    + GFP_KERNEL);
    + if (!mxc_rng)
    + return -ENOMEM;
    +
    + mxc_rng->dev = &pdev->dev;
    + mxc_rng->rng.name = "mxc-rnga";
    + mxc_rng->rng.init = mxc_rnga_init;
    + mxc_rng->rng.cleanup = mxc_rnga_cleanup,
    + mxc_rng->rng.data_present = mxc_rnga_data_present,
    + mxc_rng->rng.data_read = mxc_rnga_data_read,
    +
    + mxc_rng->clk = devm_clk_get(&pdev->dev, NULL);
    + if (IS_ERR(mxc_rng->clk)) {
    dev_err(&pdev->dev, "Could not get rng_clk!\n");
    - err = PTR_ERR(clk);
    + err = PTR_ERR(mxc_rng->clk);
    goto out;
    }

    - clk_prepare_enable(clk);
    + clk_prepare_enable(mxc_rng->clk);

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!res) {
    @@ -173,36 +178,27 @@ static int __init mxc_rnga_probe(struct platform_device *pdev)
    goto err_region;
    }

    - rng_base = ioremap(res->start, resource_size(res));
    - if (!rng_base) {
    + mxc_rng->mem = ioremap(res->start, resource_size(res));
    + if (!mxc_rng->mem) {
    err = -ENOMEM;
    goto err_ioremap;
    }

    - mxc_rnga.priv = (unsigned long)rng_base;
    -
    - err = hwrng_register(&mxc_rnga);
    + err = hwrng_register(&mxc_rng->rng);
    if (err) {
    dev_err(&pdev->dev, "MXC RNGA registering failed (%d)\n", err);
    - goto err_register;
    + goto err_ioremap;
    }

    - rng_dev = pdev;
    -
    dev_info(&pdev->dev, "MXC RNGA Registered.\n");

    return 0;

    -err_register:
    - iounmap(rng_base);
    - rng_base = NULL;
    -
    err_ioremap:
    release_mem_region(res->start, resource_size(res));

    err_region:
    - clk_disable_unprepare(clk);
    - clk_put(clk);
    + clk_disable_unprepare(mxc_rng->clk);

    out:
    return err;
    @@ -211,17 +207,15 @@ out:
    static int __exit mxc_rnga_remove(struct platform_device *pdev)
    {
    struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    - void __iomem *rng_base = (void __iomem *)mxc_rnga.priv;
    - struct clk *clk = clk_get(&pdev->dev, NULL);
    + struct mxc_rng *mxc_rng = platform_get_drvdata(pdev);

    - hwrng_unregister(&mxc_rnga);
    + hwrng_unregister(&mxc_rng->rng);

    - iounmap(rng_base);
    + iounmap(mxc_rng->mem);

    release_mem_region(res->start, resource_size(res));

    - clk_disable_unprepare(clk);
    - clk_put(clk);
    + clk_disable_unprepare(mxc_rng->clk);

    return 0;
    }
    --
    1.7.1



    \
     
     \ /
      Last update: 2012-07-27 19:21    [W:0.034 / U:29.964 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site