mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	hwrng: bcm2835 - Manage an optional clock
One of the last steps before bcm63xx-rng can be eliminated is to manage a clock during hwrng::init and hwrng::cleanup, so fetch it in the probe function, and manage it during these two steps when valid. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Reviewed-by: Eric Anholt <eric@anholt.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
		
							parent
							
								
									04b154fa86
								
							
						
					
					
						commit
						791af4f490
					
				
					 1 changed files with 16 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -15,6 +15,7 @@
 | 
			
		|||
#include <linux/of_platform.h>
 | 
			
		||||
#include <linux/platform_device.h>
 | 
			
		||||
#include <linux/printk.h>
 | 
			
		||||
#include <linux/clk.h>
 | 
			
		||||
 | 
			
		||||
#define RNG_CTRL	0x0
 | 
			
		||||
#define RNG_STATUS	0x4
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +34,7 @@ struct bcm2835_rng_priv {
 | 
			
		|||
	struct hwrng rng;
 | 
			
		||||
	void __iomem *base;
 | 
			
		||||
	bool mask_interrupts;
 | 
			
		||||
	struct clk *clk;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline struct bcm2835_rng_priv *to_rng_priv(struct hwrng *rng)
 | 
			
		||||
| 
						 | 
				
			
			@ -66,8 +68,15 @@ static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max,
 | 
			
		|||
static int bcm2835_rng_init(struct hwrng *rng)
 | 
			
		||||
{
 | 
			
		||||
	struct bcm2835_rng_priv *priv = to_rng_priv(rng);
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	u32 val;
 | 
			
		||||
 | 
			
		||||
	if (!IS_ERR(priv->clk)) {
 | 
			
		||||
		ret = clk_prepare_enable(priv->clk);
 | 
			
		||||
		if (ret)
 | 
			
		||||
			return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->mask_interrupts) {
 | 
			
		||||
		/* mask the interrupt */
 | 
			
		||||
		val = readl(priv->base + RNG_INT_MASK);
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +88,7 @@ static int bcm2835_rng_init(struct hwrng *rng)
 | 
			
		|||
	__raw_writel(RNG_WARMUP_COUNT, priv->base + RNG_STATUS);
 | 
			
		||||
	__raw_writel(RNG_RBGEN, priv->base + RNG_CTRL);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void bcm2835_rng_cleanup(struct hwrng *rng)
 | 
			
		||||
| 
						 | 
				
			
			@ -88,6 +97,9 @@ static void bcm2835_rng_cleanup(struct hwrng *rng)
 | 
			
		|||
 | 
			
		||||
	/* disable rng hardware */
 | 
			
		||||
	__raw_writel(0, priv->base + RNG_CTRL);
 | 
			
		||||
 | 
			
		||||
	if (!IS_ERR(priv->clk))
 | 
			
		||||
		clk_disable_unprepare(priv->clk);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct bcm2835_rng_of_data {
 | 
			
		||||
| 
						 | 
				
			
			@ -130,6 +142,9 @@ static int bcm2835_rng_probe(struct platform_device *pdev)
 | 
			
		|||
		return PTR_ERR(priv->base);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Clock is optional on most platforms */
 | 
			
		||||
	priv->clk = devm_clk_get(dev, NULL);
 | 
			
		||||
 | 
			
		||||
	priv->rng.name = "bcm2835-rng";
 | 
			
		||||
	priv->rng.init = bcm2835_rng_init;
 | 
			
		||||
	priv->rng.read = bcm2835_rng_read;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue