~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to arch/arm/plat-stmp3xxx/timer.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * System timer for Freescale STMP37XX/STMP378X
3
 
 *
4
 
 * Embedded Alley Solutions, Inc <source@embeddedalley.com>
5
 
 *
6
 
 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
7
 
 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
8
 
 */
9
 
 
10
 
/*
11
 
 * The code contained herein is licensed under the GNU General Public
12
 
 * License. You may obtain a copy of the GNU General Public License
13
 
 * Version 2 or later at the following locations:
14
 
 *
15
 
 * http://www.opensource.org/licenses/gpl-license.html
16
 
 * http://www.gnu.org/copyleft/gpl.html
17
 
 */
18
 
#include <linux/kernel.h>
19
 
#include <linux/init.h>
20
 
#include <linux/spinlock.h>
21
 
#include <linux/clocksource.h>
22
 
#include <linux/clockchips.h>
23
 
#include <linux/io.h>
24
 
#include <linux/irq.h>
25
 
#include <linux/interrupt.h>
26
 
 
27
 
#include <asm/mach/time.h>
28
 
#include <mach/stmp3xxx.h>
29
 
#include <mach/platform.h>
30
 
#include <mach/regs-timrot.h>
31
 
 
32
 
static irqreturn_t
33
 
stmp3xxx_timer_interrupt(int irq, void *dev_id)
34
 
