Changing to handle_ir_level make the system boot a bit further, but
still locks.

In the ns921x_timer_init function there is a  call to to
clocksource_register(&ns921x_clocksource) and it is configured (timer 0)
in enabled mode REGSET(tc, SYS_TCx, TE, EN), up counter, 32 bits
autoreload, so I think this is the clocksource. I attach full
time-ns921x.c (I hope I haven't missed anything).

Added lines in hal.h
#elif defined(CONFIG_MACH_CC9P9215JS)
#define RTHAL_TIMER_DEVICE      "ns921x-timer" __stringify(TIMER_CLOCKEVENT)
#define RTHAL_CLOCK_DEVICE      "ns921x-timer" __stringify(TIMER_CLOCKSOURCE)


Thanks again.
-----------------------------------------------------------------
/*
 * arch/arm/mach-ns9xxx/time-ns921x.c
 *
 * Copyright (C) 2007 by Digi International Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
it
 * under the terms of the GNU General Public License version 2 as
published by
 * the Free Software Foundation.
 */
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/stringify.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>

#include <mach/regs-sys-ns921x.h>
#include <mach/irqs.h>

#include "irq.h"
#include "processor-ns921x.h"

#define TIMER_CLOCKSOURCE 0
#define TIMER_CLOCKEVENT 1

static u32 latch;

#ifdef CONFIG_IPIPE
#ifdef CONFIG_NO_IDLE_HZ
#error "dynamic tick timer not yet supported with IPIPE"
#endif                          /* CONFIG_NO_IDLE_HZ */
int __ipipe_mach_timerint = IRQ_NS921X_TIMER0 + TIMER_CLOCKEVENT;
EXPORT_SYMBOL(__ipipe_mach_timerint);

int __ipipe_mach_timerstolen = 0;
EXPORT_SYMBOL(__ipipe_mach_timerstolen);

unsigned int __ipipe_mach_ticks_per_jiffy = LATCH;
EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy);

static int ns921x_timer_initialized;
union tsc_reg {
#ifdef __BIG_ENDIAN
        struct {
                unsigned long high;
                unsigned long low;
        };
#else                           /* __LITTLE_ENDIAN */
        struct {
                unsigned long low;
                unsigned long high;
        };
#endif                          /* __LITTLE_ENDIAN */
        unsigned long long full;
};

static union tsc_reg *tsc;

void __ipipe_mach_get_tscinfo(struct __ipipe_tscinfo *info)
{
        info->type = IPIPE_TSC_TYPE_FREERUNNING;
        info->u.fr.counter = (unsigned *)SYS_TRC(TIMER_CLOCKSOURCE);
        info->u.fr.mask = 0xffffffff;
        info->u.fr.tsc = &tsc->full;
}


static void ipipe_mach_update_tsc(void);

#endif                          /* CONFIG_IPIPE */



static cycle_t ns921x_clocksource_read(void)
{
        return __raw_readl(SYS_TRC(TIMER_CLOCKSOURCE));
}

static struct clocksource ns921x_clocksource = {
        .name   = "ns921x-timer" __stringify(TIMER_CLOCKSOURCE),
        .rating = 300,
        .read   = ns921x_clocksource_read,
        .mask   = CLOCKSOURCE_MASK(32),
        .shift  = 20,
        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
};

static void ns921x_clockevent_setmode(enum clock_event_mode mode,
                struct clock_event_device *clk)
{
        u32 oldtc, tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
        oldtc = tc;

        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
                __raw_writel(latch, SYS_TRCC(TIMER_CLOCKEVENT));
                REGSET(tc, SYS_TCx, RELENBL, EN);
                REGSET(tc, SYS_TCx, INTSEL, EN);
                REGSET(tc, SYS_TCx, TE, EN);
                //printk("ns921x_clockevent_setmode CLOCK_EVT_MODE_PERIODIC\n");
                break;

        case CLOCK_EVT_MODE_ONESHOT:
                REGSET(tc, SYS_TCx, RELENBL, DIS);
                REGSET(tc, SYS_TCx, INTSEL, EN);
                REGSET(tc, SYS_TCx, TE, DIS);
                //printk("ns921x_clockevent_setmode CLOCK_EVT_MODE_ONESHOT\n");
                break;

