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; }
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; }
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; }
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; }
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); }
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); }
/* 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; }
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); }
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); }
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); } }
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; } }
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); }
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); }