{
35
 
        struct clock_event_device *c = dev_id;
36
 
 
37
 
        /* timer 0 */
38
 
        if (__raw_readl(REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0) &
39
 
                        BM_TIMROT_TIMCTRLn_IRQ) {
40
 
                stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ,
41
 
                                REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
42
 
                c->event_handler(c);
43
 
        }
44
 
 
45
 
        /* timer 1 */
46
 
        else if (__raw_readl(REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1)
47
 
                        & BM_TIMROT_TIMCTRLn_IRQ) {
48
 
                stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ,
49
 
                                REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
50
 
                stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ_EN,
51
 
                                REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
52
 
                __raw_writel(0xFFFF, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
53
 
        }
54
 
 
55
 
        return IRQ_HANDLED;
56
 
}
57
 
 
58
 
static cycle_t stmp3xxx_clock_read(struct clocksource *cs)
59
 
{
60
 
        return ~((__raw_readl(REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1)
61
 
                                & 0xFFFF0000) >> 16);
62
 
}
63
 
 
64
 
static int
65
 
stmp3xxx_timrot_set_next_event(unsigned long delta,
66
 
                struct clock_event_device *dev)
67
 
{
68
 
        /* reload the timer */
69
 
        __raw_writel(delta, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
70
 
        return 0;
71
 
}
72
 
 
73
 
static void
74
 
stmp3xxx_timrot_set_mode(enum clock_event_mode mode,
75
 
                struct clock_event_device *dev)
76
 
{
77
 
}
78
 
 
79
 
static struct clock_event_device ckevt_timrot = {
80
 
        .name           = "timrot",
81
 
        .features       = CLOCK_EVT_FEAT_ONESHOT,
82
 
        .shift          = 32,
83
 
        .set_next_event = stmp3xxx_timrot_set_next_event,
84
 
        .set_mode       = stmp3xxx_timrot_set_mode,
85
 
};
86
 
 
87
 
static struct clocksource cksrc_stmp3xxx = {
88
 
        .name           = "cksrc_stmp3xxx",
89
 
        .rating         = 250,
90
 
        .read           = stmp3xxx_clock_read,
91
 
        .mask           = CLOCKSOURCE_MASK(16),
92
 
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
93
 
};
94
 
 
95
 
static struct irqaction stmp3xxx_timer_irq = {
96
 
        .name           = "stmp3xxx_timer",
97
 
        .flags          = IRQF_DISABLED | IRQF_TIMER,
98
 
        .handler        = stmp3xxx_timer_interrupt,
99
 
        .dev_id         = &ckevt_timrot,
100
 
};
101
 
 
102
 
 
103
 
/*
104
 
 * Set up timer interrupt, and return the current time in seconds.
105
 
 */
106
 
static void __init stmp3xxx_init_timer(void)
107
 
{
108
 
        ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
109
 
                                ckevt_timrot.shift);
110
 
        ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot);
111
 
        ckevt_timrot.max_delta_ns = clockevent_delta2ns(0xFFF, &ckevt_timrot);
112
 
        ckevt_timrot.cpumask = cpumask_of(0);
113
 
 
114
 
        stmp3xxx_reset_block(REGS_TIMROT_BASE, false);
115
 
 
116
 
        /* clear two timers */
117
 
        __raw_writel(0, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
118
 
        __raw_writel(0, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
119
 
 
120
 
        /* configure them */
121
 
        __raw_writel(
122
 
                (8 << BP_TIMROT_TIMCTRLn_SELECT) |  /* 32 kHz */
123
 
                BM_TIMROT_TIMCTRLn_RELOAD |
124
 
                BM_TIMROT_TIMCTRLn_UPDATE |
125
 
                BM_TIMROT_TIMCTRLn_IRQ_EN,
126
 
                        REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
127
 
        __raw_writel(
128
 
                (8 << BP_TIMROT_TIMCTRLn_SELECT) |  /* 32 kHz */
129
 
                BM_TIMROT_TIMCTRLn_RELOAD |
130
 
                BM_TIMROT_TIMCTRLn_UPDATE |
131
 
                BM_TIMROT_TIMCTRLn_IRQ_EN,
132
 
                        REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
133
 
 
134
 
        __raw_writel(CLOCK_TICK_RATE / HZ - 1,
135
 
                        REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
136
 
        __raw_writel(0xFFFF, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
137
 
 
138
 
        setup_irq(IRQ_TIMER0, &stmp3xxx_timer_irq);
139
 
 
140
 
        clocksource_register_hz(&cksrc_stmp3xxx, CLOCK_TICK_RATE);
141
 
        clockevents_register_device(&ckevt_timrot);
142
 
}
143
 
 
144
 
#ifdef CONFIG_PM
145
 
 
146
 
void stmp3xxx_suspend_timer(void)
147
 
{
148
 
        stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ_EN | BM_TIMROT_TIMCTRLn_IRQ,
149
 
                        REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
150
 
        stmp3xxx_setl(BM_TIMROT_ROTCTRL_CLKGATE,
151
 
                        REGS_TIMROT_BASE + HW_TIMROT_ROTCTRL);
152
 
}
153
 
 
154
 
void stmp3xxx_resume_timer(void)
155
 
{
156
 
        stmp3xxx_clearl(BM_TIMROT_ROTCTRL_SFTRST | BM_TIMROT_ROTCTRL_CLKGATE,
157
 
                        REGS_TIMROT_BASE + HW_TIMROT_ROTCTRL);
158
 
        __raw_writel(
159
 
                8 << BP_TIMROT_TIMCTRLn_SELECT |  /* 32 kHz */
160
 
                BM_TIMROT_TIMCTRLn_RELOAD |
161
 
                BM_TIMROT_TIMCTRLn_UPDATE |
162
 
                BM_TIMROT_TIMCTRLn_IRQ_EN,
163
 
                        REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
164
 
        __raw_writel(
165
 
                8 << BP_TIMROT_TIMCTRLn_SELECT |  /* 32 kHz */
166
 
                BM_TIMROT_TIMCTRLn_RELOAD |
167
 
                BM_TIMROT_TIMCTRLn_UPDATE |
168
 
                BM_TIMROT_TIMCTRLn_IRQ_EN,
169
 
                        REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
170
 
        __raw_writel(CLOCK_TICK_RATE / HZ - 1,
171
 
                        REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
172
 
        __raw_writel(0xFFFF, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
173
 
}
174
 
 
175
 
#else
176
 
 
177
 
#define stmp3xxx_suspend_timer  NULL
178
 
#define stmp3xxx_resume_timer   NULL
179
 
 
180
 
#endif  /* CONFIG_PM */
181
 
 
182
 
struct sys_timer stmp3xxx_timer = {
183
 
        .init           = stmp3xxx_init_timer,
184
 
        .suspend        = stmp3xxx_suspend_timer,
185
 
        .resume         = stmp3xxx_resume_timer,
186
 
};