~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to arch/arm/mach-armadaxp/time.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <asm/localtimer.h>
24
24
#include <asm/sched_clock.h>
25
25
 
26
 
 
27
26
#include <linux/clk.h>
28
27
#include <linux/clockchips.h>
29
28
#include <linux/delay.h>
34
33
#include "cpu/mvCpu.h"
35
34
 
36
35
#ifdef CONFIG_SMP
37
 
static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
 
36
static struct clock_event_device __percpu ** axp_local_clockevent;
38
37
#endif
39
38
 
40
39
extern void axp_irq_mask(struct irq_data *d);
158
157
{
159
158
        unsigned long flags;
160
159
        u32 u;
161
 
 
162
160
        local_irq_save(flags);
163
161
 
164
162
        if (mode == CLOCK_EVT_MODE_PERIODIC) {
212
210
static struct irqaction axp_timer_irq = {
213
211
        .name           = "axp_tick",
214
212
        .flags          = IRQF_DISABLED | IRQF_TIMER,
215
 
        .handler        = axp_timer_interrupt
 
213
        .handler        = axp_timer_interrupt,
 
214
        .dev_id         = &axp_clkevt,
216
215
};
217
216
 
218
217
 
299
298
/*
300
299
 * Used on SMP for either the local timer or IPI_TIMER
301
300
 */
302
 
void local_timer_interrupt(void)
 
301
/*void local_timer_interrupt(void)
303
302
{
304
 
        struct clock_event_device *clk = &__get_cpu_var(local_clockevent);
 
303
        struct clock_event_device *clk = &__get_cpu_var(axp_local_clockevent);
305
304
 
306
 
        printk("local_timer_interrupt\n");
307
305
        clk->event_handler(clk);
308
306
}
 
307
*/
309
308
 
310
309
/*
311
310
 * local_timer_ack: checks for a local timer interrupt.
313
312
 * If a local timer interrupt has occurred, acknowledge and return 1.
314
313
 * Otherwise, return 0.
315
314
 */
 
315
 
316
316
int local_timer_ack(void)
317
317
{
318
318
        if(MV_REG_READ(LCL_TIMER_CAUSE) & ~LCL_INT_TIMER0_CLR) {
322
322
        return 0;
323
323
}
324
324
 
 
325
static irqreturn_t axp_localtimer_handler(int irq, void *dev_id)
 
326
{
 
327
 
 
328
        struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
 
329
        if (local_timer_ack()) {
 
330
                evt->event_handler(evt);
 
331
                return IRQ_HANDLED;
 
332
        }
 
333
 
 
334
        return IRQ_NONE;
 
335
}
 
336
 
325
337
/*
326
338
 * Setup the local clock events for a CPU.
327
339
 */
328
 
int __cpuinit local_timer_setup(struct clock_event_device *clk)
 
340
 __cpuinit local_timer_setup(struct clock_event_device *clk)
329
341
{
330
342
#if !defined (CONFIG_ARMADA_XP_REV_Z1) || defined (CONFIG_MACH_ARMADA_XP_FPGA)
331
343
        /* FPGA hardcoded to 25Mhz and in DSMP-A0 the referance clock for the timers is 25MHz */
335
347
#endif
336
348
        static cpu0_flag=0;
337
349
        int cpu = smp_processor_id(); 
 
350
        struct clock_event_device **this_cpu_clk;
 
351
 
 
352
 
 
353
        if (!axp_local_clockevent) {
 
354
                int err;
 
355
 
 
356
                axp_local_clockevent = alloc_percpu(struct clock_event_device *);
 
357
                if (!axp_local_clockevent) {
 
358
                        pr_err("axp_local_clockevent: can't allocate memory\n");
 
359
                        return 0;
 
360
                }
 
361
                err = request_percpu_irq(IRQ_LOCALTIMER, axp_localtimer_handler,
 
362
                                "axp_local_clockevent", axp_local_clockevent);
 
363
                if (err) {
 
364
                        pr_err("axp_local_clockevent: can't register interrupt %d (%d)\n",
 
365
                               IRQ_LOCALTIMER, err);
 
366
                        return 0;
 
367
                }
 
368
        }
338
369
 
339
370
        if((cpu) || (!cpu && !cpu0_flag)){
340
371
                ticks_per_jiffy = (fabric_clk + HZ/2) / HZ;
341
372
                clk->name = "local_timer";
342
373
                clk->irq = IRQ_LOCALTIMER;
343
374
                mv_timer_setup(clk, fabric_clk);
 
375
 
 
376
                this_cpu_clk = __this_cpu_ptr(axp_local_clockevent);
 
377
                *this_cpu_clk = clk;
344
378
                clockevents_register_device(clk);
345
379
         if(!cpu)
346
380
                cpu0_flag++;
347
381
        }
 
382
        enable_percpu_irq(clk->irq, 0);
348
383
        return 0;
349
384
}
350
385
 
352
387
/*
353
388
 * take a local timer down
354
389
 */
355
 
void __cpuexit local_timer_stop(void)
 
390
void  __cpuexit local_timer_stop(struct clock_event_device * evt)
356
391
{
357
392
        unsigned long flags;
358
393
        u32 u;
359
 
 
360
394
        local_irq_save(flags);
361
395
 
362
396
        /* Disable timer */