예제 #1
0
static int setup_serial(struct serial_info * info, ioaddr_t port, int irq)
{
	struct serial_struct serial;
	int line;

	memset(&serial, 0, sizeof (serial));
	serial.port = port;
	serial.irq = irq;
	serial.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ;
	if (buggy_uart)
		serial.flags |= UPF_BUGGY_UART;
	line = register_serial(&serial);
	if (line < 0) {
		printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
		       " irq %d failed\n", (u_long) serial.port, serial.irq);
		return -EINVAL;
	}

	info->line[info->ndev] = line;
	sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
	info->node[info->ndev].major = TTY_MAJOR;
	info->node[info->ndev].minor = 0x40 + line;
	if (info->ndev > 0)
		info->node[info->ndev - 1].next = &info->node[info->ndev];
	info->ndev++;

	return 0;
}
예제 #2
0
static int
pnp_init_one(struct pci_dev *dev, const struct pnpbios_device_id *ent,
	     char *slot_name)
{
	struct serial_struct serial_req;
	int ret, line, flags = ent ? ent->driver_data : 0;

	if (!ent) {
		ret = serial_pnp_guess_board(dev, &flags);
		if (ret)
			return ret;
	}

	if (dev->prepare(dev) < 0) {
		printk("serial: PNP device '%s' prepare failed\n",
			slot_name);
		return -ENODEV;
	}

	if (dev->active)
		return -ENODEV;

	if (flags & SPCI_FL_NO_SHIRQ)
		avoid_irq_share(dev);

	if (dev->activate(dev) < 0) {
		printk("serial: PNP device '%s' activate failed\n",
			slot_name);
		return -ENODEV;
	}

	memset(&serial_req, 0, sizeof(serial_req));
	serial_req.irq = dev->irq_resource[0].start;
	serial_req.port = pci_resource_start(dev, 0);
	if (HIGH_BITS_OFFSET)
		serial_req.port = pci_resource_start(dev, 0) >> HIGH_BITS_OFFSET;

#ifdef SERIAL_DEBUG_PCI
	printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
	       serial_req.port, serial_req.irq, serial_req.io_type);
#endif

	serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
	serial_req.baud_base = 115200;
	line = register_serial(&serial_req);

	if (line >= 0) {
		pci_set_drvdata(dev, (void *)(line + 1));

		/*
		 * Public health warning: remove this once the 2.5
		 * pnpbios_module_init() stuff is incorporated.
		 */
		dev->driver = (void *)pnp_dev_table;
	} else
		dev->deactivate(dev);

	return line >= 0 ? 0 : -ENODEV;
}
예제 #3
0
static dev_node_t *serial_attach(dev_locator_t *loc)
{
    u_int io;
    u_char irq;
    int line;
    struct serial_struct serial;
    struct pci_dev *pdev;
    dev_node_t *node;

    MOD_INC_USE_COUNT;

    if (loc->bus != LOC_PCI) goto err_out;
    pdev = pci_find_slot (loc->b.pci.bus, loc->b.pci.devfn);
    if (!pdev) goto err_out;
    if (pci_enable_device(pdev)) goto err_out;

    printk(KERN_INFO "serial_attach(bus %d, fn %d)\n", pdev->bus->number, pdev->devfn);
    io = pci_resource_start (pdev, 0);
    irq = pdev->irq;
    if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
        printk(KERN_NOTICE "serial_cb: PCI base address 0 is not IO\n");
        goto err_out;
    }
    device_setup(pdev, io);
    memset(&serial, 0, sizeof(serial));
    serial.port = io;
    serial.irq = irq;
    serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;

    /* Some devices seem to need extra time */
    __set_current_state(TASK_UNINTERRUPTIBLE);
    schedule_timeout(HZ/50);

    line = register_serial(&serial);
    if (line < 0) {
        printk(KERN_NOTICE "serial_cb: register_serial() at 0x%04x, "
               "irq %d failed\n", serial.port, serial.irq);
        goto err_out;
    }

    node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
    if (!node)
        goto err_out_unregister;
    sprintf(node->dev_name, "ttyS%d", line);
    node->major = TTY_MAJOR;
    node->minor = 0x40 + line;
    node->next = NULL;
    return node;

err_out_unregister:
    unregister_serial(line);
