~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to arch/arm/mach-footbridge/isa-timer.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 *  Copyright (C) 1998 Russell King.
5
5
 *  Copyright (C) 1998 Phil Blundell
6
6
 */
 
7
#include <linux/clockchips.h>
 
8
#include <linux/clocksource.h>
7
9
#include <linux/init.h>
8
10
#include <linux/interrupt.h>
9
11
#include <linux/irq.h>
10
12
#include <linux/io.h>
 
13
#include <linux/timex.h>
11
14
 
12
15
#include <asm/irq.h>
13
16
 
15
18
 
16
19
#include "common.h"
17
20
 
18
 
/*
19
 
 * ISA timer tick support
20
 
 */
21
 
#define mSEC_10_from_14 ((14318180 + 100) / 200)
22
 
 
23
 
static unsigned long isa_gettimeoffset(void)
 
21
#define PIT_MODE        0x43
 
22
#define PIT_CH0         0x40
 
23
 
 
24
#define PIT_LATCH       ((PIT_TICK_RATE + HZ / 2) / HZ)
 
25
 
 
26
static cycle_t pit_read(struct clocksource *cs)
24
27
{
 
28
        unsigned long flags;
 
29
        static int old_count;
 
30
        static u32 old_jifs;
25
31
        int count;
26
 
 
27
 
        static int count_p = (mSEC_10_from_14/6);    /* for the first call after boot */
28
 
        static unsigned long jiffies_p = 0;
29
 
 
30
 
        /*
31
 
         * cache volatile jiffies temporarily; we have IRQs turned off. 
32
 
         */
33
 
        unsigned long jiffies_t;
34
 
 
35
 
        /* timer count may underflow right here */
36
 
        outb_p(0x00, 0x43);     /* latch the count ASAP */
37
 
 
38
 
        count = inb_p(0x40);    /* read the latched count */
39
 
 
40
 
        /*
41
 
         * We do this guaranteed double memory access instead of a _p 
42
 
         * postfix in the previous port access. Wheee, hackady hack
43
 
         */
44
 
        jiffies_t = jiffies;
45
 
 
46
 
        count |= inb_p(0x40) << 8;
47
 
 
48
 
        /* Detect timer underflows.  If we haven't had a timer tick since 
49
 
           the last time we were called, and time is apparently going
50
 
           backwards, the counter must have wrapped during this routine. */
51
 
        if ((jiffies_t == jiffies_p) && (count > count_p))
52
 
                count -= (mSEC_10_from_14/6);
53
 
        else
54
 
                jiffies_p = jiffies_t;
55
 
 
56
 
        count_p = count;
57
 
 
58
 
        count = (((mSEC_10_from_14/6)-1) - count) * (tick_nsec / 1000);
59
 
        count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
60
 
 
61
 
        return count;
62
 
}
63
 
 
64
 
static irqreturn_t
65
 
isa_timer_interrupt(int irq, void *dev_id)
66
 
{
67
 
        timer_tick();
 
32
        u32 jifs;
 
33
 
 
34
        raw_local_irq_save(flags);
 
35
 
 
36
        jifs = jiffies;
 
37
        outb_p(0x00, PIT_MODE);         /* latch the count */
 
38
        count = inb_p(PIT_CH0);         /* read the latched count */
 
39
        count |= inb_p(PIT_CH0) << 8;
 
40
 
 
41
        if (count > old_count && jifs == old_jifs)
 
42
                count = old_count;
 
43
 
 
44
        old_count = count;
 
45
        old_jifs = jifs;
 
46
 
 
47
        raw_local_irq_restore(flags);
 
48
 
 
49
        count = (PIT_LATCH - 1) - count;
 
50
 
 
51
        return (cycle_t)(jifs * PIT_LATCH) + count;
 
52
}
 
53
 
 
54
static struct clocksource pit_cs = {
 
55
        .name           = "pit",
 
56
        .rating         = 110,
 
57
        .read           = pit_read,
 
58
        .mask           = CLOCKSOURCE_MASK(32),
 
59
};
 
60
 
 
61
static void pit_set_mode(enum clock_event_mode mode,
 
62
        struct clock_event_device *evt)
 
63
{
 
64
        unsigned long flags;
 
65
 
 
66
        raw_local_irq_save(flags);
 
67
 
 
68
        switch (mode) {
 
69
        case CLOCK_EVT_MODE_PERIODIC:
 
70
                outb_p(0x34, PIT_MODE);
 
71
                outb_p(PIT_LATCH & 0xff, PIT_CH0);
 
72
                outb_p(PIT_LATCH >> 8, PIT_CH0);
 
73
                break;
 
74
 
 
75
        case CLOCK_EVT_MODE_SHUTDOWN:
 
76
        case CLOCK_EVT_MODE_UNUSED:
 
77
                outb_p(0x30, PIT_MODE);
 
78
                outb_p(0, PIT_CH0);
 
79
                outb_p(0, PIT_CH0);
 
80
                break;
 
81
 
 
82
        case CLOCK_EVT_MODE_ONESHOT:
 
83
        case CLOCK_EVT_MODE_RESUME:
 
84
                break;
 
85
        }
 
86
        local_irq_restore(flags);
 
87
}
 
88
 
 
89
static int pit_set_next_event(unsigned long delta,
 
90
        struct clock_event_device *evt)
 
91
{
 
92
        return 0;
 
93
}
 
94
 
 
95
static struct clock_event_device pit_ce = {
 
96
        .name           = "pit",
 
97
        .features       = CLOCK_EVT_FEAT_PERIODIC,
 
98
        .set_mode       = pit_set_mode,
 
99
        .set_next_event = pit_set_next_event,
 
100
        .shift          = 32,
 
101
};
 
102
 
 
103
static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
 
104
{
 
105
        struct clock_event_device *ce = dev_id;
 
106
        ce->event_handler(ce);
68
107
        return IRQ_HANDLED;
69
108
}
70
109
 
71
 
static struct irqaction isa_timer_irq = {
72
 
        .name           = "ISA timer tick",
73
 
        .handler        = isa_timer_interrupt,
 
110
static struct irqaction pit_timer_irq = {
 
111
        .name           = "pit",
 
112
        .handler        = pit_timer_interrupt,
74
113
        .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
 
114
        .dev_id         = &pit_ce,
75
115
};
76
116
 
77
117
static void __init isa_timer_init(void)
78
118
{
79
 
        /* enable PIT timer */
80
 
        /* set for periodic (4) and LSB/MSB write (0x30) */
81
 
        outb(0x34, 0x43);
82
 
        outb((mSEC_10_from_14/6) & 0xFF, 0x40);
83
 
        outb((mSEC_10_from_14/6) >> 8, 0x40);
84
 
 
85
 
        setup_irq(IRQ_ISA_TIMER, &isa_timer_irq);
 
119
        pit_ce.cpumask = cpumask_of(smp_processor_id());
 
120
        pit_ce.mult = div_sc(PIT_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
 
121
        pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce);
 
122
        pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce);
 
123
 
 
124
        clocksource_register_hz(&pit_cs, PIT_TICK_RATE);
 
125
 
 
126
        setup_irq(pit_ce.irq, &pit_timer_irq);
 
127
        clockevents_register_device(&pit_ce);
86
128
}
87
129
 
88
130
struct sys_timer isa_timer = {
89
131
        .init           = isa_timer_init,
90
 
        .offset         = isa_gettimeoffset,
91
132
};