        case CLOCK_EVT_MODE_UNUSED:
        case CLOCK_EVT_MODE_SHUTDOWN:
        default:
                REGSET(tc, SYS_TCx, TE, DIS);
                //printk("ns921x_clockevent_setmode default\n");
                break;
        }

        /* ack an possibly pending irq
         * This might stuck the irq priority encoder, but only until the next
         * timer irq ... */
        if (REGGET(tc, SYS_TCx, TE) == SYS_TCx_TE_DIS &&
                        REGGET(oldtc, SYS_TCx, TE) == SYS_TCx_TE_EN) {
                REGSETIM(tc, SYS_TCx, INTCLR, 1);
                __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
                REGSETIM(tc, SYS_TCx, INTCLR, 0);
        }

        __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
}

static int ns921x_clockevent_setnextevent(unsigned long evt,
                struct clock_event_device *clk)
{
        u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));

        if (REGGET(tc, SYS_TCx, TE)) {
                REGSET(tc, SYS_TCx, TE, DIS);
                __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
        }

        REGSET(tc, SYS_TCx, TE, EN);

        __raw_writel(evt, SYS_TRCC(TIMER_CLOCKEVENT));

        __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));

        return 0;
}


static struct clock_event_device ns921x_clockevent_device = {
        .name           = "ns921x-timer" __stringify(TIMER_CLOCKEVENT),
        .shift          = 20,
        .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
        .set_mode       = ns921x_clockevent_setmode,
        .set_next_event = ns921x_clockevent_setnextevent,
};

#ifdef CONFIG_IPIPE
int __ipipe_check_tickdev(const char *devname)
{
        return !strcmp(devname, ns921x_clockevent_device.name);
        //printk("__ipipe_check_tickdev devname: %s\n", devname);
}
#endif /* CONFIG_IPIPE */

static irqreturn_t ns921x_clockevent_handler(int irq, void *dev_id)
{
        struct clock_event_device *evt = &ns921x_clockevent_device;
        //struct clock_event_device *evt = dev_id;
#ifndef CONFIG_IPIPE
        int timerno = irq - IRQ_NS921X_TIMER0;
        u32 tc;

        /* clear irq */
        tc = __raw_readl(SYS_TC(timerno));
        if (REGGET(tc, SYS_TCx, RELENBL) == SYS_TCx_RELENBL_DIS) {
                REGSET(tc, SYS_TCx, TE, DIS);
                __raw_writel(tc, SYS_TC(timerno));
        }
        REGSETIM(tc, SYS_TCx, INTCLR, 1);
        __raw_writel(tc, SYS_TC(timerno));
        REGSETIM(tc, SYS_TCx, INTCLR, 0);
        __raw_writel(tc, SYS_TC(timerno));

#else /* CONFIG_IPIPE */
        ipipe_mach_update_tsc();
#endif /* CONFIG_IPIPE */
        evt->event_handler(evt);
        //printk("ns921x_clockevent_handler irq: %d\n", irq);
        //printk("ns921x_clockevent_handler __ipipe_mach_timerstolen: %d\n",
__ipipe_mach_timerstolen);
        //printk("ns921x_clockevent_handler __ipipe_mach_ticks_per_jiffy: %d
\n", __ipipe_mach_ticks_per_jiffy);
        //printk("ns921x_clockevent_handler __ipipe_mach_timerint: %d\n",
__ipipe_mach_timerint);
        //printk("ns921x_clockevent_handler ns921x_clockevent_device.mode: %d
\n", evt->mode);
        return  IRQ_HANDLED;
}

static struct irqaction ns921x_clockevent_action = {
        .name           = "ns921x-timer" __stringify(TIMER_CLOCKEVENT),
        .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = ns921x_clockevent_handler,
};

static void __init ns921x_timer_init(void)
{
        int tc;

        tc = __raw_readl(SYS_TC(TIMER_CLOCKSOURCE));
        if (REGGET(tc, SYS_TCx, TE)) {
                REGSET(tc, SYS_TCx, TE, DIS);
                __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));
        }

        __raw_writel(0, SYS_TRC(TIMER_CLOCKSOURCE));

        REGSET(tc, SYS_TCx, TE, EN);
        REGSET(tc, SYS_TCx, DEBUG, STOP);
        REGSET(tc, SYS_TCx, TCS, 2AHB);
        REGSET(tc, SYS_TCx, MODE, INTERNAL);
        REGSET(tc, SYS_TCx, INTSEL, DIS);
        REGSET(tc, SYS_TCx, UPDOWN, UP);
        REGSET(tc, SYS_TCx, BITTIMER, 32);
        REGSET(tc, SYS_TCx, RELENBL, EN);

        __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));

        ns921x_clocksource.mult = clocksource_hz2mult(ns921x_ahbclock() * 2,
                        ns921x_clocksource.shift);

        clocksource_register(&ns921x_clocksource);

        latch = SH_DIV(ns921x_ahbclock() * 2, HZ, 0);
        //__ipipe_mach_ticks_per_jiffy = latch;
        //latch = LATCH;

        tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
        REGSET(tc, SYS_TCx, TE, DIS);
        REGSET(tc, SYS_TCx, DEBUG, STOP);
        REGSET(tc, SYS_TCx, TCS, 2AHB);
        REGSET(tc, SYS_TCx, MODE, INTERNAL);
        REGSET(tc, SYS_TCx, INTSEL, DIS);
        REGSET(tc, SYS_TCx, UPDOWN, DOWN);
        REGSET(tc, SYS_TCx, BITTIMER, 32);
        REGSET(tc, SYS_TCx, RELENBL, EN);
        __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));

        ns921x_clockevent_device.mult = div_sc(ns921x_ahbclock() * 2,
                        NSEC_PER_SEC, ns921x_clockevent_device.shift);
        ns921x_clockevent_device.max_delta_ns =
                clockevent_delta2ns(-1, &ns921x_clockevent_device);
        ns921x_clockevent_device.min_delta_ns =
                clockevent_delta2ns(1, &ns921x_clockevent_device);

        ns921x_clockevent_device.cpumask = cpumask_of_cpu(0);
        clockevents_register_device(&ns921x_clockevent_device);

