diff options
Diffstat (limited to 'drivers/clocksource/timer-davinci.c')
| -rw-r--r-- | drivers/clocksource/timer-davinci.c | 30 | 
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/clocksource/timer-davinci.c b/drivers/clocksource/timer-davinci.c index 9996c0542520..b1c248498be4 100644 --- a/drivers/clocksource/timer-davinci.c +++ b/drivers/clocksource/timer-davinci.c @@ -257,21 +257,25 @@ int __init davinci_timer_register(struct clk *clk,  				resource_size(&timer_cfg->reg),  				"davinci-timer")) {  		pr_err("Unable to request memory region\n"); -		return -EBUSY; +		rv = -EBUSY; +		goto exit_clk_disable;  	}  	base = ioremap(timer_cfg->reg.start, resource_size(&timer_cfg->reg));  	if (!base) {  		pr_err("Unable to map the register range\n"); -		return -ENOMEM; +		rv = -ENOMEM; +		goto exit_mem_region;  	}  	davinci_timer_init(base);  	tick_rate = clk_get_rate(clk);  	clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL); -	if (!clockevent) -		return -ENOMEM; +	if (!clockevent) { +		rv = -ENOMEM; +		goto exit_iounmap_base; +	}  	clockevent->dev.name = "tim12";  	clockevent->dev.features = CLOCK_EVT_FEAT_ONESHOT; @@ -296,7 +300,7 @@ int __init davinci_timer_register(struct clk *clk,  			 "clockevent/tim12", clockevent);  	if (rv) {  		pr_err("Unable to request the clockevent interrupt\n"); -		return rv; +		goto exit_free_clockevent;  	}  	davinci_clocksource.dev.rating = 300; @@ -323,13 +327,27 @@ int __init davinci_timer_register(struct clk *clk,  	rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate);  	if (rv) {  		pr_err("Unable to register clocksource\n"); -		return rv; +		goto exit_free_irq;  	}  	sched_clock_register(davinci_timer_read_sched_clock,  			     DAVINCI_TIMER_CLKSRC_BITS, tick_rate);  	return 0; + +exit_free_irq: +	free_irq(timer_cfg->irq[DAVINCI_TIMER_CLOCKEVENT_IRQ].start, +			clockevent); +exit_free_clockevent: +	kfree(clockevent); +exit_iounmap_base: +	iounmap(base); +exit_mem_region: +	release_mem_region(timer_cfg->reg.start, +			   resource_size(&timer_cfg->reg)); +exit_clk_disable: +	clk_disable_unprepare(clk); +	return rv;  }  static int __init of_davinci_timer_register(struct device_node *np)  |