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

« back to all changes in this revision

Viewing changes to arch/mips/kernel/i8253.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:
125
125
        setup_irq(0, &irq0);
126
126
}
127
127
 
128
 
/*
129
 
 * Since the PIT overflows every tick, its not very useful
130
 
 * to just read by itself. So use jiffies to emulate a free
131
 
 * running counter:
132
 
 */
133
 
static cycle_t pit_read(struct clocksource *cs)
134
 
{
135
 
        unsigned long flags;
136
 
        int count;
137
 
        u32 jifs;
138
 
        static int old_count;
139
 
        static u32 old_jifs;
140
 
 
141
 
        raw_spin_lock_irqsave(&i8253_lock, flags);
142
 
        /*
143
 
         * Although our caller may have the read side of xtime_lock,
144
 
         * this is now a seqlock, and we are cheating in this routine
145
 
         * by having side effects on state that we cannot undo if
146
 
         * there is a collision on the seqlock and our caller has to
147
 
         * retry.  (Namely, old_jifs and old_count.)  So we must treat
148
 
         * jiffies as volatile despite the lock.  We read jiffies
149
 
         * before latching the timer count to guarantee that although
150
 
         * the jiffies value might be older than the count (that is,
151
 
         * the counter may underflow between the last point where
152
 
         * jiffies was incremented and the point where we latch the
153
 
         * count), it cannot be newer.
154
 
         */
155
 
        jifs = jiffies;
156
 
        outb_p(0x00, PIT_MODE); /* latch the count ASAP */
157
 
        count = inb_p(PIT_CH0); /* read the latched count */
158
 
        count |= inb_p(PIT_CH0) << 8;
159
 
 
160
 
        /* VIA686a test code... reset the latch if count > max + 1 */
161
 
        if (count > LATCH) {
162
 
                outb_p(0x34, PIT_MODE);
163
 
                outb_p(LATCH & 0xff, PIT_CH0);
164
 
                outb(LATCH >> 8, PIT_CH0);
165
 
                count = LATCH - 1;
166
 
        }
167
 
 
168
 
        /*
169
 
         * It's possible for count to appear to go the wrong way for a
170
 
         * couple of reasons:
171
 
         *
172
 
         *  1. The timer counter underflows, but we haven't handled the
173
 
         *     resulting interrupt and incremented jiffies yet.
174
 
         *  2. Hardware problem with the timer, not giving us continuous time,
175
 
         *     the counter does small "jumps" upwards on some Pentium systems,
176
 
         *     (see c't 95/10 page 335 for Neptun bug.)
177
 
         *
178
 
         * Previous attempts to handle these cases intelligently were
179
 
         * buggy, so we just do the simple thing now.
180
 
         */
181
 
        if (count > old_count && jifs == old_jifs) {
182
 
                count = old_count;
183
 
        }
184
 
        old_count = count;
185
 
        old_jifs = jifs;
186
 
 
187
 
        raw_spin_unlock_irqrestore(&i8253_lock, flags);
188
 
 
189
 
        count = (LATCH - 1) - count;
190
 
 
191
 
        return (cycle_t)(jifs * LATCH) + count;
192
 
}
193
 
 
194
 
static struct clocksource clocksource_pit = {
195
 
        .name   = "pit",
196
 
        .rating = 110,
197
 
        .read   = pit_read,
198
 
        .mask   = CLOCKSOURCE_MASK(32),
199
 
        .mult   = 0,
200
 
        .shift  = 20,
201
 
};
202
 
 
203
128
static int __init init_pit_clocksource(void)
204
129
{
205
130
        if (num_possible_cpus() > 1) /* PIT does not scale! */
206
131
                return 0;
207
132
 
208
 
        clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20);
209
 
        return clocksource_register(&clocksource_pit);
 
133
        return clocksource_i8253_init();
210
134
}
211
135
arch_initcall(init_pit_clocksource);