static int grtm_device_init(struct grtm_priv *pDev) { struct amba_dev_info *ambadev; struct ambapp_core *pnpinfo; union drvmgr_key_value *value; /* Get device information from AMBA PnP information */ ambadev = (struct amba_dev_info *)pDev->dev->businfo; if ( ambadev == NULL ) { return -1; } pnpinfo = &ambadev->info; pDev->irq = pnpinfo->irq; pDev->regs = (struct grtm_regs *)pnpinfo->apb_slv->start; pDev->minor = pDev->dev->minor_drv; pDev->open = 0; pDev->running = 0; /* Create Binary RX Semaphore with count = 0 */ if ( rtems_semaphore_create(rtems_build_name('G', 'R', 'M', '0' + pDev->minor), 0, RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\ RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING, 0, &pDev->sem_tx) != RTEMS_SUCCESSFUL ) { return -1; } /* Allocate Memory for Buffer Descriptor Table, or let user provide a custom * address. */ value = drvmgr_dev_key_get(pDev->dev, "bdTabAdr", DRVMGR_KT_POINTER); if ( value ) { pDev->bds = (struct grtm_bd *)value->ptr; pDev->_bds = (void *)value->ptr; } else { pDev->bds = (struct grtm_bd *)grtm_memalign(0x400, 0x400, &pDev->_bds); } if ( !pDev->bds ) { DBG("GRTM: Failed to allocate descriptor table\n"); return -1; } memset(pDev->bds, 0, 0x400); pDev->_ring = malloc(sizeof(struct grtm_ring) * 128); if ( !pDev->_ring ) { return -1; } /* Reset Hardware before attaching IRQ handler */ grtm_hw_reset(pDev); /* Read SUB revision number, ignore */ pDev->subrev = (READ_REG(&pDev->regs->revision) & GRTM_REV1_REV_SREV) >> GRTM_REV1_REV_SREV_BIT; return 0; }
static int grtm_device_init(struct grtm_priv *pDev) { struct amba_dev_info *ambadev; struct ambapp_core *pnpinfo; union drvmgr_key_value *value; /* Get device information from AMBA PnP information */ ambadev = (struct amba_dev_info *)pDev->dev->businfo; if ( ambadev == NULL ) { return -1; } pnpinfo = &ambadev->info; pDev->irq = pnpinfo->irq; pDev->regs = (struct grtm_regs *)pnpinfo->apb_slv->start; pDev->minor = pDev->dev->minor_drv; pDev->open = 0; pDev->running = 0; /* Create Binary RX Semaphore with count = 0 */ if ( rtems_semaphore_create(rtems_build_name('G', 'R', 'M', '0' + pDev->minor), 0, RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\ RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING, 0, &pDev->sem_tx) != RTEMS_SUCCESSFUL ) { return -1; } /* Create ISR protection Counting Semaphore with count = 1 */ if ( rtems_semaphore_create(rtems_build_name('G', 'T', 'M', '0' + pDev->minor), 1, RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY | \ RTEMS_LOCAL | RTEMS_NO_PRIORITY_CEILING, 0, &pDev->handling_transmission) != RTEMS_SUCCESSFUL ) { return -1; } /* Override default 2k MAX FRAME length if available from bus resource */ pDev->frame_length_max = 2*1024; value = drvmgr_dev_key_get(pDev->dev, "maxFrameLength", KEY_TYPE_INT); if ( value ) pDev->frame_length_max = value->i; /* Default to allocate from partition 0 */ pDev->alloc_part_bd = 0; pDev->alloc_part_frm = 0; value = drvmgr_dev_key_get(pDev->dev, "bdAllocPartition", KEY_TYPE_INT); if ( value ) pDev->alloc_part_bd = value->i; value = drvmgr_dev_key_get(pDev->dev, "frameAllocPartition", KEY_TYPE_INT); if ( value ) pDev->alloc_part_frm = value->i; /* Allocate Memory for Descriptors */ #ifdef REMOTE_DESCRIPTORS pDev->bds = 0xA0000000; pDev->_bds = 0xA0000000; #else pDev->_bds = pDev->bds = (struct grtm_bd *) ambapp_rmap_partition_memalign(pDev->dev, pDev->alloc_part_bd, 0x400, 0x400); #endif if ( !pDev->bds ) { DBG("GRTM: Failed to allocate descriptor table\n"); return -1; } MEMSET(pDev, pDev->bds, 0, 0x400); pDev->_ring = malloc(sizeof(struct grtm_ring) * 128); if ( !pDev->_ring ) { return -1; } pDev->_frame_buffers = (unsigned char *) ambapp_rmap_partition_memalign( pDev->dev, pDev->alloc_part_frm, 0x4, DESCRIPTOR_MAX * pDev->frame_length_max); if ( !pDev->_frame_buffers ) { return -1; } /* Reset Hardware before attaching IRQ handler */ grtm_hw_reset(pDev); /* Read SUB revision number, ignore */ pDev->subrev = (READ_REG(pDev, &pDev->regs->revision) & GRTM_REV1_REV_SREV) >> GRTM_REV1_REV_SREV_BIT; return 0; }
int apbuart_init1(struct drvmgr_dev *dev) { struct apbuart_priv *priv; struct amba_dev_info *ambadev; struct ambapp_core *pnpinfo; union drvmgr_key_value *value; char prefix[32]; unsigned int db; static int first_uart = 1; /* The default operation in AMP is to use APBUART[0] for CPU[0], * APBUART[1] for CPU[1] and so on. The remaining UARTs is not used * since we don't know how many CPU-cores there are. Note this only * affects the on-chip amba bus (the root bus). The user can override * the default resource sharing by defining driver resources for the * APBUART devices on each AMP OS instance. */ #if defined(RTEMS_MULTIPROCESSING) && defined(LEON3) if (drvmgr_on_rootbus(dev) && dev->minor_drv != LEON3_Cpu_Index && drvmgr_keys_get(dev, NULL) != 0) { /* User hasn't configured on-chip APBUART, leave it untouched */ return DRVMGR_EBUSY; } #endif DBG("APBUART[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name); /* Private data was allocated and zeroed by driver manager */ priv = dev->priv; if (!priv) return DRVMGR_NOMEM; priv->dev = dev; /* Get device information from AMBA PnP information */ ambadev = (struct amba_dev_info *)priv->dev->businfo; if (ambadev == NULL) return -1; pnpinfo = &ambadev->info; priv->regs = (struct apbuart_regs *)pnpinfo->apb_slv->start; /* Clear HW regs, leave baudrate register as it is */ priv->regs->status = 0; /* leave Transmitter/receiver if this is the RTEMS debug UART (assume * it has been setup by boot loader). */ db = 0; #ifdef LEON3 if (priv->regs == leon3_debug_uart) { db = priv->regs->ctrl & (LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE | LEON_REG_UART_CTRL_PE | LEON_REG_UART_CTRL_PS); } #endif /* Let UART debug tunnelling be untouched if Flow-control is set. * * With old APBUARTs debug is enabled by setting LB and FL, since LB or * DB are not reset we can not trust them. However since FL is reset we * guess that we are debugging if FL is already set, the debugger set * either LB or DB depending on UART capabilities. */ if (priv->regs->ctrl & LEON_REG_UART_CTRL_FL) { db |= priv->regs->ctrl & (LEON_REG_UART_CTRL_DB | LEON_REG_UART_CTRL_LB | LEON_REG_UART_CTRL_FL); } priv->regs->ctrl = db; priv->cap = probecap(priv->regs); /* The system console and Debug console may depend on this device, so * initialize it straight away. * * We default to have System Console on first APBUART, user may override * this behaviour by setting the syscon option to 0. */ if (drvmgr_on_rootbus(dev) && first_uart) { priv->condev.flags = CONSOLE_FLAG_SYSCON; first_uart = 0; } else { priv->condev.flags = 0; } value = drvmgr_dev_key_get(priv->dev, "syscon", DRVMGR_KT_INT); if (value) { if (value->i) priv->condev.flags |= CONSOLE_FLAG_SYSCON; else priv->condev.flags &= ~CONSOLE_FLAG_SYSCON; } /* Select 0=Polled, 1=IRQ, 2=Task-Driven UART Mode */ value = drvmgr_dev_key_get(priv->dev, "mode", DRVMGR_KT_INT); if (value) priv->mode = value->i; else priv->mode = TERMIOS_POLLED; /* TERMIOS device handlers */ if (priv->mode == TERMIOS_IRQ_DRIVEN) { priv->condev.handler = &handler_interrupt; } else if (priv->mode == TERMIOS_TASK_DRIVEN) { priv->condev.handler = &handler_task; } else { priv->condev.handler = &handler_polled; } priv->condev.fsname = NULL; /* Get Filesystem name prefix */ prefix[0] = '\0'; if (drvmgr_get_dev_prefix(dev, prefix)) { /* Got special prefix, this means we have a bus prefix * And we should use our "bus minor" */ sprintf(priv->devName, "/dev/%sapbuart%d", prefix, dev->minor_bus); priv->condev.fsname = priv->devName; } else { sprintf(priv->devName, "/dev/apbuart%d", dev->minor_drv); } /* Register it as a console device, the console driver will register * a termios device as well */ console_dev_register(&priv->condev); return DRVMGR_OK; }