#ifdef CONFIG_IPIPE
        tsc = (union tsc_reg *)__ipipe_tsc_area;
        barrier();
        ns921x_timer_initialized = 1;
#endif          

        setup_irq(IRQ_NS921X_TIMER0 + TIMER_CLOCKEVENT,
                        &ns921x_clockevent_action);
}

struct sys_timer ns921x_timer = {
        .init = ns921x_timer_init,
};

#ifdef CONFIG_IPIPE
void __ipipe_mach_acktimer(void)
{
        int timerno = IRQ_NS921X_TIMER1 - IRQ_NS921X_TIMER0;
        u32 tc;
        tc = __raw_readl(SYS_TC(timerno));
        if (REGGET(tc, SYS_TCx, RELENBL) == SYS_TCx_RELENBL_DIS) {
                REGSET(tc, SYS_TCx, TE, DIS);
                __raw_writel(tc, SYS_TC(timerno));
        }

        REGSETIM(tc, SYS_TCx, INTCLR, 1);
        __raw_writel(tc, SYS_TC(timerno));
        REGSETIM(tc, SYS_TCx, INTCLR, 0);
        __raw_writel(tc, SYS_TC(timerno));
        //printk("__ipipe_mach_acktimer INTCLR: %d\n", REGGET(tc, SYS_TCx,
INTCLR) );
        //printk("__ipipe_mach_acktimer timerno: %d\n", timerno );
}

static void ipipe_mach_update_tsc(void)
{
        union tsc_reg *local_tsc;
        unsigned long stamp, flags;

        local_irq_save_hw(flags);
        local_tsc = &tsc[ipipe_processor_id()];
        stamp = __raw_readl(SYS_TRC(TIMER_CLOCKSOURCE));
        if (unlikely(stamp < local_tsc->low))
                /* 32 bit counter wrapped, increment high word. */
                local_tsc->high++;
        local_tsc->low = stamp;
        local_irq_restore_hw(flags);
        //printk("ipipe_mach_update_tsc stamp: %ld\n", stamp );
}

notrace unsigned long long __ipipe_mach_get_tsc(void)
{
        if (likely(ns921x_timer_initialized)) {
                union tsc_reg *local_tsc, result;
                unsigned long stamp;

                local_tsc = &tsc[ipipe_processor_id()];

                __asm__("ldmia %1, %M0\n":
                        "=r"(result.full): "r"(local_tsc), "m"(*local_tsc));
                barrier();
                stamp = __raw_readl(SYS_TRC(TIMER_CLOCKSOURCE));
                if (unlikely(stamp < result.low))
                        result.high++;
                result.low = stamp;
                //printk("__ipipe_mach_get_tsc stamp: %ld\n", stamp );
                return result.full;
        }
        return 0;
}

EXPORT_SYMBOL(__ipipe_mach_get_tsc);

/*
 * Reprogram the timer
 */
void __ipipe_mach_set_dec(unsigned long delay)
{
        unsigned long flags;
        if (delay > 8) {
                u32 tc;
                local_irq_save_hw(flags);
                tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));

                if (REGGET(tc, SYS_TCx, TE)) {
                        REGSET(tc, SYS_TCx, TE, DIS);
                        __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
                }
        
                REGSET(tc, SYS_TCx, TE, EN);
        
                __raw_writel(delay, SYS_TRCC(TIMER_CLOCKEVENT));

                __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
                local_irq_restore_hw(flags);
        } else
                ipipe_trigger_irq(IRQ_NS921X_TIMER0 + TIMER_CLOCKEVENT);
        //printk("__ipipe_mach_set_dec delay: %ld\n", delay );
}