err_out:
    MOD_DEC_USE_COUNT;
    return NULL;
}
예제 #4
0
파일: 8250_acpi.c 프로젝트: wxlong/Test
static int acpi_serial_add(struct acpi_device *device)
{
	struct serial_private *priv;
	acpi_status status;
	struct serial_struct serial_req;
	int result;

	memset(&serial_req, 0, sizeof(serial_req));

	priv = kmalloc(sizeof(struct serial_private), GFP_KERNEL);
	if (!priv) {
		result = -ENOMEM;
		goto fail;
	}
	memset(priv, 0, sizeof(*priv));

	status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
				     acpi_serial_resource, &serial_req);
	if (ACPI_FAILURE(status)) {
		result = -ENODEV;
		goto fail;
	}

	if (serial_req.iomem_base)
		priv->iomem_base = serial_req.iomem_base;
	else if (!serial_req.port) {
		printk(KERN_ERR "%s: no iomem or port address in %s _CRS\n",
			__FUNCTION__, device->pnp.bus_id);
		result = -ENODEV;
		goto fail;
	}

	serial_req.baud_base = BASE_BAUD;
	serial_req.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_RESOURCES;

	priv->line = register_serial(&serial_req);
	if (priv->line < 0) {
		printk(KERN_WARNING "Couldn't register serial port %s: %d\n",
			device->pnp.bus_id, priv->line);
		result = -ENODEV;
		goto fail;
	}

	acpi_driver_data(device) = priv;
	return 0;

