Quantcast

Using timers on kernel 3.2

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Using timers on kernel 3.2

MiLo
There are two thing I really need on the Overo: Wifi and PWM.

Good Wifi is only available now in sakoman's 3.2 kernel, which now has a patch to enable SDIO IRQ and hence finally gets a decent performance.

Unfortunately, something has drastically changed in the 3.2 kernel with respect to the PWM timers. I'm using three of them, 9,10,11 currently, to generate a complex set of timed outputs with little to no CPU intervention. This ran perfectly on the 3.0 kernel, but on the 3.2 kernel, my driver gets an error when calling omap2_dm_timer_set_src, in the dmesg output, it says:
omap_timer omap_timer.9: omap2_dm_timer_set_src: clk_set_parent() to sys_ck FAILED
omap_timer omap_timer.10: omap2_dm_timer_set_src: clk_set_parent() to sys_ck FAILED
omap_timer omap_timer.11: omap2_dm_timer_set_src: clk_set_parent() to sys_ck FAILED

I tried just ignoring this, but this leads to a complete system hangup when I start using my driver, which is based on Scott Ellis's too, and I got one hit on Google which did not help at all, but explains the problem perfectly:
https://github.com/scottellis/omap3-pwm/issues/3

So currently I get to chose between Wifi or PWM, and I cannot get both :(

I'd really like to solve the PWM issue, anyone who can point me into the direction of WHAT has changed with the timers, and what is expected from a user like me to adapt to the new situation?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using timers on kernel 3.2

Scott Ellis
For anyone interested, I committed a new [3.2] branch for the omap3-pwm driver.

MiLo see commit 85360a417

Still testing, but it at least loads and runs again on 3.2 kernels. I haven't tested the change against older kernels so I'm keeping it in a separate branch.

There is another new issue on the 3.2 systems with unloading and reloading the driver. This doesn't work any more if you use one of the timers while the driver is loaded. That particular timer won't load again.

This is really only a problem during development since you'll likely only load the driver once on boot.

When I get a chance I'll take a closer look at the unload/reload problem.

It looks like its all PM related kernel changes.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using timers on kernel 3.2

Scott Ellis
FYI

I merged this change into the [master] branch.

The change didn't hurt operation on older kernels.

The [3.2] branch no longer exists.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using timers on kernel 3.2

MiLo
This still does not solve the "omap2_dm_timer_set_src: clk_set_parent() to sys_ck FAILED" error, as a result, timers 10 and 11 will only run at 32kHz instead of 13MHz as intended. Any news on that?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using timers on kernel 3.2

Scott Ellis
The pwm driver is working for me. I've tested all 4 timers on a 3.2 kernel.

In the pwm_init() function in my code, the src clock is changed to the 13 MHz clock unconditionally.
I never use the 32 kHz clock in the pwm driver.

If the clock change fails the driver wouldn't load.

... snip from pwm_init() ...

    for (i = 0; i < num_timers; i++) {
        pwm_dev[i].timer = omap_dm_timer_request_specific(pwm_dev[i].id);

        if (!pwm_dev[i].timer)
            goto timer_init_fail;

        omap_dm_timer_set_pwm(pwm_dev[i].timer,
            0, // ~SCPWM low when off
            1, // PT pulse toggle modulation
            OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE);

        if (omap_dm_timer_set_source(pwm_dev[i].timer, OMAP_TIMER_SRC_SYS_CLK))
            goto timer_init_fail;

        // make sure we know the source clock frequency
        fclk = omap_dm_timer_get_fclk(pwm_dev[i].timer);
        pwm_dev[i].input_freq = clk_get_rate(fclk);

        pwm_set_frequency(&pwm_dev[i]);
    }
...

I still can't unload the driver and reload it again and use the same timers though.
It fails with the error you point out.

It isn't my call to omap_dm_timer_set_source() in pwm_init()  that fails either.

Inside the omap_dm_timer_request_specific() code is another call to omap_dm_timer_set_source().

That is the omap_dm_timer_set_source() call that is failing.

As I said in the github issue, I traced it down through several function to arch/arm/plat-omap/clock.c - clk_set_parent()

There are several ways this function can fail, but the actual error code does not survive the higher calling functions.

One of them throws away the error code and you get back basically a boolean, failed or succeeded.

I've yet to put in some printk's to troubleshoot further.

I have one other observation. I can load and unload the driver repeatedly as long as I don't call omap_dm_timer_start().
Once that has been called I cannot unload the driver and reload it and use that particular timer again. I suspect it is some
cleanup problem, but it is not obvious to me what is missing.

Likely most kernel timer users/developers would never see this because they load their kernel driver only once.

Unfortunately and because I'm lazy, that's what I've been doing as well and the reason I haven't pursued fixing this.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using timers on kernel 3.2

MiLo
Still can't get around this issue. Really. Please, help!

This is in my __init routine, it ALWAYS fails with "omap_timer omap_timer.10: omap2_dm_timer_set_src: clk_set_parent() to sys_ck FAILED" on the kernel log.

	
	timer = omap_dm_timer_request_specific(10);
	if (timer == NULL)
	{
		printk(KERN_WARNING "pwm: omap_dm_timer_request_specific(10) failed\n");
		status = -ENOMEM;
		goto error0;
	}
	omap_dm_timer_set_pwm(timer,
			0,	// ~SCPWM low when off
			1,	// PT pulse toggle modulation
			OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE);
	if (omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_SYS_CLK) != 0)
	{
		printk(KERN_WARNING "omap_dm_timer_set_source failed, this may lead to bad things.\n");
	}

It's the first thing I do. Nothing else happens. The driver is a module and gets loaded at boot (modutils).

It's 100% the same thing as Scott is doing, but for me, this only works on the 3.0 kernel and NEVER on the 3.2 kernel.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using timers on kernel 3.2

Scott Ellis
Send me your driver and I'll try it right now.

I'm working on some Gumstix kernel stuff today so it's a good time.
Loading...