Changeset c609ccea in rtems


Ignore:
Timestamp:
Jan 19, 2017, 5:57:58 PM (4 years ago)
Author:
Martin Aberg <maberg@…>
Branches:
5, master
Children:
a8595605
Parents:
c241236
git-author:
Martin Aberg <maberg@…> (01/19/17 17:57:58)
git-committer:
Daniel Hellstrom <daniel@…> (05/02/17 10:34:48)
Message:

leon, ahbstat: Use RTEMS 4.12 SMP interrupt lock

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/shared/amba/ahbstat.c

    rc241236 rc609ccea  
    11/*  AHB Status register driver
    22 *
    3  *  COPYRIGHT (c) 2009.
     3 *  COPYRIGHT (c) 2009 - 2017.
    44 *  Cobham Gaisler AB.
    55 *
     
    1010
    1111#include <stdint.h>
     12#include <rtems.h>
     13#include <rtems/bspIo.h>
    1214#include <drvmgr/drvmgr.h>
    1315#include <drvmgr/ambapp_bus.h>
    1416
    1517#include <bsp/ahbstat.h>
    16 #include <rtems/bspIo.h>
     18
     19#define SPIN_IRQ_DECLARE(name)          RTEMS_INTERRUPT_LOCK_DECLARE(, name)
     20#define SPIN_IRQ_INIT(lock, name)       rtems_interrupt_lock_initialize(lock, name)
     21#define SPIN_IRQ_LOCK(lock, ctx)        rtems_interrupt_lock_acquire(lock, &(ctx))
     22#define SPIN_IRQ_UNLOCK(lock, ctx)      rtems_interrupt_lock_release(lock, &(ctx))
     23#define SPIN_IRQ_LOCK_ISR(lock, ctx)    rtems_interrupt_lock_acquire_isr(lock, &(ctx))
     24#define SPIN_IRQ_UNLOCK_ISR(lock, ctx)  rtems_interrupt_lock_release_isr(lock, &(ctx))
     25#define SPIN_IRQ_CTX                    rtems_interrupt_lock_context
     26
     27#define REG_WRITE(addr, val) (*(volatile uint32_t *)(addr) = (uint32_t)(val))
     28#define REG_READ(addr) (*(volatile uint32_t *)(addr))
    1729
    1830void ahbstat_isr(void *arg);
     
    5264#define AHBSTAT_STS_HS (0x7 << AHBSTAT_STS_HS_BIT)
    5365
     66enum { DEVNAME_LEN = 9 };
    5467struct ahbstat_priv {
    5568        struct drvmgr_dev *dev;
    5669        struct ahbstat_regs *regs;
     70        char devname[DEVNAME_LEN];
    5771        int minor;
     72        /* Cached error */
    5873        uint32_t last_status;
    5974        uint32_t last_address;
     75        /* Spin-lock ISR protection */
     76        SPIN_IRQ_DECLARE(devlock);
    6077};
    6178
     
    114131        priv->minor = dev->minor_drv;
    115132
     133        strncpy(&priv->devname[0], "ahbstat0", DEVNAME_LEN);
     134        priv->devname[7] += priv->minor;
     135        /*
     136         * Initialize spinlock for AHBSTAT Device. It is used to protect user
     137         * API calls involivng priv structure from updates in ISR.
     138         */
     139        SPIN_IRQ_INIT(&priv->devlock, priv->devname);
     140
    116141        /* Initialize hardware */
    117         priv->regs->status = 0;
     142        REG_WRITE(&priv->regs->status, 0);
    118143
    119144        /* Install IRQ handler */
    120         drvmgr_interrupt_register(dev, 0, "ahbstat", ahbstat_isr, priv);
     145        drvmgr_interrupt_register(dev, 0, priv->devname, ahbstat_isr, priv);
    121146
    122147        return DRVMGR_OK;
     
    128153        uint32_t fadr, status;
    129154        int rc;
     155        SPIN_IRQ_CTX lock_context;
    130156
    131157        /* Get hardware status */
    132         status = priv->regs->status;
     158        status = REG_READ(&priv->regs->status);
    133159        if ((status & AHBSTAT_STS_NE) == 0)
    134160                return;
     
    137163
    138164        /* Get Failing address */
    139         fadr = priv->regs->failing;
    140 
     165        fadr = REG_READ(&priv->regs->failing);
     166
     167        SPIN_IRQ_LOCK_ISR(&priv->devlock, lock_context);
    141168        priv->last_status = status;
    142169        priv->last_address = fadr;
     170        SPIN_IRQ_UNLOCK_ISR(&priv->devlock, lock_context);
    143171
    144172        /* Let user handle error, default to print the error and reenable HW
     
    147175         *  0: print error and reenable AHBSTAT
    148176         *  1: just reenable AHBSTAT
    149          *  2: just print error reenable
     177         *  2: just print error
    150178         *  3: do nothing
    151179         */
     
    155183
    156184        if ((rc & 0x1) == 0) {
    157                 printk("\n### AHBSTAT: %s %s error of size %lu by master %ld"
     185                printk("\n### AHBSTAT: %s %s error of size %ld by master %ld"
    158186                        " at 0x%08lx\n",
    159187                        status & AHBSTAT_STS_CE ? "single" : "non-correctable",
    160188                        status & AHBSTAT_STS_HW ? "write" : "read",
    161                         (status & AHBSTAT_STS_HS) >> AHBSTAT_STS_HS_BIT,
    162                         (status & AHBSTAT_STS_HM) >> AHBSTAT_STS_HM_BIT,
     189                        (int) (status & AHBSTAT_STS_HS) >> AHBSTAT_STS_HS_BIT,
     190                        (int) (status & AHBSTAT_STS_HM) >> AHBSTAT_STS_HM_BIT,
    163191                        fadr);
    164192        }
     
    166194        if ((rc & 0x2) == 0) {
    167195                /* Trigger new interrupts */
    168                 priv->regs->status = 0;
     196                REG_WRITE(&priv->regs->status, 0);
    169197        }
    170198}
     
    181209        struct drvmgr_dev *dev;
    182210        struct ahbstat_priv *priv;
     211        uint32_t last_status;
     212        uint32_t last_address;
     213        SPIN_IRQ_CTX lock_context;
    183214
    184215        if (drvmgr_get_dev(&ahbstat_drv_info.general, minor, &dev)) {
     
    187218        priv = (struct ahbstat_priv *)dev->priv;
    188219
    189         *status = priv->last_status;
    190         *address = priv->last_address;
    191 
    192         return (priv->last_status & AHBSTAT_STS_NE) >> AHBSTAT_STS_NE_BIT;
     220        /* Read information cached by ISR */
     221        SPIN_IRQ_LOCK(&priv->devlock, lock_context);
     222        last_status = REG_READ(&priv->last_status);
     223        last_address = REG_READ(&priv->last_address);
     224        SPIN_IRQ_UNLOCK(&priv->devlock, lock_context);
     225
     226        *status = last_status;
     227        *address = last_address;
     228
     229        return (last_status & AHBSTAT_STS_NE) >> AHBSTAT_STS_NE_BIT;
    193230}
    194231
Note: See TracChangeset for help on using the changeset viewer.