fail:
	if (serial_req.iomem_base)
		iounmap(serial_req.iomem_base);
	kfree(priv);

	return result;
}
예제 #5
0
static inline int serial_register_onedev (unsigned long port, int irq)
{
	struct serial_struct req;

	memset(&req, 0, sizeof(req));
	req.baud_base = MY_BAUD_BASE;
	req.irq = irq;
	req.port = port;
	req.flags = 0;

	return register_serial(&req);
}
예제 #6
0
static int __init serial_bast_register(unsigned long port, unsigned int irq)
{
	struct serial_struct serial_req;

	serial_req.flags      = UPF_AUTOPROBE | UPF_SHARE_IRQ;
	serial_req.baud_base  = BASE_BAUD;
	serial_req.irq        = irq;
	serial_req.io_type    = UPIO_MEM;
	serial_req.iomap_base = port;
	serial_req.iomem_base = ioremap(port, 0x10);
	serial_req.iomem_reg_shift = 0;

	return register_serial(&serial_req);
}
예제 #7
0
/* adapted from drivers/char/pcmcia/serial_cs.c (where it is a static procedure) */
static int setup_serial(ioaddr_t port, int irq)
{
    struct serial_struct serial;
    int line;

    memset(&serial, 0, sizeof(serial));
    serial.port = port;
    serial.irq = irq;
    serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
    line = register_serial(&serial);
    if (line < 0) {
        printk(KERN_NOTICE " " __FILE__ ": register_serial() at 0x%04lx,"
               " irq %d failed\n", (u_long)serial.port, serial.irq);
    }
    return line;
}
예제 #8
0
static inline int
serial_register_onedev(unsigned long baddr, void *vaddr, int irq, unsigned int baud_base)
{
    struct serial_struct req;

    memset(&req, 0, sizeof(req));
    req.irq			= irq;
    req.flags		= UPF_AUTOPROBE | UPF_RESOURCES |
                      UPF_SHARE_IRQ;
    req.baud_base		= baud_base;
    req.io_type		= UPIO_MEM;
    req.iomem_base		= vaddr;
    req.iomem_reg_shift	= 2;
    req.iomap_base		= baddr;

    return register_serial(&req);
}
예제 #9
0
파일: mwavedd.c 프로젝트: kzlin129/tt-gpl
static int register_serial_portandirq(unsigned int port, int irq)
{
	struct serial_struct serial;

	switch ( port ) {
		case 0x3f8:
		case 0x2f8:
		case 0x3e8:
		case 0x2e8:
			/* OK */
			break;
		default:
			PRINTK_ERROR(KERN_ERR_MWAVE
					"mwavedd::register_serial_portandirq:"
					" Error: Illegal port %x\n", port );
			return -1;
	} /* switch */
	/* port is okay */

	switch ( irq ) {
		case 3:
		case 4:
		case 5:
		case 7:
			/* OK */
			break;
		default:
			PRINTK_ERROR(KERN_ERR_MWAVE
					"mwavedd::register_serial_portandirq:"
					" Error: Illegal irq %x\n", irq );
			return -1;
	} /* switch */
	/* irq is okay */

	memset(&serial, 0, sizeof(serial));
	serial.port = port;
	serial.irq = irq;
	serial.flags = ASYNC_SHARE_IRQ;

	return register_serial(&serial);
}
예제 #10
0
static __init void s5pv210_serial_dev_init(void)
{
	struct serial_parameter * param;
	u32_t i;

	if(!clk_get_rate("psys-pclk", 0))
	{
		LOG_E("can't get the clock of \'psys-pclk\'");
		return;
	}

	/* register serial driver */
	for(i = 0; i < ARRAY_SIZE(s5pv210_uart_driver); i++)
	{
		param = (struct serial_parameter *)resource_get_data(s5pv210_uart_driver[i].info->name);
		if(param)
			memcpy(s5pv210_uart_driver[i].info->parameter, param, sizeof(struct serial_parameter));
		else
			LOG_W("can't get the resource of \'%s\', use default parameter", s5pv210_uart_driver[i].info->name);

		if(!register_serial(&s5pv210_uart_driver[i]))
			LOG_E("failed to register serial driver '%s'", s5pv210_uart_driver[i].info->name);
	}
}
예제 #11
0
int asdg_setup(void)
{
  int i, line1, line2;
  struct SCC *scc=NULL;
  int dummy;
  struct ConfigDev *cd=NULL;
  struct serial_struct req;
  struct async_struct *info=NULL;
  int CardFound=0; 
  
  if (!MACH_IS_AMIGA)
    return -ENODEV;
  
#ifdef DEBUG
  printk("We are a miggy\n");
#endif

  nr_asdg = 0;
  
  while((i=zorro_find(MANUF_ASDG, PROD_TWIN_X,1, 0))) {

    CardFound=1;

    board_index[nr_asdg/2] = i;
    cd = zorro_get_board(i);
    scc = (struct SCC *)ZTWO_VADDR((((volatile u_char *)cd->cd_BoardAddr)));

#ifdef DEBUG
    printk("Found ASDG DSB at %p\n", scc);
#endif
    
    req.line = -1; /* first free ttyS? device */
    req.type = SER_ASDG;
    req.port = (int) &(scc->B);
    if ((line1 = register_serial( &req )) < 0) {
      printk( "Cannot register ASDG serial port: no free device\n" );
      return -EBUSY;
    }
    lines[nr_asdg++] = line1;
    info = &rs_table[line1];
    info->sw = &asdg_ser_switch;
    info->nr_uarts = nr_asdg;
    info->board_base = scc;
    
    req.line = -1; /* first free ttyS? device */
    req.type = SER_ASDG;
    req.port = (int) &(scc->A);
    if ((line2 = register_serial( &req )) < 0) {
      printk( "Cannot register ASDG serial port: no free device\n" );
      unregister_serial( line1 );
      return -EBUSY;
    }
    lines[nr_asdg++] = line2;
    info = &rs_table[line2];
    info->sw = &asdg_ser_switch;
    info->nr_uarts = nr_asdg--;
    info->board_base = scc;
    
    nr_asdg++;
    
    zorro_config_board(i,1);

    /* Clear pointers */
    dummy = scc->A.control;
    dummy = scc->B.control;
    
#ifdef DEBUG
    printk("Pointers cleared \n");
#endif

    /* Reset card */
    write_zsreg(&scc->A, R9, FHWRES | MIE);
    udelay(10); /* Give card time to reset */
    write_zsreg(&scc->B, R9, FHWRES | MIE);
    udelay(10); /* Give card time to reset */

#ifdef DEBUG
    printk("Card reset - MIE on \n");
#endif

    /* Reset all potential interupt sources */
    write_zsreg(&scc->A, R0, RES_EXT_INT);  /* Ext ints (disabled anyways) */
    write_zsreg(&scc->B, R0, RES_EXT_INT); 

#ifdef DEBUG
    printk("Ext ints cleared\n");
#endif

    write_zsreg(&scc->A, R0, RES_Tx_P);     /* TBE int */
    write_zsreg(&scc->B, R0, RES_Tx_P);

#ifdef DEBUG
    printk("TBE Cleared\n");
#endif

    /* Clear Rx FIFO */
    while( (read_zsreg(&scc->A, R0) & Rx_CH_AV) != 0)
      dummy=read_zsdata(&scc->A);
    while( (read_zsreg(&scc->B, R0) & Rx_CH_AV) != 0) 
      dummy=read_zsdata(&scc->B);

#ifdef DEBUG
    printk("Rx buffer empty\n");
#endif
    
    /* TBE and RX int off - we will turn them on in _init()*/
    write_zsreg(&scc->A, R1, 0);
    write_zsreg(&scc->B, R1, 0);

#ifdef DEBUG    
    printk("Tx and Rx ints off \n");
#endif

    /* Interrupt vector */
    write_zsreg(&scc->A, R2, 0);
    write_zsreg(&scc->B, R2, 0);

#ifdef DEBUG
    printk("Int vector set (unused) \n");
#endif

    write_zsreg(&scc->A, R3, Rx8);
    write_zsreg(&scc->B, R3, Rx8);

#ifdef DEBUG
    printk("Rx enabled\n");
#endif

    write_zsreg(&scc->A, R4, SB1 | X16CLK);
    write_zsreg(&scc->B, R4, SB1 | X16CLK);

#ifdef DEBUG
    printk("1 stop bit, x16 clock\n");
#endif

    write_zsreg(&scc->A, R5, Tx8);
    write_zsreg(&scc->B, R5, Tx8);
    
#ifdef DEBUG
    printk("Tx enabled \n");
#endif

    write_zsreg(&scc->A, R10, NRZ); 
    write_zsreg(&scc->B, R10, NRZ); 

#ifdef DEBUG
    printk("NRZ mode\n");
#endif

    write_zsreg(&scc->A, R11, TCBR | RCBR | TRxCBR);
    write_zsreg(&scc->B, R11, TCBR | RCBR | TRxCBR);

#ifdef DEBUG
    printk("Clock source setup\n");
#endif

    /*300 bps */
    write_zsreg(&scc->A, R12, 0xfe);
    write_zsreg(&scc->A, R13, 2);
    write_zsreg(&scc->B, R12, 0xfe);
    write_zsreg(&scc->B, R13, 2);

#ifdef DEBUG
    printk("Baud rate set - 300\n");
#endif

    write_zsreg(&scc->A, R14, BRENABL | BRSRC);
    write_zsreg(&scc->B, R14, BRENABL | BRSRC);

#ifdef DEBUG
    printk("BRG enabled \n");
#endif

    write_zsreg(&scc->A, R15, 0);
    write_zsreg(&scc->A, R15, 0);

#ifdef DEBUG
    printk("Ext INT IE bits cleared \n");
#endif
  }

  if(CardFound) {
    request_irq(IRQ_AMIGA_EXTER, asdg_interrupt, 0, "ASDG serial",
		asdg_interrupt);
    return 0;
  } else {
    printk("No ASDG Cards found\n");
    return -ENODEV;
  }
}
예제 #12
0
int whippet_init(void)
{
struct serial_struct req;
struct async_struct *info;
unsigned char ch;
unsigned long flags;

	if (!((MACH_IS_AMIGA) && (boot_info.bi_amiga.model == AMI_1200)))
		return -ENODEV;

	save_flags(flags);
	cli();

/* Acknowledge any possible PCMCIA interrupts */

	ch=inb(GAYLE_IRQ_STATUS);
	outb(0xdc | (ch & 0x03),GAYLE_IRQ_STATUS);

/* Check for 16c550 by testing the scratch register and other stuff */
/* If there is nothing in the PCMCIA port, then any reads should(!) */
/* return 0xff.							    */

#ifdef WHIPPET_DEBUG
	printk("Probing for Whippet Serial...\n");
	printk("Looking at address 0x%08x\n",(int)&uart);
#endif
	uart.IER=0x00;
	uart.MCR=0x00;
	uart.LCR=0x00;
	uart.FCR=0x00;
	if ((uart.IER) != 0x00)	return -ENODEV;

	(void)uart.RBR;
	(void)uart.LSR;
	(void)uart.IIR;
	(void)uart.MSR;
	uart.FCR=0x00;
	uart.LCR=0x00;
	uart.MCR=0x00;

	uart.SCR=0xA5;
	uart.IER=0x00;
	if ((uart.SCR) != 0xA5)	return -ENODEV;

	uart.SCR=0x4D;
	uart.IER=0x00;
	if ((uart.SCR) != 0x4D)	return -ENODEV;

	restore_flags(flags);

/*
 * Set the necessary tty-stuff.
 */
	req.line = -1;			/* first free ttyS? device */
	req.type = SER_WHIPPET;
	req.port = (int) &uart.RBR;

	if ((line = register_serial( &req )) < 0)
	{
		printk( "Cannot register Whippet serial port: no free device\n" );
		return -EBUSY;
	}

	info = &rs_table[line];		/* set info == struct *async_struct */

	info->nr_uarts = 1;			/* one UART (necessary?) */
	info->sw = &whippet_ser_switch;		/* switch functions      */

	/* Install ISR - level 2 - data is struct *async_struct */

	request_irq(IRQ_AMIGA_PORTS, ser_interrupt, 0, "whippet serial", info);


/* Add {} in here so that without debugging we still get the
 * desired effect (murray)
 */

/* Wait for the uarts to get empty */

	while(!((uart.LSR) & TEMT))
	{
#if WHIPPET_DEBUG
	printk("Waiting for transmitter to finish\n");
#endif
	}

/*
 * Set the uarts to a default setting of 8N1 - 9600
 */

	uart.LCR = (data_8bit | DLAB);
	uart.DLM = 0;
	uart.DLL = 48;
	uart.LCR = (data_8bit);

/*
 * Enable + reset both the tx and rx FIFO's.
 * Set the rx FIFO-trigger count.
 */

	uart.FCR = (FIFO_ENA | RCVR_FIFO_RES | XMIT_FIFO_RES | FIFO_TRIGGER_LEVEL );

/*
 * Disable all uart interrupts (they will be re-enabled in ser_init when
 *  they are needed).
 */
	uart.IER = 0x00;


/* Print confirmation of whippet detection */

	printk("Detected Whippet Serial Port at 0x%08x (ttyS%i)\n",(int)&uart,line);
	return(0);
}
예제 #13
0
unsigned long serial_init(int chan, void *ignored)
{
#if 0
	struct serial_struct req;

	/* UARTA has already been initialized by the bootloader */
	if (chan > 0) {
		memset(&req, 0, sizeof(struct serial_struct));
		req.port = chan;
		req.iomem_base = UARTA_ADR_BASE + (0x40 * chan);
		req.irq = BRCM_SERIAL1_IRQ + chan;  // FOr now, assume all 3 irqs are consecutive
		req.baud_base = BRCM_BASE_BAUD;
		req.xmit_fifo_size = 32;

		/* How far apart the registers are. */
		req.iomem_reg_shift = shift = 2;  /* Offset by 4 bytes, UART_SDW_LCR=0c offset, UART_LCR=3 */
		
		req.io_type = SERIAL_IO_MEM;
		req.flags = STD_COM_FLAGS;
		req.iomap_base = chan;

		register_serial(&req);

	}
	
#endif

	unsigned long uartBaseAddr = UARTA_ADR_BASE + (0x40 * chan); 
	void uartB_puts(const char *s);

#ifdef CONFIG_MIPS_BRCM_IKOS
  #define DIVISOR (14)
#else
  #define DIVISOR (44)
#endif

	shift = 2;


#if 1 /* Enable UARTB */
if (chan == 1) {
// MUX for UARTB is: RX: ctrl3: bit 29:27 (001'b) and TX: ctrl4: bit 02:00 (001'b)

#define SUN_TOP_CTRL_PIN_MUX_CTRL_3	(0xb040410c)
	volatile unsigned long* pSunTopMuxCtrl3 = (volatile unsigned long*) SUN_TOP_CTRL_PIN_MUX_CTRL_3;
#define SUN_TOP_CTRL_PIN_MUX_CTRL_4	(0xb0404110)
	volatile unsigned long* pSunTopMuxCtrl4 = (volatile unsigned long*) SUN_TOP_CTRL_PIN_MUX_CTRL_4;
	
	*pSunTopMuxCtrl3 &= 0xc7ffffff;	// Clear it
	*pSunTopMuxCtrl3 |= 0x08000000;  // Write 001'b at 27:29

	*pSunTopMuxCtrl4 &= 0xfffffff8;	// Clear it
	*pSunTopMuxCtrl4 |= 0x00000001;  // Write 001'b  at 00:02
}
#endif

	/* UARTA has already been initialized by the bootloader */
	if (chan > 0 ) {
		// Write DLAB, and (8N1) = 0x83
		writel(UART_LCR_DLAB|UART_LCR_WLEN8, (void *)(uartBaseAddr + (UART_LCR << shift)));
		// Write DLL to 0xe
		writel(DIVISOR, (void *)(uartBaseAddr + (UART_DLL << shift)));
		writel(0, (void *)(uartBaseAddr + (UART_DLM << shift)));

		// Clear DLAB
		writel(UART_LCR_WLEN8, (void *)(uartBaseAddr + (UART_LCR << shift)));

		// Disable FIFO
		writel(0, (void *)(uartBaseAddr + (UART_FCR << shift)));

		if (chan == 1) {
			uartB_puts("Done initializing UARTB\n");
		}
	}
	return (uartBaseAddr);
}