diff options
Diffstat (limited to 'drivers/clocksource/timer-microchip-pit64b.c')
| -rw-r--r-- | drivers/clocksource/timer-microchip-pit64b.c | 64 | 
1 files changed, 27 insertions, 37 deletions
| diff --git a/drivers/clocksource/timer-microchip-pit64b.c b/drivers/clocksource/timer-microchip-pit64b.c index abce83d2f00b..d5f1436f33d9 100644 --- a/drivers/clocksource/timer-microchip-pit64b.c +++ b/drivers/clocksource/timer-microchip-pit64b.c @@ -61,7 +61,7 @@ struct mchp_pit64b_timer {  };  /** - * mchp_pit64b_clkevt - PIT64B clockevent data structure + * struct mchp_pit64b_clkevt - PIT64B clockevent data structure   * @timer: PIT64B timer   * @clkevt: clockevent   */ @@ -75,7 +75,7 @@ struct mchp_pit64b_clkevt {  		struct mchp_pit64b_clkevt, clkevt))  /** - * mchp_pit64b_clksrc - PIT64B clocksource data structure + * struct mchp_pit64b_clksrc - PIT64B clocksource data structure   * @timer: PIT64B timer   * @clksrc: clocksource   */ @@ -173,7 +173,8 @@ static int mchp_pit64b_clkevt_shutdown(struct clock_event_device *cedev)  {  	struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); -	writel_relaxed(MCHP_PIT64B_CR_SWRST, timer->base + MCHP_PIT64B_CR); +	if (!clockevent_state_detached(cedev)) +		mchp_pit64b_suspend(timer);  	return 0;  } @@ -182,35 +183,37 @@ static int mchp_pit64b_clkevt_set_periodic(struct clock_event_device *cedev)  {  	struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); +	if (clockevent_state_shutdown(cedev)) +		mchp_pit64b_resume(timer); +  	mchp_pit64b_reset(timer, mchp_pit64b_ce_cycles, MCHP_PIT64B_MR_CONT,  			  MCHP_PIT64B_IER_PERIOD);  	return 0;  } -static int mchp_pit64b_clkevt_set_next_event(unsigned long evt, -					     struct clock_event_device *cedev) +static int mchp_pit64b_clkevt_set_oneshot(struct clock_event_device *cedev)  {  	struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); -	mchp_pit64b_reset(timer, evt, MCHP_PIT64B_MR_ONE_SHOT, +	if (clockevent_state_shutdown(cedev)) +		mchp_pit64b_resume(timer); + +	mchp_pit64b_reset(timer, mchp_pit64b_ce_cycles, MCHP_PIT64B_MR_ONE_SHOT,  			  MCHP_PIT64B_IER_PERIOD);  	return 0;  } -static void mchp_pit64b_clkevt_suspend(struct clock_event_device *cedev) +static int mchp_pit64b_clkevt_set_next_event(unsigned long evt, +					     struct clock_event_device *cedev)  {  	struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); -	mchp_pit64b_suspend(timer); -} - -static void mchp_pit64b_clkevt_resume(struct clock_event_device *cedev) -{ -	struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); +	mchp_pit64b_reset(timer, evt, MCHP_PIT64B_MR_ONE_SHOT, +			  MCHP_PIT64B_IER_PERIOD); -	mchp_pit64b_resume(timer); +	return 0;  }  static irqreturn_t mchp_pit64b_interrupt(int irq, void *dev_id) @@ -242,8 +245,10 @@ static void __init mchp_pit64b_pres_compute(u32 *pres, u32 clk_rate,  }  /** - * mchp_pit64b_init_mode - prepare PIT64B mode register value to be used at - *			   runtime; this includes prescaler and SGCLK bit + * mchp_pit64b_init_mode() - prepare PIT64B mode register value to be used at + *			     runtime; this includes prescaler and SGCLK bit + * @timer: pointer to pit64b timer to init + * @max_rate: maximum rate that timer's clock could use   *   * PIT64B timer may be fed by gclk or pclk. When gclk is used its rate has to   * be at least 3 times lower that pclk's rate. pclk rate is fixed, gclk rate @@ -341,6 +346,7 @@ static int __init mchp_pit64b_init_clksrc(struct mchp_pit64b_timer *timer,  	if (!cs)  		return -ENOMEM; +	mchp_pit64b_resume(timer);  	mchp_pit64b_reset(timer, ULLONG_MAX, MCHP_PIT64B_MR_CONT, 0);  	mchp_pit64b_cs_base = timer->base; @@ -362,8 +368,7 @@ static int __init mchp_pit64b_init_clksrc(struct mchp_pit64b_timer *timer,  		pr_debug("clksrc: Failed to register PIT64B clocksource!\n");  		/* Stop timer. */ -		writel_relaxed(MCHP_PIT64B_CR_SWRST, -			       timer->base + MCHP_PIT64B_CR); +		mchp_pit64b_suspend(timer);  		kfree(cs);  		return ret; @@ -395,9 +400,8 @@ static int __init mchp_pit64b_init_clkevt(struct mchp_pit64b_timer *timer,  	ce->clkevt.rating = 150;  	ce->clkevt.set_state_shutdown = mchp_pit64b_clkevt_shutdown;  	ce->clkevt.set_state_periodic = mchp_pit64b_clkevt_set_periodic; +	ce->clkevt.set_state_oneshot = mchp_pit64b_clkevt_set_oneshot;  	ce->clkevt.set_next_event = mchp_pit64b_clkevt_set_next_event; -	ce->clkevt.suspend = mchp_pit64b_clkevt_suspend; -	ce->clkevt.resume = mchp_pit64b_clkevt_resume;  	ce->clkevt.cpumask = cpumask_of(0);  	ce->clkevt.irq = irq; @@ -448,19 +452,10 @@ static int __init mchp_pit64b_dt_init_timer(struct device_node *node,  	if (ret)  		goto irq_unmap; -	ret = clk_prepare_enable(timer.pclk); -	if (ret) -		goto irq_unmap; - -	if (timer.mode & MCHP_PIT64B_MR_SGCLK) { -		ret = clk_prepare_enable(timer.gclk); -		if (ret) -			goto pclk_unprepare; - +	if (timer.mode & MCHP_PIT64B_MR_SGCLK)  		clk_rate = clk_get_rate(timer.gclk); -	} else { +	else  		clk_rate = clk_get_rate(timer.pclk); -	}  	clk_rate = clk_rate / (MCHP_PIT64B_MODE_TO_PRES(timer.mode) + 1);  	if (clkevt) @@ -469,15 +464,10 @@ static int __init mchp_pit64b_dt_init_timer(struct device_node *node,  		ret = mchp_pit64b_init_clksrc(&timer, clk_rate);  	if (ret) -		goto gclk_unprepare; +		goto irq_unmap;  	return 0; -gclk_unprepare: -	if (timer.mode & MCHP_PIT64B_MR_SGCLK) -		clk_disable_unprepare(timer.gclk); -pclk_unprepare: -	clk_disable_unprepare(timer.pclk);  irq_unmap:  	irq_dispose_mapping(irq);  io_unmap: | 
