~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/char/hpet.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
84
84
        .rating         = 250,
85
85
        .read           = read_hpet,
86
86
        .mask           = CLOCKSOURCE_MASK(64),
87
 
        .mult           = 0,            /* to be calculated */
88
 
        .shift          = 10,
89
87
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
90
88
};
91
89
static struct clocksource *hpet_clocksource;
165
163
         * This has the effect of treating non-periodic like periodic.
166
164
         */
167
165
        if ((devp->hd_flags & (HPET_IE | HPET_PERIODIC)) == HPET_IE) {
168
 
                unsigned long m, t;
 
166
                unsigned long m, t, mc, base, k;
 
167
                struct hpet __iomem *hpet = devp->hd_hpet;
 
168
                struct hpets *hpetp = devp->hd_hpets;
169
169
 
170
170
                t = devp->hd_ireqfreq;
171
171
                m = read_counter(&devp->hd_timer->hpet_compare);
172
 
                write_counter(t + m, &devp->hd_timer->hpet_compare);
 
172
                mc = read_counter(&hpet->hpet_mc);
 
173
                /* The time for the next interrupt would logically be t + m,
 
174
                 * however, if we are very unlucky and the interrupt is delayed
 
175
                 * for longer than t then we will completely miss the next
 
176
                 * interrupt if we set t + m and an application will hang.
 
177
                 * Therefore we need to make a more complex computation assuming
 
178
                 * that there exists a k for which the following is true:
 
179
                 * k * t + base < mc + delta
 
180
                 * (k + 1) * t + base > mc + delta
 
181
                 * where t is the interval in hpet ticks for the given freq,
 
182
                 * base is the theoretical start value 0 < base < t,
 
183
                 * mc is the main counter value at the time of the interrupt,
 
184
                 * delta is the time it takes to write the a value to the
 
185
                 * comparator.
 
186
                 * k may then be computed as (mc - base + delta) / t .
 
187
                 */
 
188
                base = mc % t;
 
189
                k = (mc - base + hpetp->hp_delta) / t;
 
190
                write_counter(t * (k + 1) + base,
 
191
                              &devp->hd_timer->hpet_compare);
173
192
        }
174
193
 
175
194
        if (devp->hd_flags & HPET_SHARED_IRQ)
934
953
        if (!hpet_clocksource) {
935
954
                hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc;
936
955
                CLKSRC_FSYS_MMIO_SET(clocksource_hpet.fsys_mmio, hpet_mctr);
937
 
                clocksource_hpet.mult = clocksource_hz2mult(hpetp->hp_tick_freq,
938
 
                                                clocksource_hpet.shift);
939
 
                clocksource_register(&clocksource_hpet);
 
956
                clocksource_register_hz(&clocksource_hpet, hpetp->hp_tick_freq);
940
957
                hpetp->hp_clocksource = &clocksource_hpet;
941
958
                hpet_clocksource = &clocksource_hpet;
942
959
        }