Changeset ce76b9d2 in rtems


Ignore:
Timestamp:
May 8, 2017, 12:58:41 PM (3 years ago)
Author:
Daniel Hellstrom <daniel@…>
Branches:
master
Children:
f767fe7
Parents:
8670c464
git-author:
Daniel Hellstrom <daniel@…> (05/08/17 12:58:41)
git-committer:
Daniel Hellstrom <daniel@…> (05/14/17 10:31:59)
Message:

leon, pci-peripherals: SMP support by spin-locks and updated genirq

Location:
c/src/lib/libbsp/sparc/shared/pci
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/shared/pci/gr_701.c

    r8670c464 rce76b9d2  
    2424#include <bsp.h>
    2525#include <rtems/bspIo.h>
     26#include <rtems/score/isrlock.h> /* spin-lock */
    2627#include <pci.h>
    2728#include <pci/access.h>
     
    3738
    3839#include <bsp/gr_701.h>
     40
     41/* map via rtems_interrupt_lock_* API: */
     42#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     43#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     44#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     45#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     46#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     47#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     48#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     49#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    3950
    4051/* Offset from 0x80000000 (dual bus version) */
     
    8899struct gr701_priv {
    89100        /* Driver management */
    90         struct drvmgr_dev       *dev;
     101        struct drvmgr_dev               *dev;
    91102        char                            prefix[16];
     103        SPIN_DECLARE(devlock);
    92104
    93105        struct pci_bridge_regs          *pcib;
     
    201213        unsigned int status;
    202214        int irq = 0;
    203 
     215        SPIN_ISR_IRQFLAGS(irqflags);
     216
     217        SPIN_LOCK(&priv->devlock, irqflags);
    204218        while ( (status=priv->pcib->istatus) != 0 ) {
    205219                priv->interrupt_cnt++;  /* An interrupt was generated */
     
    209223                priv->pcib->istatus = 0;
    210224        }
     225        SPIN_UNLOCK(&priv->devlock, irqflags);
    211226
    212227        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
     
    348363                return DRVMGR_ENORES;
    349364
     365        /* Initialize spin-lock for this PCI perihperal device. This is to
     366         * protect the Interrupt Controller Registers. The genirq layer is
     367         * protecting its own internals and ISR dispatching.
     368         */
     369        SPIN_INIT(&priv->devlock, priv->prefix);
     370
    350371        priv->genirq = genirq_init(16);
    351372        if ( priv->genirq == NULL ) {
     
    411432{
    412433        struct gr701_priv *priv = dev->parent->dev->priv;
    413         rtems_interrupt_level level;
     434        SPIN_IRQFLAGS(irqflags);
    414435        int status;
    415 
    416         rtems_interrupt_disable(level);
    417 
    418         status = genirq_register(priv->genirq, irq, handler, arg);
     436        void *h;
     437
     438        h = genirq_alloc_handler(handler, arg);
     439        if ( h == NULL )
     440                return DRVMGR_FAIL;
     441
     442        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
     443
     444        status = genirq_register(priv->genirq, irq, h);
    419445        if ( status == 0 ) {
    420446                /* Clear IRQ for first registered handler */
     
    424450
    425451        if (status != 0) {
    426                 rtems_interrupt_enable(level);
     452                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     453                genirq_free_handler(h);
    427454                return DRVMGR_FAIL;
    428455        }
     
    435462                status = DRVMGR_OK;
    436463
    437         rtems_interrupt_enable(level);
     464        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    438465
    439466        return status;
     
    447474{
    448475        struct gr701_priv *priv = dev->parent->dev->priv;
    449         rtems_interrupt_level level;
     476        SPIN_IRQFLAGS(irqflags);
    450477        int status;
    451 
    452         rtems_interrupt_disable(level);
     478        void *handler;
     479
     480        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    453481
    454482        status = genirq_disable(priv->genirq, irq, isr, arg);
     
    458486        }
    459487
    460         status = genirq_unregister(priv->genirq, irq, isr, arg);
    461         if ( status != 0 )
     488        handler = genirq_unregister(priv->genirq, irq, isr, arg);
     489        if ( handler == NULL )
    462490                status = DRVMGR_FAIL;
    463 
    464         rtems_interrupt_enable(level);
     491        else
     492                status = DRVMGR_OK;
     493
     494        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     495
     496        if (handler)
     497                genirq_free_handler(handler);
    465498
    466499        return status;
     
    472505{
    473506        struct gr701_priv *priv = dev->parent->dev->priv;
    474         rtems_interrupt_level level;
     507        SPIN_IRQFLAGS(irqflags);
    475508
    476509        DBG("GR-701 IRQ %d: enable\n", irq);
     
    479512                return DRVMGR_FAIL;
    480513
    481         rtems_interrupt_disable(level);
     514        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    482515
    483516        /* Enable IRQ */
    484517        priv->pcib->imask |= (1<<irq); /* unmask interrupt source */
    485518
    486         rtems_interrupt_enable(level);
     519        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    487520
    488521        return DRVMGR_OK;
     
    494527{
    495528        struct gr701_priv *priv = dev->parent->dev->priv;
    496         rtems_interrupt_level level;
     529        SPIN_IRQFLAGS(irqflags);
    497530
    498531        DBG("GR-701 IRQ %d: disable\n", irq);
     
    501534                return DRVMGR_FAIL;
    502535
    503         rtems_interrupt_disable(level);
     536        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    504537
    505538        /* Disable IRQ */
    506539        priv->pcib->imask &= ~(1<<irq); /* mask interrupt source */
    507540
    508         rtems_interrupt_enable(level);
     541        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    509542
    510543        return DRVMGR_OK;
  • c/src/lib/libbsp/sparc/shared/pci/gr_cpci_gr740.c

    r8670c464 rce76b9d2  
    3434#include <bsp.h>
    3535#include <rtems/bspIo.h>
     36#include <rtems/score/isrlock.h> /* spin-lock */
    3637#include <pci.h>
    3738
     
    4546
    4647#include <bsp/gr_cpci_gr740.h>
     48
     49/* map via rtems_interrupt_lock_* API: */
     50#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     51#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     52#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     53#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     54#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     55#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     56#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     57#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    4758
    4859/* Determines which PCI address the AHB masters on the GR740 board will
     
    99110        /* Driver management */
    100111        struct drvmgr_dev       *dev;
    101         char                    prefix[20];
     112        char                    prefix[16];
     113        SPIN_DECLARE(devlock);
    102114
    103115        /* PCI */
     
    214226        unsigned int status, tmp;
    215227        int irq, eirq;
     228        SPIN_ISR_IRQFLAGS(irqflags);
     229
    216230        tmp = status = priv->irq->ipend;
    217231
    218232        /* DBG("GR-CPCI-GR740: IRQ 0x%x\n",status); */
    219233
     234        SPIN_LOCK(&priv->devlock, irqflags);
    220235        for(irq = 0; irq < 32; irq++) {
    221236                if (status & (1 << irq)) {
     
    236251                }
    237252        }
     253        SPIN_UNLOCK(&priv->devlock, irqflags);
    238254
    239255        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller
     
    462478        /* Generate Device prefix */
    463479
    464         strcpy(priv->prefix, "/dev/gr7400");
    465         priv->prefix[10] += dev->minor_drv;
     480        strcpy(priv->prefix, "/dev/gr740_0");
     481        priv->prefix[11] += dev->minor_drv;
    466482        mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
    467         priv->prefix[11] = '/';
    468         priv->prefix[12] = '\0';
     483        priv->prefix[12] = '/';
     484        priv->prefix[13] = '\0';
    469485
    470486        priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
     
    486502        printf(" IRQ: %d\n\n\n", devinfo->irq);
    487503
     504        /* Initialize spin-lock for this PCI perihperal device. This is to
     505         * protect the Interrupt Controller Registers. The genirq layer is
     506         * protecting its own internals and ISR dispatching.
     507         */
     508        SPIN_INIT(&priv->devlock, priv->prefix);
     509
    488510        /* Let user override which PCI address the AHB masters of the
    489511         * GR740 board access when doing DMA to HOST RAM. The AHB masters
     
    577599{
    578600        struct gr_cpci_gr740_priv *priv = dev->parent->dev->priv;
    579         rtems_interrupt_level level;
     601        SPIN_IRQFLAGS(irqflags);
    580602        int status;
    581 
    582         rtems_interrupt_disable(level);
    583 
    584         status = genirq_register(priv->genirq, irq, handler, arg);
     603        void *h;
     604
     605        h = genirq_alloc_handler(handler, arg);
     606        if ( h == NULL )
     607                return DRVMGR_FAIL;
     608
     609        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
     610
     611        status = genirq_register(priv->genirq, irq, h);
    585612        if (status == 0) {
    586613                /* Clear IRQ for first registered handler */
     
    590617
    591618        if (status != 0) {
    592                 rtems_interrupt_enable(level);
     619                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     620                genirq_free_handler(h);
    593621                return DRVMGR_FAIL;
    594622        }
     
    601629                status = 0;
    602630
    603         rtems_interrupt_enable(level);
     631        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    604632
    605633        return status;
     
    613641{
    614642        struct gr_cpci_gr740_priv *priv = dev->parent->dev->priv;
    615         rtems_interrupt_level level;
     643        SPIN_IRQFLAGS(irqflags);
    616644        int status;
    617 
    618         rtems_interrupt_disable(level);
     645        void *handler;
     646
     647        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    619648
    620649        status = genirq_disable(priv->genirq, irq, isr, arg);
     
    624653        }
    625654
    626         status = genirq_unregister(priv->genirq, irq, isr, arg);
    627         if ( status != 0 )
     655        handler = genirq_unregister(priv->genirq, irq, isr, arg);
     656        if ( handler == NULL )
    628657                status = DRVMGR_FAIL;
    629 
    630         rtems_interrupt_enable(level);
     658        else
     659                status = DRVMGR_OK;
     660
     661        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     662
     663        if (handler)
     664                genirq_free_handler(handler);
    631665
    632666        return status;
     
    638672{
    639673        struct gr_cpci_gr740_priv *priv = dev->parent->dev->priv;
    640         rtems_interrupt_level level;
     674        SPIN_IRQFLAGS(irqflags);
    641675
    642676        DBG("GR740 IRQ %d: unmask\n", irq);
     
    645679                return DRVMGR_EINVAL;
    646680
    647         rtems_interrupt_disable(level);
     681        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    648682
    649683        /* Enable IRQ for first enabled handler only */
    650684        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
    651685
    652         rtems_interrupt_enable(level);
     686        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    653687
    654688        return DRVMGR_OK;
     
    660694{
    661695        struct gr_cpci_gr740_priv *priv = dev->parent->dev->priv;
    662         rtems_interrupt_level level;
     696        SPIN_IRQFLAGS(irqflags);
    663697
    664698        DBG("GR740 IRQ %d: mask\n", irq);
     
    667701                return DRVMGR_EINVAL;
    668702
    669         rtems_interrupt_disable(level);
     703        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    670704
    671705        /* Disable/mask IRQ */
    672706        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
    673707
    674         rtems_interrupt_enable(level);
     708        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    675709
    676710        return DRVMGR_OK;
  • c/src/lib/libbsp/sparc/shared/pci/gr_leon4_n2x.c

    r8670c464 rce76b9d2  
    3333#include <bsp.h>
    3434#include <rtems/bspIo.h>
     35#include <rtems/score/isrlock.h> /* spin-lock */
    3536#include <pci.h>
    3637
     
    4445
    4546#include <bsp/gr_leon4_n2x.h>
     47
     48/* map via rtems_interrupt_lock_* API: */
     49#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     50#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     51#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     52#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     53#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     54#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     55#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     56#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    4657
    4758/* Determines which PCI address the AHB masters on the LEON-N2X board will
     
    99110        struct drvmgr_dev       *dev;
    100111        char                    prefix[20];
     112        SPIN_DECLARE(devlock);
    101113
    102114        /* PCI */
     
    214226        unsigned int status, tmp;
    215227        int irq, eirq;
     228        SPIN_ISR_IRQFLAGS(irqflags);
     229
    216230        tmp = status = priv->irq->ipend;
    217231
    218232        /* DBG("GR-CPCI-LEON4-N2X: IRQ 0x%x\n",status); */
    219233
     234        SPIN_LOCK(&priv->devlock, irqflags);
    220235        for(irq = 0; irq < 32; irq++) {
    221236                if (status & (1 << irq)) {
     
    236251                }
    237252        }
     253        SPIN_UNLOCK(&priv->devlock, irqflags);
    238254
    239255        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller
     
    509525        printf(" IRQ: %d\n\n\n", devinfo->irq);
    510526
     527        /* Initialize spin-lock for this PCI perihperal device. This is to
     528         * protect the Interrupt Controller Registers. The genirq layer is
     529         * protecting its own internals and ISR dispatching.
     530         */
     531        SPIN_INIT(&priv->devlock, priv->prefix);
     532
    511533        /* Let user override which PCI address the AHB masters of the
    512534         * LEON4-N2X board access when doing DMA to HOST RAM. The AHB masters
     
    600622{
    601623        struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
    602         rtems_interrupt_level level;
     624        SPIN_IRQFLAGS(irqflags);
    603625        int status;
    604 
    605         rtems_interrupt_disable(level);
    606 
    607         status = genirq_register(priv->genirq, irq, handler, arg);
     626        void *h;
     627
     628        h = genirq_alloc_handler(handler, arg);
     629        if ( h == NULL )
     630                return DRVMGR_FAIL;
     631
     632        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
     633
     634        status = genirq_register(priv->genirq, irq, h);
    608635        if (status == 0) {
    609636                /* Clear IRQ for first registered handler */
     
    613640
    614641        if (status != 0) {
    615                 rtems_interrupt_enable(level);
     642                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     643                genirq_free_handler(h);
    616644                return DRVMGR_FAIL;
    617645        }
     
    624652                status = 0;
    625653
    626         rtems_interrupt_enable(level);
     654        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    627655
    628656        return status;
     
    636664{
    637665        struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
    638         rtems_interrupt_level level;
     666        SPIN_IRQFLAGS(irqflags);
    639667        int status;
    640 
    641         rtems_interrupt_disable(level);
     668        void *handler;
     669
     670        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    642671
    643672        status = genirq_disable(priv->genirq, irq, isr, arg);
     
    647676        }
    648677
    649         status = genirq_unregister(priv->genirq, irq, isr, arg);
    650         if ( status != 0 )
     678        handler = genirq_unregister(priv->genirq, irq, isr, arg);
     679        if ( handler == NULL )
    651680                status = DRVMGR_FAIL;
    652 
    653         rtems_interrupt_enable(level);
     681        else
     682                status = DRVMGR_OK;
     683
     684        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     685
     686        if (handler)
     687                genirq_free_handler(handler);
    654688
    655689        return status;
     
    661695{
    662696        struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
    663         rtems_interrupt_level level;
     697        SPIN_IRQFLAGS(irqflags);
    664698
    665699        DBG("LEON4-N2X IRQ %d: unmask\n", irq);
     
    668702                return DRVMGR_EINVAL;
    669703
    670         rtems_interrupt_disable(level);
     704        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    671705
    672706        /* Enable IRQ for first enabled handler only */
    673707        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
    674708
    675         rtems_interrupt_enable(level);
     709        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    676710
    677711        return DRVMGR_OK;
     
    683717{
    684718        struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
    685         rtems_interrupt_level level;
     719        SPIN_IRQFLAGS(irqflags);
    686720
    687721        DBG("LEON4-N2X IRQ %d: mask\n", irq);
     
    690724                return DRVMGR_EINVAL;
    691725
    692         rtems_interrupt_disable(level);
     726        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    693727
    694728        /* Disable/mask IRQ */
    695729        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
    696730
    697         rtems_interrupt_enable(level);
     731        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    698732
    699733        return DRVMGR_OK;
  • c/src/lib/libbsp/sparc/shared/pci/gr_rasta_adcdac.c

    r8670c464 rce76b9d2  
    2424#include <bsp.h>
    2525#include <rtems/bspIo.h>
     26#include <rtems/score/isrlock.h> /* spin-lock */
    2627#include <pci.h>
    2728
     
    3536
    3637#include <bsp/gr_rasta_adcdac.h>
     38
     39/* map via rtems_interrupt_lock_* API: */
     40#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     41#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     42#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     43#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     44#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     45#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     46#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     47#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    3748
    3849/*#define DEBUG 1*/
     
    7788struct gr_rasta_adcdac_priv {
    7889        /* Driver management */
    79         struct drvmgr_dev       *dev;
     90        struct drvmgr_dev               *dev;
    8091        char                            prefix[20];
     92        SPIN_DECLARE(devlock);
    8193
    8294        /* PCI */
     
    194206        unsigned int status, tmp;
    195207        int irq;
     208        SPIN_ISR_IRQFLAGS(irqflags);
     209
    196210        tmp = status = priv->irq->ipend;
    197211
    198212        /* DBG("GR-RASTA-ADCDAC: IRQ 0x%x\n",status); */
    199213
     214        SPIN_LOCK(&priv->devlock, irqflags);
    200215        for(irq=0; irq<16; irq++) {
    201216                if ( status & (1<<irq) ) {
     
    207222                }
    208223        }
     224        SPIN_UNLOCK(&priv->devlock, irqflags);
    209225
    210226        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
     
    411427        if ((bar0_size == 0) || (bar1_size == 0))
    412428                return DRVMGR_ENORES;
     429
     430        /* Initialize spin-lock for this PCI perihperal device. This is to
     431         * protect the Interrupt Controller Registers. The genirq layer is
     432         * protecting its own internals and ISR dispatching.
     433         */
     434        SPIN_INIT(&priv->devlock, priv->prefix);
    413435
    414436        /* Let user override which PCI address the AHB masters of the
     
    489511{
    490512        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
    491         rtems_interrupt_level level;
     513        SPIN_IRQFLAGS(irqflags);
    492514        int status;
    493 
    494         rtems_interrupt_disable(level);
    495 
    496         status = genirq_register(priv->genirq, irq, handler, arg);
     515        void *h;
     516
     517        h = genirq_alloc_handler(handler, arg);
     518        if ( h == NULL )
     519                return DRVMGR_FAIL;
     520
     521        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
     522
     523        status = genirq_register(priv->genirq, irq, h);
    497524        if ( status == 0 ) {
    498525                /* Clear IRQ for first registered handler */
     
    502529
    503530        if (status != 0) {
    504                 rtems_interrupt_enable(level);
     531                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     532                genirq_free_handler(h);
    505533                return DRVMGR_FAIL;
    506534        }
     
    513541                status = 0;
    514542
    515         rtems_interrupt_enable(level);
     543        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    516544
    517545        return status;
     
    525553{
    526554        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
    527         rtems_interrupt_level level;
     555        SPIN_IRQFLAGS(irqflags);
    528556        int status;
    529 
    530         rtems_interrupt_disable(level);
     557        void *handler;
     558
     559        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    531560
    532561        status = genirq_disable(priv->genirq, irq, isr, arg);
     
    536565        }
    537566
    538         status = genirq_unregister(priv->genirq, irq, isr, arg);
    539         if ( status != 0 )
     567        handler = genirq_unregister(priv->genirq, irq, isr, arg);
     568        if ( handler == NULL )
    540569                status = DRVMGR_FAIL;
    541 
    542         rtems_interrupt_enable(level);
     570        else
     571                status = DRVMGR_OK;
     572
     573        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     574
     575        if (handler)
     576                genirq_free_handler(handler);
    543577
    544578        return status;
     
    550584{
    551585        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
    552         rtems_interrupt_level level;
     586        SPIN_IRQFLAGS(irqflags);
    553587
    554588        DBG("RASTA-ADCDAC IRQ %d: unmask\n", irq);
     
    557591                return DRVMGR_EINVAL;
    558592
    559         rtems_interrupt_disable(level);
     593        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    560594
    561595        /* Enable IRQ for first enabled handler only */
    562596        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
    563597
    564         rtems_interrupt_enable(level);
     598        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    565599
    566600        return DRVMGR_OK;
     
    572606{
    573607        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
    574         rtems_interrupt_level level;
     608        SPIN_IRQFLAGS(irqflags);
    575609
    576610        DBG("RASTA-ADCDAC IRQ %d: mask\n", irq);
     
    579613                return DRVMGR_EINVAL;
    580614
    581         rtems_interrupt_disable(level);
     615        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    582616
    583617        /* Disable/mask IRQ */
    584618        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
    585619
    586         rtems_interrupt_enable(level);
     620        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    587621
    588622        return DRVMGR_OK;
  • c/src/lib/libbsp/sparc/shared/pci/gr_rasta_io.c

    r8670c464 rce76b9d2  
    2424#include <bsp.h>
    2525#include <rtems/bspIo.h>
     26#include <rtems/score/isrlock.h> /* spin-lock */
    2627#include <pci.h>
    2728
     
    3536
    3637#include <bsp/gr_rasta_io.h>
     38
     39/* map via rtems_interrupt_lock_* API: */
     40#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     41#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     42#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     43#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     44#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     45#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     46#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     47#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    3748
    3849/* Determines which PCI address the AHB masters will access, it should be
     
    109120struct gr_rasta_io_priv {
    110121        /* Driver management */
    111         struct drvmgr_dev       *dev;
     122        struct drvmgr_dev               *dev;
    112123        char                            prefix[16];
     124        SPIN_DECLARE(devlock);
    113125
    114126        /* PCI */
     
    234246        unsigned int status, tmp;
    235247        int irq;
     248        SPIN_ISR_IRQFLAGS(irqflags);
     249
    236250        tmp = status = priv->irq->ipend;
    237251
    238252        /* DBG("GR-RASTA-IO: IRQ 0x%x\n",status); */
    239253
     254        SPIN_LOCK(&priv->devlock, irqflags);
    240255        for(irq=0; irq<16; irq++) {
    241256                if ( status & (1<<irq) ) {
     
    247262                }
    248263        }
     264        SPIN_UNLOCK(&priv->devlock, irqflags);
    249265
    250266        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
     
    590606        if ((bar0_size == 0) || (bar1_size == 0))
    591607                return DRVMGR_ENORES;
     608
     609        /* Initialize spin-lock for this PCI peripheral device. This is to
     610         * protect the Interrupt Controller Registers. The genirq layer is
     611         * protecting its own internals and ISR dispatching.
     612         */
     613        SPIN_INIT(&priv->devlock, priv->prefix);
    592614
    593615        /* Let user override which PCI address the AHB masters of the
     
    686708{
    687709        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
    688         rtems_interrupt_level level;
     710        SPIN_IRQFLAGS(irqflags);
    689711        int status;
    690 
    691         rtems_interrupt_disable(level);
    692 
    693         status = genirq_register(priv->genirq, irq, handler, arg);
     712        void *h;
     713
     714        h = genirq_alloc_handler(handler, arg);
     715        if ( h == NULL )
     716                return DRVMGR_FAIL;
     717
     718        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
     719
     720        status = genirq_register(priv->genirq, irq, h);
    694721        if ( status == 0 ) {
    695722                /* Clear IRQ for first registered handler */
     
    699726
    700727        if (status != 0) {
    701                 rtems_interrupt_enable(level);
     728                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     729                genirq_free_handler(h);
    702730                return DRVMGR_FAIL;
    703731        }
     
    710738                status = 0;
    711739
    712         rtems_interrupt_enable(level);
     740        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    713741
    714742        return status;
     
    722750{
    723751        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
    724         rtems_interrupt_level level;
     752        SPIN_IRQFLAGS(irqflags);
    725753        int status;
    726 
    727         rtems_interrupt_disable(level);
     754        void *handler;
     755
     756        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    728757
    729758        status = genirq_disable(priv->genirq, irq, isr, arg);
     
    733762        }
    734763
    735         status = genirq_unregister(priv->genirq, irq, isr, arg);
    736         if ( status != 0 )
     764        handler = genirq_unregister(priv->genirq, irq, isr, arg);
     765        if ( handler == NULL )
    737766                status = DRVMGR_FAIL;
    738 
    739         rtems_interrupt_enable(level);
     767        else
     768                status = DRVMGR_OK;
     769
     770        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     771
     772        if (handler)
     773                genirq_free_handler(handler);
    740774
    741775        return status;
     
    747781{
    748782        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
    749         rtems_interrupt_level level;
     783        SPIN_IRQFLAGS(irqflags);
    750784
    751785        DBG("RASTA-IO IRQ %d: unmask\n", irq);
     
    754788                return DRVMGR_EINVAL;
    755789
    756         rtems_interrupt_disable(level);
     790        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    757791
    758792        /* Enable IRQ for first enabled handler only */
    759793        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
    760794
    761         rtems_interrupt_enable(level);
     795        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    762796
    763797        return DRVMGR_OK;
     
    769803{
    770804        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
    771         rtems_interrupt_level level;
     805        SPIN_IRQFLAGS(irqflags);
    772806
    773807        DBG("RASTA-IO IRQ %d: mask\n", irq);
     
    776810                return DRVMGR_EINVAL;
    777811
    778         rtems_interrupt_disable(level);
     812        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    779813
    780814        /* Disable/mask IRQ */
    781815        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
    782816
    783         rtems_interrupt_enable(level);
     817        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    784818
    785819        return DRVMGR_OK;
  • c/src/lib/libbsp/sparc/shared/pci/gr_rasta_spw_router.c

    r8670c464 rce76b9d2  
    2222#include <bsp.h>
    2323#include <rtems/bspIo.h>
     24#include <rtems/score/isrlock.h> /* spin-lock */
    2425#include <pci.h>
    2526
     
    3233#include <bsp/genirq.h>
    3334#include <bsp/gr_rasta_spw_router.h>
     35
     36/* map via rtems_interrupt_lock_* API: */
     37#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     38#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     39#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     40#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     41#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     42#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     43#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     44#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    3445
    3546/* Determines which PCI address the AHB masters will access, it should be
     
    94105        struct drvmgr_dev       *dev;
    95106        char                    prefix[20];
     107        SPIN_DECLARE(devlock);
    96108
    97109        /* PCI */
     
    210222        unsigned int status, tmp;
    211223        int irq;
     224        SPIN_ISR_IRQFLAGS(irqflags);
     225
    212226        tmp = status = priv->irq->ipend;
    213227
    214228        /* DBG("GR-RASTA-SPW-ROUTER: IRQ 0x%x\n",status); */
    215229
     230        SPIN_LOCK(&priv->devlock, irqflags);
    216231        for(irq=0; irq<16; irq++) {
    217232                if ( status & (1<<irq) ) {
     
    223238                }
    224239        }
     240        SPIN_UNLOCK(&priv->devlock, irqflags);
    225241
    226242        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller
     
    423439        if (bar0_size == 0)
    424440                return DRVMGR_ENORES;
     441
     442        /* Initialize spin-lock for this PCI peripheral device. This is to
     443         * protect the Interrupt Controller Registers. The genirq layer is
     444         * protecting its own internals and ISR dispatching.
     445         */
     446        SPIN_INIT(&priv->devlock, priv->prefix);
    425447
    426448        /* Let user override which PCI address the AHB masters of the
     
    496518{
    497519        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
    498         rtems_interrupt_level level;
     520        SPIN_IRQFLAGS(irqflags);
    499521        int status;
    500 
    501         rtems_interrupt_disable(level);
    502 
    503         status = genirq_register(priv->genirq, irq, handler, arg);
     522        void *h;
     523
     524        h = genirq_alloc_handler(handler, arg);
     525        if ( h == NULL )
     526                return DRVMGR_FAIL;
     527
     528        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
     529
     530        status = genirq_register(priv->genirq, irq, h);
    504531        if (status == 0) {
    505532                /* Clear IRQ for first registered handler */
     
    509536
    510537        if (status != 0) {
    511                 rtems_interrupt_enable(level);
     538                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     539                genirq_free_handler(h);
    512540                return DRVMGR_FAIL;
    513541        }
     
    520548                status = 0;
    521549
    522         rtems_interrupt_enable(level);
     550        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    523551
    524552        return status;
     
    532560{
    533561        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
    534         rtems_interrupt_level level;
     562        SPIN_IRQFLAGS(irqflags);
    535563        int status;
    536 
    537         rtems_interrupt_disable(level);
     564        void *handler;
     565
     566        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    538567
    539568        status = genirq_disable(priv->genirq, irq, isr, arg);
     
    543572        }
    544573
    545         status = genirq_unregister(priv->genirq, irq, isr, arg);
    546         if ( status != 0 )
     574        handler = genirq_unregister(priv->genirq, irq, isr, arg);
     575        if ( handler == NULL )
    547576                status = DRVMGR_FAIL;
    548 
    549         rtems_interrupt_enable(level);
     577        else
     578                status = DRVMGR_OK;
     579
     580        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     581
     582        if (handler)
     583                genirq_free_handler(handler);
    550584
    551585        return status;
     
    557591{
    558592        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
    559         rtems_interrupt_level level;
     593        SPIN_IRQFLAGS(irqflags);
    560594
    561595        DBG("RASTA-SPW-ROUTER IRQ %d: unmask\n", irq);
     
    564598                return DRVMGR_EINVAL;
    565599
    566         rtems_interrupt_disable(level);
     600        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    567601
    568602        /* Enable IRQ for first enabled handler only */
    569603        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
    570604
    571         rtems_interrupt_enable(level);
     605        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    572606
    573607        return DRVMGR_OK;
     
    579613{
    580614        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
    581         rtems_interrupt_level level;
     615        SPIN_IRQFLAGS(irqflags);
    582616
    583617        DBG("RASTA-SPW-ROUTER IRQ %d: mask\n", irq);
     
    586620                return DRVMGR_EINVAL;
    587621
    588         rtems_interrupt_disable(level);
     622        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    589623
    590624        /* Disable/mask IRQ */
    591625        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
    592626
    593         rtems_interrupt_enable(level);
     627        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    594628
    595629        return DRVMGR_OK;
  • c/src/lib/libbsp/sparc/shared/pci/gr_rasta_tmtc.c

    r8670c464 rce76b9d2  
    2424#include <bsp.h>
    2525#include <rtems/bspIo.h>
     26#include <rtems/score/isrlock.h> /* spin-lock */
    2627#include <pci.h>
    2728
     
    3536
    3637#include <bsp/gr_rasta_tmtc.h>
     38
     39/* map via rtems_interrupt_lock_* API: */
     40#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     41#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     42#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     43#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     44#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     45#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     46#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     47#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    3748
    3849/* Determines which PCI address the AHB masters will access, it should be
     
    105116struct gr_rasta_tmtc_priv {
    106117        /* Driver management */
    107         struct drvmgr_dev       *dev;
     118        struct drvmgr_dev               *dev;
    108119        char                            prefix[20];
     120        SPIN_DECLARE(devlock);
    109121
    110122        /* PCI */
     
    225237        unsigned int status, tmp;
    226238        int irq;
     239        SPIN_ISR_IRQFLAGS(irqflags);
     240
    227241        tmp = status = priv->irq->ipend;
    228242
    229243        /* printk("GR-RASTA-TMTC: IRQ 0x%x\n",status); */
    230244
     245        SPIN_LOCK(&priv->devlock, irqflags);
    231246        for(irq=0; irq<32; irq++) {
    232247                if ( status & (1<<irq) ) {
     
    238253                }
    239254        }
     255        SPIN_UNLOCK(&priv->devlock, irqflags);
    240256
    241257        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
     
    602618        if ((bar0_size == 0) || (bar1_size == 0))
    603619                return DRVMGR_ENORES;
     620
     621        /* Initialize spin-lock for this PCI peripheral device. This is to
     622         * protect the Interrupt Controller Registers. The genirq layer is
     623         * protecting its own internals and ISR dispatching.
     624         */
     625        SPIN_INIT(&priv->devlock, priv->prefix);
    604626
    605627        /* Let user override which PCI address the AHB masters of the
     
    690712{
    691713        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
    692         rtems_interrupt_level level;
     714        SPIN_IRQFLAGS(irqflags);
    693715        int status;
    694 
    695         rtems_interrupt_disable(level);
    696 
    697         status = genirq_register(priv->genirq, irq, handler, arg);
     716        void *h;
     717
     718        h = genirq_alloc_handler(handler, arg);
     719        if ( h == NULL )
     720                return DRVMGR_FAIL;
     721
     722        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
     723
     724        status = genirq_register(priv->genirq, irq, h);
    698725        if ( status == 0 ) {
    699726                /* Disable and clear IRQ for first registered handler */
     
    703730
    704731        if (status != 0) {
    705                 rtems_interrupt_enable(level);
     732                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     733                genirq_free_handler(h);
    706734                return DRVMGR_FAIL;
    707735        }
     
    714742                status = 0;
    715743
    716         rtems_interrupt_enable(level);
     744        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    717745
    718746        return status;
     
    726754{
    727755        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
    728         rtems_interrupt_level level;
     756        SPIN_IRQFLAGS(irqflags);
    729757        int status;
    730 
    731         rtems_interrupt_disable(level);
     758        void *handler;
     759
     760        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    732761
    733762        status = genirq_disable(priv->genirq, irq, isr, arg);
     
    738767                status = 0;
    739768
    740         status = genirq_unregister(priv->genirq, irq, isr, arg);
    741         if ( status != 0 )
     769        handler = genirq_unregister(priv->genirq, irq, isr, arg);
     770        if ( handler == NULL )
    742771                status = DRVMGR_FAIL;
    743 
    744         rtems_interrupt_enable(level);
     772        else
     773                status = DRVMGR_OK;
     774
     775        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     776
     777        if (handler)
     778                genirq_free_handler(handler);
    745779
    746780        return status;
     
    752786{
    753787        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
    754         rtems_interrupt_level level;
     788        SPIN_IRQFLAGS(irqflags);
    755789
    756790        DBG("RASTA-TMTC IRQ %d: unmask\n", irq);
     
    759793                return DRVMGR_EINVAL;
    760794
    761         rtems_interrupt_disable(level);
     795        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    762796
    763797        /* Enable IRQ */
    764798        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
    765799
    766         rtems_interrupt_enable(level);
     800        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    767801
    768802        return DRVMGR_OK;
     
    774808{
    775809        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
    776         rtems_interrupt_level level;
     810        SPIN_IRQFLAGS(irqflags);
    777811
    778812        DBG("RASTA-TMTC IRQ %d: mask\n", irq);
     
    781815                return DRVMGR_EINVAL;
    782816
    783         rtems_interrupt_disable(level);
     817        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    784818
    785819        /* Disable IRQ */
    786820        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
    787821
    788         rtems_interrupt_enable(level);
     822        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    789823
    790824        return DRVMGR_OK;
  • c/src/lib/libbsp/sparc/shared/pci/gr_tmtc_1553.c

    r8670c464 rce76b9d2  
    2424#include <bsp.h>
    2525#include <rtems/bspIo.h>
     26#include <rtems/score/isrlock.h> /* spin-lock */
    2627#include <pci.h>
    2728#include <pci/access.h>
     
    3738#include <bsp/gr_tmtc_1553.h>
    3839
     40/* map via rtems_interrupt_lock_* API: */
     41#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     42#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     43#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     44#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     45#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     46#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     47#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     48#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
    3949
    4050/*#define DEBUG 1 */
     
    6171struct gr_tmtc_1553_priv {
    6272        /* Driver management */
    63         struct drvmgr_dev       *dev;
     73        struct drvmgr_dev               *dev;
    6474        char                            prefix[32];
     75        SPIN_DECLARE(devlock);
    6576
    6677        /* PCI */
     
    175186        unsigned int status, tmp;
    176187        int irq;
     188        SPIN_ISR_IRQFLAGS(irqflags);
     189
    177190        tmp = status = priv->irq->ipend;
    178191
    179192        /* DBG("GR-RASTA-IO: IRQ 0x%x\n",status); */
    180193
     194        SPIN_LOCK(&priv->devlock, irqflags);
    181195        for(irq=0; irq<16; irq++) {
    182196                if ( status & (1<<irq) ) {
     
    188202                }
    189203        }
     204        SPIN_UNLOCK(&priv->devlock, irqflags);
    190205
    191206        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
     
    307322        /* Generate Device prefix */
    308323
    309         strcpy(priv->prefix, "/dev/tmtc1553_0/");
    310         priv->prefix[19] += dev->minor_drv;
     324        strcpy(priv->prefix, "/dev/tmtc1553_0");
     325        priv->prefix[14] += dev->minor_drv;
    311326        mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
    312         priv->prefix[20] = '/';
    313         priv->prefix[21] = '\0';
     327        priv->prefix[15] = '/';
     328        priv->prefix[16] = '\0';
    314329
    315330        priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
     
    328343        if (bar0_size == 0)
    329344                return DRVMGR_ENORES;
     345
     346        /* Initialize spin-lock for this PCI peripheral device. This is to
     347         * protect the Interrupt Controller Registers. The genirq layer is
     348         * protecting its own internals and ISR dispatching.
     349         */
     350        SPIN_INIT(&priv->devlock, priv->prefix);
    330351
    331352        priv->genirq = genirq_init(16);
     
    395416{
    396417        struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
    397         rtems_interrupt_level level;
     418        SPIN_IRQFLAGS(irqflags);
    398419        int status;
    399 
    400         rtems_interrupt_disable(level);
    401 
    402         status = genirq_register(priv->genirq, irq, handler, arg);
     420        void *h;
     421
     422        h = genirq_alloc_handler(handler, arg);
     423        if ( h == NULL )
     424                return DRVMGR_FAIL;
     425
     426        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
     427
     428        status = genirq_register(priv->genirq, irq, h);
    403429        if ( status == 0 ) {
    404430                /* Disable and clear IRQ for first registered handler */
     
    409435
    410436        if (status != 0) {
    411                 rtems_interrupt_enable(level);
     437                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     438                genirq_free_handler(h);
    412439                return DRVMGR_FAIL;
    413440        }
     
    420447                status = 0;
    421448
    422         rtems_interrupt_enable(level);
     449        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    423450
    424451        return status;
     
    432459{
    433460        struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
    434         rtems_interrupt_level level;
     461        SPIN_IRQFLAGS(irqflags);
    435462        int status;
    436 
    437         rtems_interrupt_disable(level);
     463        void *handler;
     464
     465        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    438466
    439467        status = genirq_disable(priv->genirq, irq, isr, arg);
     
    444472                status = 0;
    445473
    446         status = genirq_unregister(priv->genirq, irq, isr, arg);
    447         if ( status != 0 )
     474        handler = genirq_unregister(priv->genirq, irq, isr, arg);
     475        if ( handler == NULL )
    448476                status = DRVMGR_FAIL;
    449 
    450         rtems_interrupt_enable(level);
     477        else
     478                status = DRVMGR_OK;
     479
     480        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     481
     482        if (handler)
     483                genirq_free_handler(handler);
    451484
    452485        return status;
     
    458491{
    459492        struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
    460         rtems_interrupt_level level;
     493        SPIN_IRQFLAGS(irqflags);
    461494
    462495        DBG("TMTC-1553 IRQ %d: enable\n", irq);
     
    465498                return DRVMGR_FAIL;
    466499
    467         rtems_interrupt_disable(level);
     500        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    468501
    469502        /* Enable IRQ */
    470503        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
    471504
    472         rtems_interrupt_enable(level);
     505        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    473506
    474507        return DRVMGR_OK;
     
    480513{
    481514        struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
    482         rtems_interrupt_level level;
     515        SPIN_IRQFLAGS(irqflags);
    483516
    484517        DBG("TMTC-1553 IRQ %d: disable\n", irq);
     
    487520                return DRVMGR_FAIL;
    488521
    489         rtems_interrupt_disable(level);
     522        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    490523
    491524        /* Disable IRQ */
    492525        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
    493526
    494         rtems_interrupt_enable(level);
     527        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    495528
    496529        return DRVMGR_OK;
Note: See TracChangeset for help on using the changeset viewer.