On Thu, Apr 17, 2008 at 04:52:35PM +0400, Anton Vorontsov wrote:
> Heh. Scott, think about it. You have single 16bit timer with variable
> frequency. To use it, you'd better know what exactly precision you need.

Why?  I know the timeout I need.

> Then you limited to u16 for the interval for this chosen precision.
> 
> Yes, you can implement this:
> 
> #define MAX_PRESCALER (256 * 256 * 16)
> 
> int gtm_reset_weird_behaving_utimer16(struct gtm_timer *tmr,
>                                     unsigned long long usec,
>                                     bool free_run)
> {
>       int freq = 1000000;
>       int min_hz2 = (tmr->gtm->freq / MAX_PRESCALER) << 1;
> 
>       while (!(freq & 1) && !(usec & 1) && freq >= min_hz2) {
>               freq >>= 1;
>               usec >>= 1;
>       }
> 
>       if (usec > 0xffff)
>               return -EINVAL;
> 
>       return gtm_reset_ref_timer16(tmr, freq, (u16)usec, free_run);
> }

Try something like this:

int gtm_reset_sane_behaving_timer(struct gtm_timer *tmr,
                                  u64 usec, bool free_run)
{
        int freq = 1000000;
        int min_hz2 = (tmr->gtm->freq / MAX_PRESCALER) << 1;

        while (usec > 0xffff && freq >= min_hz2) {
                freq >>= 1;
                usec >>= 1;
        }

        if (usec > 0xffff)
                return -EINVAL;

        return gtm_reset_ref_timer16(tmr, freq, usec, free_run);
}

It could be made faster using cntlzw.

-Scott
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to