Example #1
0
File: grtm.c Project: gedare/rtems
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;
}
Example #3
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;
}