static int bfin_sir_startup(struct bfin_sir_port *port, struct net_device *dev) { #ifdef CONFIG_SIR_BFIN_DMA dma_addr_t dma_handle; #endif /* CONFIG_SIR_BFIN_DMA */ if (request_dma(port->rx_dma_channel, "BFIN_UART_RX") < 0) { dev_warn(&dev->dev, "Unable to attach SIR RX DMA channel\n"); return -EBUSY; } if (request_dma(port->tx_dma_channel, "BFIN_UART_TX") < 0) { dev_warn(&dev->dev, "Unable to attach SIR TX DMA channel\n"); free_dma(port->rx_dma_channel); return -EBUSY; } #ifdef CONFIG_SIR_BFIN_DMA set_dma_callback(port->rx_dma_channel, bfin_sir_dma_rx_int, dev); set_dma_callback(port->tx_dma_channel, bfin_sir_dma_tx_int, dev); port->rx_dma_buf.buf = dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, GFP_DMA); port->rx_dma_buf.head = 0; port->rx_dma_buf.tail = 0; port->rx_dma_nrows = 0; set_dma_config(port->rx_dma_channel, set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO, INTR_ON_ROW, DIMENSION_2D, DATA_SIZE_8, DMA_SYNC_RESTART)); set_dma_x_count(port->rx_dma_channel, DMA_SIR_RX_XCNT); set_dma_x_modify(port->rx_dma_channel, 1); set_dma_y_count(port->rx_dma_channel, DMA_SIR_RX_YCNT); set_dma_y_modify(port->rx_dma_channel, 1); set_dma_start_addr(port->rx_dma_channel, (unsigned long)port->rx_dma_buf.buf); enable_dma(port->rx_dma_channel); port->rx_dma_timer.data = (unsigned long)(dev); port->rx_dma_timer.function = (void *)bfin_sir_rx_dma_timeout; #else if (request_irq(port->irq, bfin_sir_rx_int, 0, "BFIN_SIR_RX", dev)) { dev_warn(&dev->dev, "Unable to attach SIR RX interrupt\n"); return -EBUSY; } if (request_irq(port->irq+1, bfin_sir_tx_int, 0, "BFIN_SIR_TX", dev)) { dev_warn(&dev->dev, "Unable to attach SIR TX interrupt\n"); free_irq(port->irq, dev); return -EBUSY; } #endif return 0; }
static int sport_request_resource(struct sport_device *sport) { struct device *dev = &sport->pdev->dev; int ret; ret = peripheral_request_list(sport->pin_req, "soc-audio"); if (ret) { dev_err(dev, "Unable to request sport pin\n"); return ret; } ret = request_dma(sport->tx_dma_chan, "SPORT TX Data"); if (ret) { dev_err(dev, "Unable to allocate DMA channel for sport tx\n"); goto err_tx_dma; } set_dma_callback(sport->tx_dma_chan, sport_tx_irq, sport); ret = request_dma(sport->rx_dma_chan, "SPORT RX Data"); if (ret) { dev_err(dev, "Unable to allocate DMA channel for sport rx\n"); goto err_rx_dma; } set_dma_callback(sport->rx_dma_chan, sport_rx_irq, sport); ret = request_irq(sport->tx_err_irq, sport_err_irq, 0, "SPORT TX ERROR", sport); if (ret) { dev_err(dev, "Unable to allocate tx error IRQ for sport\n"); goto err_tx_irq; } ret = request_irq(sport->rx_err_irq, sport_err_irq, 0, "SPORT RX ERROR", sport); if (ret) { dev_err(dev, "Unable to allocate rx error IRQ for sport\n"); goto err_rx_irq; } return 0; err_rx_irq: free_irq(sport->tx_err_irq, sport); err_tx_irq: free_dma(sport->rx_dma_chan); err_rx_dma: free_dma(sport->tx_dma_chan); err_tx_dma: peripheral_free_list(sport->pin_req); return ret; }
int __init bf561_coreb_init(void) { struct proc_dir_entry *proc_entry; init_waitqueue_head(&coreb_dma_wait); /* Request the core memory regions for Core B */ if (request_mem_region(0xff600000, 0x4000, "Core B - Instruction SRAM") == NULL) goto exit; if (request_mem_region(0xFF610000, 0x4000, "Core B - Instruction SRAM") == NULL) goto release_instruction_a_sram; if (request_mem_region(0xFF500000, 0x8000, "Core B - Data Bank B SRAM") == NULL) goto release_instruction_b_sram; if (request_mem_region(0xff400000, 0x8000, "Core B - Data Bank A SRAM") == NULL) goto release_data_b_sram; if (request_dma(CH_MEM_STREAM2_DEST, "Core B - DMA Destination") < 0) goto release_data_a_sram; if (request_dma(CH_MEM_STREAM2_SRC, "Core B - DMA Source") < 0) goto release_dma_dest; set_dma_callback(CH_MEM_STREAM2_DEST, coreb_dma_interrupt, NULL); misc_register(&coreb_dev); printk(KERN_INFO "Core B: Initializing /proc\n"); coreb_proc_entry = create_proc_entry("coreb", 0, NULL); if (coreb_proc_entry) { coreb_proc_entry->owner = THIS_MODULE; coreb_proc_entry->read_proc = coreb_read_status; } else { printk(KERN_ERR "Core B: Unable to register /proc/coreb\n"); goto release_dma_src; } printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER); return 0; release_dma_src: free_dma(CH_MEM_STREAM2_SRC); release_dma_dest: free_dma(CH_MEM_STREAM2_DEST); release_data_a_sram: release_mem_region(0xff400000, 0x8000); release_data_b_sram: release_mem_region(0xff500000, 0x8000); release_instruction_b_sram: release_mem_region(0xff610000, 0x4000); release_instruction_a_sram: release_mem_region(0xff600000, 0x4000); exit: return -ENOMEM; }
static int dma_init(void) { int ret; /* Request DMA channel */ ret = request_dma(CH_PPI, DRIVER_NAME); if(ret < 0) { printk(KERN_WARNING DRIVER_NAME ": Could not allocate DMA channel\n"); return ret; } /* Disable channel while it is being configured */ disable_dma(CH_PPI); /* Allocate buffer space for the DMA engine to use */ dma_buffer = __get_dma_pages(GFP_KERNEL, page_alloc_order(BUFFER_SIZE * BUFFER_COUNT)); if(dma_buffer == 0) { printk(KERN_WARNING DRIVER_NAME ": Could not allocate dma_pages\n"); free_dma(CH_PPI); return -ENOMEM; } /* Invalid caching on the DMA buffer */ invalidate_dcache_range(dma_buffer, dma_buffer + (BUFFER_SIZE * BUFFER_COUNT)); /* Set DMA configuration */ set_dma_start_addr(CH_PPI, dma_buffer); set_dma_config(CH_PPI, (DMAFLOW_AUTO | WNR | RESTART | DI_EN | WDSIZE_16 | DMA2D | DI_SEL)); set_dma_x_count(CH_PPI, SAMPLES_PER_BUFFER * CHANNELS); set_dma_x_modify(CH_PPI, SAMPLE_SIZE); set_dma_y_count(CH_PPI, BUFFER_COUNT); set_dma_y_modify(CH_PPI, SAMPLE_SIZE); set_dma_callback(CH_PPI, &buffer_full_handler, NULL); return 0; }
static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler) { const struct ppi_info *info = ppi->info; int ret; ret = request_dma(info->dma_ch, "PPI_DMA"); if (ret) { pr_err("Unable to allocate DMA channel for PPI\n"); return ret; } set_dma_callback(info->dma_ch, handler, ppi); if (ppi->err_int) { ret = request_irq(info->irq_err, ppi_irq_err, 0, "PPI ERROR", ppi); if (ret) { pr_err("Unable to allocate IRQ for PPI\n"); free_dma(info->dma_ch); } } return ret; }
/* * FUNCTION NAME: ppi_open * * INPUTS/OUTPUTS: * in_inode - Description of openned file. * in_filp - Description of openned file. * * RETURN * 0: Open ok. * -ENXIO No such device * * FUNCTION(S) CALLED: * * GLOBAL VARIABLES REFERENCED: ppiinfo * * GLOBAL VARIABLES MODIFIED: NIL * * DESCRIPTION: It is invoked when user call 'open' system call * to open ppi device. * * CAUTION: */ static int ppi_open(struct inode *inode, struct file *filp) { char intname[20]; unsigned long flags; int minor = MINOR(inode->i_rdev); pr_debug("ppi_open:\n"); /* PPI ? */ if (minor != PPI0_MINOR) return -ENXIO; spin_lock_irqsave(&ppifcd_lock, flags); if (ppiinfo.opened) { spin_unlock_irqrestore(&ppifcd_lock, flags); return -EMFILE; } /* Clear configuration information */ memset(&ppiinfo, 0, sizeof(ppi_device_t)); if (filp->f_flags & O_NONBLOCK) ppiinfo.nonblock = 1; ppiinfo.opened = 1; ppiinfo.done = 0; ppiinfo.dma_config = (DMA_FLOW_MODE | WNR | RESTART | DMA_WDSIZE_16 | DMA2D | DI_EN); ppiinfo.pixel_per_line = PIXEL_PER_LINE; ppiinfo.lines_per_frame = LINES_PER_FRAME; ppiinfo.bpp = 8; ppiinfo.ppi_control = POL_S | POL_C | PPI_DATA_LEN | PPI_PACKING | CFG_GP_Input_3Syncs | GP_Input_Mode; ppiinfo.ppi_status = 0; ppiinfo.ppi_delay = 0; ppiinfo.ppi_trigger_gpio = NO_TRIGGER; ppiinfo.rx_avail = &ppirxq0; strcpy(intname, PPI_INTNAME); ppiinfo.irqnum = IRQ_PPI; filp->private_data = &ppiinfo; ppifcd_reg_reset(filp->private_data); /* Request DMA channel, and pass the interrupt handler */ if (request_dma(CH_PPI, "BF533_PPI_DMA") < 0) { panic("Unable to attach BlackFin PPI DMA channel\n"); ppiinfo.opened = 0; spin_unlock_irqrestore(&ppifcd_lock, flags); return -EFAULT; } else set_dma_callback(CH_PPI, (void *)ppifcd_irq, filp->private_data); request_irq(IRQ_PPI_ERROR, (void *)ppifcd_irq_error, IRQF_DISABLED, "PPI ERROR", filp->private_data); spin_unlock_irqrestore(&ppifcd_lock, flags); pr_debug("ppi_open: return\n"); return 0; }
static int bfin_serial_startup(struct uart_port *port) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; #ifdef CONFIG_SERIAL_BFIN_DMA dma_addr_t dma_handle; if (request_dma(uart->rx_dma_channel, "BFIN_UART_RX") < 0) { printk(KERN_NOTICE "Unable to attach Blackfin UART RX DMA channel\n"); return -EBUSY; } if (request_dma(uart->tx_dma_channel, "BFIN_UART_TX") < 0) { printk(KERN_NOTICE "Unable to attach Blackfin UART TX DMA channel\n"); free_dma(uart->rx_dma_channel); return -EBUSY; } set_dma_callback(uart->rx_dma_channel, bfin_serial_dma_rx_int, uart); set_dma_callback(uart->tx_dma_channel, bfin_serial_dma_tx_int, uart); uart->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, GFP_DMA); uart->rx_dma_buf.head = 0; uart->rx_dma_buf.tail = 0; uart->rx_dma_nrows = 0; set_dma_config(uart->rx_dma_channel, set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO, INTR_ON_ROW, DIMENSION_2D, DATA_SIZE_8, DMA_SYNC_RESTART)); set_dma_x_count(uart->rx_dma_channel, DMA_RX_XCOUNT); set_dma_x_modify(uart->rx_dma_channel, 1); set_dma_y_count(uart->rx_dma_channel, DMA_RX_YCOUNT); set_dma_y_modify(uart->rx_dma_channel, 1); set_dma_start_addr(uart->rx_dma_channel, (unsigned long)uart->rx_dma_buf.buf); enable_dma(uart->rx_dma_channel); uart->rx_dma_timer.data = (unsigned long)(uart); uart->rx_dma_timer.function = (void *)bfin_serial_rx_dma_timeout; uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; add_timer(&(uart->rx_dma_timer)); #else #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) if (kgdboc_port_line == uart->port.line && kgdboc_break_enabled) kgdboc_break_enabled = 0; else { # endif if (request_irq(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, "BFIN_UART_RX", uart)) { printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); return -EBUSY; } if (request_irq (uart->port.irq+1, bfin_serial_tx_int, IRQF_DISABLED, "BFIN_UART_TX", uart)) { printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n"); free_irq(uart->port.irq, uart); return -EBUSY; } # ifdef CONFIG_BF54x { unsigned uart_dma_ch_rx, uart_dma_ch_tx; switch (uart->port.irq) { case IRQ_UART3_RX: uart_dma_ch_rx = CH_UART3_RX; uart_dma_ch_tx = CH_UART3_TX; break; case IRQ_UART2_RX: uart_dma_ch_rx = CH_UART2_RX; uart_dma_ch_tx = CH_UART2_TX; break; default: uart_dma_ch_rx = uart_dma_ch_tx = 0; break; }; if (uart_dma_ch_rx && request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) { printk(KERN_NOTICE"Fail to attach UART interrupt\n"); free_irq(uart->port.irq, uart); free_irq(uart->port.irq + 1, uart); return -EBUSY; } if (uart_dma_ch_tx && request_dma(uart_dma_ch_tx, "BFIN_UART_TX") < 0) { printk(KERN_NOTICE "Fail to attach UART interrupt\n"); free_dma(uart_dma_ch_rx); free_irq(uart->port.irq, uart); free_irq(uart->port.irq + 1, uart); return -EBUSY; } } # endif #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) } # endif #endif UART_SET_IER(uart, ERBFI); return 0; }
static int bfin_serial_startup(struct uart_port *port) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; #ifdef CONFIG_SERIAL_BFIN_DMA dma_addr_t dma_handle; if (request_dma(uart->rx_dma_channel, "BFIN_UART_RX") < 0) { printk(KERN_NOTICE "Unable to attach Blackfin UART RX DMA channel\n"); return -EBUSY; } if (request_dma(uart->tx_dma_channel, "BFIN_UART_TX") < 0) { printk(KERN_NOTICE "Unable to attach Blackfin UART TX DMA channel\n"); free_dma(uart->rx_dma_channel); return -EBUSY; } set_dma_callback(uart->rx_dma_channel, bfin_serial_dma_rx_int, uart); set_dma_callback(uart->tx_dma_channel, bfin_serial_dma_tx_int, uart); uart->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, GFP_DMA); uart->rx_dma_buf.head = 0; uart->rx_dma_buf.tail = 0; uart->rx_dma_nrows = 0; set_dma_config(uart->rx_dma_channel, set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO, INTR_ON_ROW, DIMENSION_2D, DATA_SIZE_8, DMA_SYNC_RESTART)); set_dma_x_count(uart->rx_dma_channel, DMA_RX_XCOUNT); set_dma_x_modify(uart->rx_dma_channel, 1); set_dma_y_count(uart->rx_dma_channel, DMA_RX_YCOUNT); set_dma_y_modify(uart->rx_dma_channel, 1); set_dma_start_addr(uart->rx_dma_channel, (unsigned long)uart->rx_dma_buf.buf); enable_dma(uart->rx_dma_channel); uart->rx_dma_timer.data = (unsigned long)(uart); uart->rx_dma_timer.function = (void *)bfin_serial_rx_dma_timeout; uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; add_timer(&(uart->rx_dma_timer)); #else # if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) if (kgdboc_port_line == uart->port.line && kgdboc_break_enabled) kgdboc_break_enabled = 0; else { # endif if (request_irq(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, "BFIN_UART_RX", uart)) { printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); return -EBUSY; } if (request_irq (uart->port.irq+1, bfin_serial_tx_int, IRQF_DISABLED, "BFIN_UART_TX", uart)) { printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n"); free_irq(uart->port.irq, uart); return -EBUSY; } # ifdef CONFIG_BF54x { /* * UART2 and UART3 on BF548 share interrupt PINs and DMA * controllers with SPORT2 and SPORT3. UART rx and tx * interrupts are generated in PIO mode only when configure * their peripheral mapping registers properly, which means * request corresponding DMA channels in PIO mode as well. */ unsigned uart_dma_ch_rx, uart_dma_ch_tx; switch (uart->port.irq) { case IRQ_UART3_RX: uart_dma_ch_rx = CH_UART3_RX; uart_dma_ch_tx = CH_UART3_TX; break; case IRQ_UART2_RX: uart_dma_ch_rx = CH_UART2_RX; uart_dma_ch_tx = CH_UART2_TX; break; default: uart_dma_ch_rx = uart_dma_ch_tx = 0; break; }; if (uart_dma_ch_rx && request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) { printk(KERN_NOTICE"Fail to attach UART interrupt\n"); free_irq(uart->port.irq, uart); free_irq(uart->port.irq + 1, uart); return -EBUSY; } if (uart_dma_ch_tx && request_dma(uart_dma_ch_tx, "BFIN_UART_TX") < 0) { printk(KERN_NOTICE "Fail to attach UART interrupt\n"); free_dma(uart_dma_ch_rx); free_irq(uart->port.irq, uart); free_irq(uart->port.irq + 1, uart); return -EBUSY; } } # endif # if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) } # endif #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS if (uart->cts_pin >= 0) { if (request_irq(gpio_to_irq(uart->cts_pin), bfin_serial_mctrl_cts_int, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED, "BFIN_UART_CTS", uart)) { uart->cts_pin = -1; pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); } } if (uart->rts_pin >= 0) { gpio_direction_output(uart->rts_pin, 0); } #endif #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS if (uart->cts_pin >= 0 && request_irq(uart->status_irq, bfin_serial_mctrl_cts_int, IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) { uart->cts_pin = -1; pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n"); } /* CTS RTS PINs are negative assertive. */ UART_PUT_MCR(uart, ACTS); UART_SET_IER(uart, EDSSI); #endif UART_SET_IER(uart, ERBFI); return 0; }