Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'at91-cleanup-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux into next/drivers

Merge "First batch of cleanups for 4.4:" from Alexandre Belloni:
- properly get the slow clock from timer-atmel-st, tcb_clksrc and pwm-atmel-tcb
- small fix in an error path for tcb_clksrc

* tag 'at91-cleanup-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux:
misc: atmel_tclib: get and use slow clock
clocksource: tcb_clksrc: fix setup_clkevents error path
clocksource: atmel-st: get and use slow clock

+57 -19
+11 -3
drivers/clocksource/tcb_clksrc.c
··· 193 193 struct clk *t2_clk = tc->clk[2]; 194 194 int irq = tc->irq[2]; 195 195 196 - /* try to enable t2 clk to avoid future errors in mode change */ 197 - ret = clk_prepare_enable(t2_clk); 196 + ret = clk_prepare_enable(tc->slow_clk); 198 197 if (ret) 199 198 return ret; 199 + 200 + /* try to enable t2 clk to avoid future errors in mode change */ 201 + ret = clk_prepare_enable(t2_clk); 202 + if (ret) { 203 + clk_disable_unprepare(tc->slow_clk); 204 + return ret; 205 + } 206 + 200 207 clk_disable(t2_clk); 201 208 202 209 clkevt.regs = tc->regs; ··· 215 208 216 209 ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt); 217 210 if (ret) { 218 - clk_disable_unprepare(t2_clk); 211 + clk_unprepare(t2_clk); 212 + clk_disable_unprepare(tc->slow_clk); 219 213 return ret; 220 214 } 221 215
+22 -9
drivers/clocksource/timer-atmel-st.c
··· 22 22 #include <linux/kernel.h> 23 23 #include <linux/interrupt.h> 24 24 #include <linux/irq.h> 25 + #include <linux/clk.h> 25 26 #include <linux/clockchips.h> 26 27 #include <linux/export.h> 27 28 #include <linux/mfd/syscon.h> ··· 34 33 static u32 irqmask; 35 34 static struct clock_event_device clkevt; 36 35 static struct regmap *regmap_st; 37 - 38 - #define AT91_SLOW_CLOCK 32768 39 - #define RM9200_TIMER_LATCH ((AT91_SLOW_CLOCK + HZ/2) / HZ) 36 + static int timer_latch; 40 37 41 38 /* 42 39 * The ST_CRTR is updated asynchronously to the master clock ... but ··· 81 82 if (sr & AT91_ST_PITS) { 82 83 u32 crtr = read_CRTR(); 83 84 84 - while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) { 85 - last_crtr += RM9200_TIMER_LATCH; 85 + while (((crtr - last_crtr) & AT91_ST_CRTV) >= timer_latch) { 86 + last_crtr += timer_latch; 86 87 clkevt.event_handler(&clkevt); 87 88 } 88 89 return IRQ_HANDLED; ··· 143 144 144 145 /* PIT for periodic irqs; fixed rate of 1/HZ */ 145 146 irqmask = AT91_ST_PITS; 146 - regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH); 147 + regmap_write(regmap_st, AT91_ST_PIMR, timer_latch); 147 148 regmap_write(regmap_st, AT91_ST_IER, irqmask); 148 149 return 0; 149 150 } ··· 196 197 */ 197 198 static void __init atmel_st_timer_init(struct device_node *node) 198 199 { 199 - unsigned int val; 200 + struct clk *sclk; 201 + unsigned int sclk_rate, val; 200 202 int irq, ret; 201 203 202 204 regmap_st = syscon_node_to_regmap(node); ··· 221 221 if (ret) 222 222 panic(pr_fmt("Unable to setup IRQ\n")); 223 223 224 + sclk = of_clk_get(node, 0); 225 + if (IS_ERR(sclk)) 226 + panic(pr_fmt("Unable to get slow clock\n")); 227 + 228 + clk_prepare_enable(sclk); 229 + if (ret) 230 + panic(pr_fmt("Could not enable slow clock\n")); 231 + 232 + sclk_rate = clk_get_rate(sclk); 233 + if (!sclk_rate) 234 + panic(pr_fmt("Invalid slow clock rate\n")); 235 + timer_latch = (sclk_rate + HZ / 2) / HZ; 236 + 224 237 /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used 225 238 * directly for the clocksource and all clockevents, after adjusting 226 239 * its prescaler from the 1 Hz default. ··· 242 229 243 230 /* Setup timer clockevent, with minimum of two ticks (important!!) */ 244 231 clkevt.cpumask = cpumask_of(0); 245 - clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK, 232 + clockevents_config_and_register(&clkevt, sclk_rate, 246 233 2, AT91_ST_ALMV); 247 234 248 235 /* register clocksource */ 249 - clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK); 236 + clocksource_register_hz(&clk32k, sclk_rate); 250 237 } 251 238 CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st", 252 239 atmel_st_timer_init);
+4
drivers/misc/atmel_tclib.c
··· 125 125 if (IS_ERR(clk)) 126 126 return PTR_ERR(clk); 127 127 128 + tc->slow_clk = devm_clk_get(&pdev->dev, "slow_clk"); 129 + if (IS_ERR(tc->slow_clk)) 130 + return PTR_ERR(tc->slow_clk); 131 + 128 132 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 129 133 tc->regs = devm_ioremap_resource(&pdev->dev, r); 130 134 if (IS_ERR(tc->regs))
+19 -7
drivers/pwm/pwm-atmel-tcb.c
··· 305 305 */ 306 306 if (i == 5) { 307 307 i = slowclk; 308 - rate = 32768; 308 + rate = clk_get_rate(tc->slow_clk); 309 309 min = div_u64(NSEC_PER_SEC, rate); 310 310 max = min << tc->tcb_config->counter_width; 311 311 ··· 387 387 388 388 tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL); 389 389 if (tcbpwm == NULL) { 390 - atmel_tc_free(tc); 390 + err = -ENOMEM; 391 391 dev_err(&pdev->dev, "failed to allocate memory\n"); 392 - return -ENOMEM; 392 + goto err_free_tc; 393 393 } 394 394 395 395 tcbpwm->chip.dev = &pdev->dev; ··· 400 400 tcbpwm->chip.npwm = NPWM; 401 401 tcbpwm->tc = tc; 402 402 403 + err = clk_prepare_enable(tc->slow_clk); 404 + if (err) 405 + goto err_free_tc; 406 + 403 407 spin_lock_init(&tcbpwm->lock); 404 408 405 409 err = pwmchip_add(&tcbpwm->chip); 406 - if (err < 0) { 407 - atmel_tc_free(tc); 408 - return err; 409 - } 410 + if (err < 0) 411 + goto err_disable_clk; 410 412 411 413 platform_set_drvdata(pdev, tcbpwm); 412 414 413 415 return 0; 416 + 417 + err_disable_clk: 418 + clk_disable_unprepare(tcbpwm->tc->slow_clk); 419 + 420 + err_free_tc: 421 + atmel_tc_free(tc); 422 + 423 + return err; 414 424 } 415 425 416 426 static int atmel_tcb_pwm_remove(struct platform_device *pdev) 417 427 { 418 428 struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev); 419 429 int err; 430 + 431 + clk_disable_unprepare(tcbpwm->tc->slow_clk); 420 432 421 433 err = pwmchip_remove(&tcbpwm->chip); 422 434 if (err < 0)
+1
include/linux/atmel_tc.h
··· 67 67 const struct atmel_tcb_config *tcb_config; 68 68 int irq[3]; 69 69 struct clk *clk[3]; 70 + struct clk *slow_clk; 70 71 struct list_head node; 71 72 bool allocated; 72 73 };