EXPORT_SYMBOL(__ipipe_mach_set_dec);

void __ipipe_mach_release_timer(void)
{
        //__ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy);
        ns921x_clockevent_setmode(ns921x_clockevent_device.mode,
&ns921x_clockevent_device);
        if (ns921x_clockevent_device.mode == CLOCK_EVT_MODE_ONESHOT)
                ns921x_clockevent_setnextevent(LATCH,
&ns921x_clockevent_device);
        //printk("__ipipe_mach_release_timer\n" );
}

EXPORT_SYMBOL(__ipipe_mach_release_timer);

unsigned long __ipipe_mach_get_dec(void)
{
        return __raw_readl(SYS_TRC(TIMER_CLOCKSOURCE));
}
#endif                          /* CONFIG_IPIPE */

/* We have no cascaded interrupts. */
void __ipipe_mach_demux_irq(unsigned irq, struct pt_regs *regs) {}




------------------------------------------------------------------------
Boot log (still no nfs packets):

Uncompressing
Linux...................................................................................
 done, booting the kernel.
[    0.000000] Linux version 2.6.28.10 (ia...@iames-laptop) (gcc version
4.3.2 (GCC) ) #96 Fri Jul 2 13:01:19 CEST 2010
[    0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ),
cr=00053177
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] Machine: ConnectCore 9P 9215 on a JSCC9P9215 Devboard
[    0.000000] Memory policy: ECC disabled, Data cache writeback
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.
Total pages: 8128
[    0.000000] Kernel command line:
ip=192.168.1.55:192.168.1.21:192.168.1.1:255.255.255.0:cc9p9215js:eth0:off 
console=ttyNS3,38400 root=nfs 
nfsroot=192.168.1.21:/exports/nfsroot-cc9p9215js/exports/nfsroot-cc9p9215js 
mtdparts=physmap-flash.0:0x40000(U-Boot),0x40...@0x40000(NVRAM),0x180...@0x80000(Kernel),0xe00...@0x200000(RootFS-JFFS2)
[    0.000000] PID hash table entries: 128 (order: 7, 512 bytes)
[42949372.960000] I-pipe 1.12-07: pipeline enabled.
[42949372.960000] Dentry cache hash table entries: 4096 (order: 2, 16384
bytes)
[42949372.970000] Inode-cache hash table entries: 2048 (order: 1, 8192
bytes)
[42949373.130000] Memory: 32MB = 32MB total
[42949373.130000] Memory: 29760KB available (2348K code, 227K data, 104K
init)
[42949373.170000] Calibrating delay loop... 4.92 BogoMIPS (lpj=24640)
[42949373.390000] Mount-cache hash table entries: 512
[42949373.460000] CPU: Testing write buffer coherency: ok
[42949373.710000] net_namespace: 288 bytes
[42949373.750000] NET: Registered protocol family 16
[42949376.170000] NET: Registered protocol family 2
[42949376.280000] IP route cache hash table entries: 1024 (order: 0,
4096 bytes)
[42949376.330000] TCP established hash table entries: 1024 (order: 1,
8192 bytes)
[42949376.340000] TCP bind hash table entries: 1024 (order: 0, 4096
bytes)
[42949376.340000] TCP: Hash tables configured (established 1024 bind
1024)
[42949376.340000] TCP reno registered
[42949376.400000] NET: Registered protocol family 1
[42949376.670000] I-pipe: Domain Xenomai registered.
[42949376.670000] Xenomai: hal/arm started.

[42949376.680000] Xenomai: scheduling class idle registered.
[42949376.680000] Xenomai: scheduling class rt registered.

[42949377.980000] Xenomai: real-time nucleus v2.5.3 (Hordes Of Locusts)
loaded.
[42949378.530000] Xenomai: native skin init failed, code -38.
[42949378.530000] Xenomai: starting POSIX services.
[42949379.070000] Xenomai: POSIX skin init failed, code -38.
[42949379.610000] Xenomai: RTDM skin init failed, code -38.
[42949379.800000] JFFS2 version 2.2. (NAND) (SUMMARY)  © 2001-2006 Red
Hat, Inc.
[42949379.860000] msgmni has been set to 58
[42949379.870000] io scheduler noop registered (default)
[42949380.020000] adc-ns9215: ADC available on MAJOR 254
[42949380.060000] ns921x-serial.1: ttyNS1 at MMIO 0x90018000 (irq = 8)
is a NS921X
[42949380.110000] ns921x-serial.2: ttyNS2 at MMIO 0x90020000 (irq = 9)
is a NS921X
[42949380.160000] ns921x-serial.3: ttyNS3 at MMIO 0x90028000 (irq = 10)
is a NS921X
[42949380.160000] console [ttyNS3] enabled
[42949380.250000] Digi NS921x UART driver
[42949381.660000] brd: module loaded
[42949381.790000] ns9xxx-eth-mii: probed
[42949381.890000] ns9xxx-eth ns9xxx-eth: eth0 at MMIO c2928000
[42949381.930000] Digi NS9XXX Ethernet driver
[42949381.990000] physmap platform flash device: 10000000 at 50000000
[42949382.340000] physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit
bank
[42949382.400000]  Amd/Fujitsu Extended Query Table at 0x0040
[42949382.420000] physmap-flash.0: CFI does not contain boot bank
location. Assuming top.
[42949382.430000] number of CFI chips: 1
[42949382.440000] cfi_cmdset_0002: Disabling erase-suspend-program due
to code brokenness.
[42949382.460000] 4 cmdlinepart partitions found on MTD device
physmap-flash.0
[42949382.470000] Creating 4 MTD partitions on "physmap-flash.0":
[42949382.490000] 0x00000000-0x00040000 : "U-Boot"
[42949382.680000] 0x00040000-0x00080000 : "NVRAM"
[42949382.830000] 0x00080000-0x00200000 : "Kernel"
[42949382.970000] 0x00200000-0x01000000 : "RootFS-JFFS2"
[42949383.170000] spi_ns921x spi_ns921x.1: NS921x SPI controller at
0xc2960000 (irq: 11)
[42949383.250000] TCP cubic registered
[42949383.260000] NET: Registered protocol family 17

[42949383.320000] RPC: Registered udp transport module.
[42949383.330000] RPC: Registered tcp transport module.
[42949383.680000] IP-Config: Complete:
[42949383.690000]      device=eth0, addr=192.168.1.55,
mask=255.255.255.0, gw=192.168.1.1,
[42949383.750000]      host=cc9p9215js, domain=, nis-domain=(none),
[42949383.760000]      bootserver=192.168.1.21, rootserver=192.168.1.21,
rootpath=
[42949383.830000] Looking up port of RPC 100003/2 on 192.168.1.21
[42949383.870000] net eth0: link up (100/full)
[42949383.900000] Looking up port of RPC 100005/1 on 192.168.1.21



-- 
Iker Amescua


El vie, 02-07-2010 a las 12:59 +0200, Gilles Chanteperdrix escribió:
> Iker Amescua wrote:
> > Thanks a lot!
> > 
> > Now at least it boots. This is what I have done (I expect correctly):
> > 
> > IRQ are now handled by 
> > #ifndef CONFIG_IPIPE
> >             set_irq_handler(i, handle_prio_irq);
> > #else
> >             set_irq_handler(i, handle_edge_irq);
> > #endif /*CONFIG_IPIPE*/
> > 
> > And in irqs.h
> > #define irq_finish(irq) irq_desc[irq].chip->eoi(irq);
> > 
> > Is this correct?
> > 
> > The problem now it locks up during boot. This is the console output:
> 
> Ok. Try handle_level_irq instead of handle_edge_irq, if your irq
> controller is well-behaved enough, it should work.
> 
> > What are these errors?
> > [42949376.490000] Xenomai: hal/arm started.
> > [42949376.490000] Xenomai: scheduling class idle registered.
> > [42949376.500000] Xenomai: scheduling class rt registered.
> > [42949377.740000] Xenomai: real-time nucleus v2.5.3 (Hordes Of Locusts)
> > loaded.
> > [42949378.290000] Xenomai: native skin init failed, code -38.
> > [42949378.290000] Xenomai: starting POSIX services.
> > [42949378.830000] Xenomai: POSIX skin init failed, code -38.
> > [42949379.370000] Xenomai: RTDM skin init failed, code -38.
> 
> Probably something wrong with the timer initialization. Are you sure the
> kernel uses the clock you think it uses? One reason may be that the
> timer you are requesting is in the CLOCK_EVT_MODE_SHUTDOWN state,
> meaning that it is not used by the kernel. Also, I see no trace
> indicating that the Linux kernel uses your clock source. You should see
> something like:
> 
> Switching to clocksource foo
> 
> in the kernel sources, unless you have not implemented a clock source?
> 


_______________________________________________
Adeos-main mailing list
[email protected]
https://mail.gna.org/listinfo/adeos-main

Reply via email to