int demo_open_rt(struct rtdm_dev_context *context, rtdm_user_info_t *user_info, int oflags) { struct demodrv_context *my_context; #ifdef USEMMAP unsigned long vaddr; #endif int dev_id = context->device->device_id; int ret; // get the context for our driver - used to store driver info my_context = (struct demodrv_context *)context->dev_private; #ifdef USEMMAP // allocate and prepare memory for our buffer my_context->buf = kmalloc(BUFFER_SIZE, GFP_KERNEL); /* mark pages reserved so that remap_pfn_range works */ for (vaddr = (unsigned long)my_context->buf; vaddr < (unsigned long)my_context->buf + BUFFER_SIZE; vaddr += PAGE_SIZE) SetPageReserved(virt_to_page(vaddr)); // write some test value to the start of our buffer *(int *)my_context->buf = 1234; my_context->mapped_user_addr = NULL; #endif // we also have an interrupt handler: #ifdef TIMERINT ret = rtdm_irq_request(&my_context->irq_handle, TIMER_INT, demo_interrupt, 0, context->device->proc_name, my_context); #else ret = rtdm_irq_request(&my_context->irq_handle, PAR_INT, demo_interrupt, 0, context->device->proc_name, my_context); #endif if (ret < 0) return ret; /* IPC initialisation - cannot fail with used parameters */ rtdm_lock_init(&my_context->lock); rtdm_event_init(&my_context->irq_event, 0); my_context->dev_id = dev_id; my_context->irq_events = 0; my_context->irq_event_lock = 0; my_context->timeout = 0; // wait INFINITE #ifndef TIMERINT //set port to interrupt mode; pins are output outb_p(0x10, BASEPORT + 2); #endif // enable interrupt in RTDM rtdm_irq_enable(&my_context->irq_handle); return 0; }
static int trigger_init(void) { int err; /*Aquire Trigger input*/ int numero_interruption = gpio_to_irq(MAIN_TRIGGER); if ((err = gpio_request(MAIN_TRIGGER, THIS_MODULE->name)) != 0) { return err; } if ((err = gpio_direction_input(MAIN_TRIGGER)) != 0) { gpio_free(MAIN_TRIGGER); return err; } /*Setup interrupt for TRIGGER*/ irq_set_irq_type(numero_interruption, IRQF_TRIGGER_RISING); if ((err = rtdm_irq_request(&irq_main_trigger, numero_interruption, gpio_interrupt, RTDM_IRQTYPE_EDGE, THIS_MODULE->name, NULL)) != 0) { gpio_free(MAIN_TRIGGER); return err; } return 0; }
static int __init exemple_init (void) { int err; int numero_interruption = gpio_to_irq(GPIO_IN); if ((err = gpio_request(GPIO_IN, THIS_MODULE->name)) != 0) { return err; } if ((err = gpio_direction_input(GPIO_IN)) != 0) { gpio_free(GPIO_IN); return err; } if ((err = gpio_request(GPIO_OUT, THIS_MODULE->name)) != 0) { gpio_free(GPIO_IN); return err; } if ((err = gpio_direction_output(GPIO_OUT, 1)) != 0) { gpio_free(GPIO_OUT); gpio_free(GPIO_IN); return err; } irq_set_irq_type(numero_interruption, 0x00000003); if ((err = rtdm_irq_request(& irq_rtdm, numero_interruption, handler_interruption, RTDM_IRQTYPE_EDGE, THIS_MODULE->name, NULL)) != 0) { gpio_free(GPIO_OUT); gpio_free(GPIO_IN); return err; } return 0; }
static int rt2x00_dev_radio_on(struct _rt2x00_device * device) { struct _rt2x00_pci *rt2x00pci = rt2x00_priv(device); u32 reg = 0x00000000; int retval; if(rt2x00_pci_alloc_rings(device)) goto exit_fail; rt2x00_clear_ring(rt2x00pci, &rt2x00pci->rx); rt2x00_clear_ring(rt2x00pci, &rt2x00pci->tx); rt2x00_init_ring_register(rt2x00pci); if(rt2x00_init_registers(rt2x00pci)) goto exit_fail; rt2x00_init_write_mac(rt2x00pci, device->rtnet_dev); if(rt2x00_init_bbp(rt2x00pci)) goto exit_fail; /* * Clear interrupts. */ rt2x00_register_read(rt2x00pci, CSR7, ®); rt2x00_register_write(rt2x00pci, CSR7, reg); /* Register rtdm-irq */ retval = rtdm_irq_request(&rt2x00pci->irq_handle, device->rtnet_dev->irq, rt2x00_interrupt, 0, device->rtnet_dev->name, device->rtnet_dev); /* * Enable interrupts. */ rt2x00_register_read(rt2x00pci, CSR8, ®); rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, 0); rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, 0); rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); rt2x00_set_field32(®, CSR8_RXDONE, 0); rt2x00_register_write(rt2x00pci, CSR8, reg); rtdm_irq_enable(&rt2x00pci->irq_handle); return 0; exit_fail: rt2x00_pci_free_rings(device); return -ENOMEM; }
static int tulip_open(/*RTnet*/struct rtnet_device *rtdev) { struct tulip_private *tp = (struct tulip_private *)rtdev->priv; int retval; if ((retval = /*RTnet*/rtdm_irq_request(&tp->irq_handle, rtdev->irq, tulip_interrupt, 0, "rt_tulip", rtdev))) { printk("%s: Unable to install ISR for IRQ %d\n", rtdev->name,rtdev->irq); return retval; } rt_stack_connect(rtdev, &STACK_manager); tulip_init_ring (rtdev); tulip_up (rtdev); rtnetif_start_queue (rtdev); return 0; }
/* Initialize the CPM Ethernet on SCC. If EPPC-Bug loaded us, or performed * some other network I/O, a whole bunch of this has already been set up. * It is no big deal if we do it again, we just have to disable the * transmit and receive to make sure we don't catch the CPM with some * inconsistent control information. */ int __init scc_enet_init(void) { struct rtnet_device *rtdev = NULL; struct scc_enet_private *cep; int i, j, k; unsigned char *eap, *ba; dma_addr_t mem_addr; bd_t *bd; volatile cbd_t *bdp; volatile cpm8xx_t *cp; volatile scc_t *sccp; volatile scc_enet_t *ep; volatile immap_t *immap; cp = cpmp; /* Get pointer to Communication Processor */ immap = (immap_t *)(mfspr(IMMR) & 0xFFFF0000); /* and to internal registers */ bd = (bd_t *)__res; /* Configure the SCC parameters (this has formerly be done * by macro definitions). */ switch (rtnet_scc) { case 3: CPM_CR_ENET = CPM_CR_CH_SCC3; PROFF_ENET = PROFF_SCC3; SCC_ENET = 2; /* Index, not number! */ CPMVEC_ENET = CPMVEC_SCC3; break; case 2: CPM_CR_ENET = CPM_CR_CH_SCC2; PROFF_ENET = PROFF_SCC2; SCC_ENET = 1; /* Index, not number! */ CPMVEC_ENET = CPMVEC_SCC2; break; case 1: CPM_CR_ENET = CPM_CR_CH_SCC1; PROFF_ENET = PROFF_SCC1; SCC_ENET = 0; /* Index, not number! */ CPMVEC_ENET = CPMVEC_SCC1; break; default: printk(KERN_ERR "enet: SCC%d doesn't exit (check rtnet_scc)\n", rtnet_scc); return -1; } /* Allocate some private information and create an Ethernet device instance. */ rtdev = rtdev_root = rt_alloc_etherdev(sizeof(struct scc_enet_private)); if (rtdev == NULL) { printk(KERN_ERR "enet: Could not allocate ethernet device.\n"); return -1; } rtdev_alloc_name(rtdev, "rteth%d"); rt_rtdev_connect(rtdev, &RTDEV_manager); RTNET_SET_MODULE_OWNER(rtdev); rtdev->vers = RTDEV_VERS_2_0; cep = (struct scc_enet_private *)rtdev->priv; rtdm_lock_init(&cep->lock); /* Get pointer to SCC area in parameter RAM. */ ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]); /* And another to the SCC register area. */ sccp = (volatile scc_t *)(&cp->cp_scc[SCC_ENET]); cep->sccp = (scc_t *)sccp; /* Keep the pointer handy */ /* Disable receive and transmit in case EPPC-Bug started it. */ sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); /* Cookbook style from the MPC860 manual..... * Not all of this is necessary if EPPC-Bug has initialized * the network. * So far we are lucky, all board configurations use the same * pins, or at least the same I/O Port for these functions..... * It can't last though...... */ #if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD)) /* Configure port A pins for Txd and Rxd. */ immap->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD); immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD); immap->im_ioport.iop_paodr &= ~PA_ENET_TXD; #elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD)) /* Configure port B pins for Txd and Rxd. */ immap->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD); immap->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD); immap->im_cpm.cp_pbodr &= ~PB_ENET_TXD; #else #error Exactly ONE pair of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined #endif #if defined(PC_ENET_LBK) /* Configure port C pins to disable External Loopback */ immap->im_ioport.iop_pcpar &= ~PC_ENET_LBK; immap->im_ioport.iop_pcdir |= PC_ENET_LBK; immap->im_ioport.iop_pcso &= ~PC_ENET_LBK; immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */ #endif /* PC_ENET_LBK */ /* Configure port C pins to enable CLSN and RENA. */ immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); /* Configure port A for TCLK and RCLK. */ immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK); immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. */ cp->cp_sicr &= ~SICR_ENET_MASK; cp->cp_sicr |= SICR_ENET_CLKRT; /* Manual says set SDDR, but I can't find anything with that * name. I think it is a misprint, and should be SDCR. This * has already been set by the communication processor initialization. */ /* Allocate space for the buffer descriptors in the DP ram. * These are relative offsets in the DP ram address space. * Initialize base addresses for the buffer descriptors. */ i = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE); ep->sen_genscc.scc_rbase = i; cep->rx_bd_base = (cbd_t *)&cp->cp_dpmem[i]; i = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE); ep->sen_genscc.scc_tbase = i; cep->tx_bd_base = (cbd_t *)&cp->cp_dpmem[i]; cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; cep->cur_rx = cep->rx_bd_base; /* Issue init Rx BD command for SCC. * Manual says to perform an Init Rx parameters here. We have * to perform both Rx and Tx because the SCC may have been * already running. * In addition, we have to do it later because we don't yet have * all of the BD control/status set properly. cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); */ /* Initialize function code registers for big-endian. */ ep->sen_genscc.scc_rfcr = SCC_EB; ep->sen_genscc.scc_tfcr = SCC_EB; /* Set maximum bytes per receive buffer. * This appears to be an Ethernet frame size, not the buffer * fragment size. It must be a multiple of four. */ ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE; /* Set CRC preset and mask. */ ep->sen_cpres = 0xffffffff; ep->sen_cmask = 0xdebb20e3; ep->sen_crcec = 0; /* CRC Error counter */ ep->sen_alec = 0; /* alignment error counter */ ep->sen_disfc = 0; /* discard frame counter */ ep->sen_pads = 0x8888; /* Tx short frame pad character */ ep->sen_retlim = 15; /* Retry limit threshold */ ep->sen_maxflr = PKT_MAXBUF_SIZE; /* maximum frame length register */ ep->sen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register */ ep->sen_maxd1 = PKT_MAXBLR_SIZE; /* maximum DMA1 length */ ep->sen_maxd2 = PKT_MAXBLR_SIZE; /* maximum DMA2 length */ /* Clear hash tables. */ ep->sen_gaddr1 = 0; ep->sen_gaddr2 = 0; ep->sen_gaddr3 = 0; ep->sen_gaddr4 = 0; ep->sen_iaddr1 = 0; ep->sen_iaddr2 = 0; ep->sen_iaddr3 = 0; ep->sen_iaddr4 = 0; /* Set Ethernet station address. */ eap = (unsigned char *)&(ep->sen_paddrh); #ifdef CONFIG_FEC_ENET /* We need a second MAC address if FEC is used by Linux */ for (i=5; i>=0; i--) *eap++ = rtdev->dev_addr[i] = (bd->bi_enetaddr[i] | (i==3 ? 0x80 : 0)); #else for (i=5; i>=0; i--) *eap++ = rtdev->dev_addr[i] = bd->bi_enetaddr[i]; #endif ep->sen_pper = 0; /* 'cause the book says so */ ep->sen_taddrl = 0; /* temp address (LSB) */ ep->sen_taddrm = 0; ep->sen_taddrh = 0; /* temp address (MSB) */ /* Now allocate the host memory pages and initialize the * buffer descriptors. */ bdp = cep->tx_bd_base; for (i=0; i<TX_RING_SIZE; i++) { /* Initialize the BD for every fragment in the page. */ bdp->cbd_sc = 0; bdp->cbd_bufaddr = 0; bdp++; } /* Set the last buffer to wrap. */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; bdp = cep->rx_bd_base; k = 0; for (i=0; i<CPM_ENET_RX_PAGES; i++) { /* Allocate a page. */ ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr); /* Initialize the BD for every fragment in the page. */ for (j=0; j<CPM_ENET_RX_FRPPG; j++) { bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR; bdp->cbd_bufaddr = mem_addr; cep->rx_vaddr[k++] = ba; mem_addr += CPM_ENET_RX_FRSIZE; ba += CPM_ENET_RX_FRSIZE; bdp++; } } /* Set the last buffer to wrap. */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; /* Let's re-initialize the channel now. We have to do it later * than the manual describes because we have just now finished * the BD initialization. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); cep->skb_cur = cep->skb_dirty = 0; sccp->scc_scce = 0xffff; /* Clear any pending events */ /* Enable interrupts for transmit error, complete frame * received, and any transmit buffer we have also set the * interrupt flag. */ sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB); /* Install our interrupt handler. */ rtdev->irq = CPM_IRQ_OFFSET + CPMVEC_ENET; rt_stack_connect(rtdev, &STACK_manager); if ((i = rtdm_irq_request(&cep->irq_handle, rtdev->irq, scc_enet_interrupt, 0, "rt_mpc8xx_enet", rtdev))) { printk(KERN_ERR "Couldn't request IRQ %d\n", rtdev->irq); rtdev_free(rtdev); return i; } /* Set GSMR_H to enable all normal operating modes. * Set GSMR_L to enable Ethernet to MC68160. */ sccp->scc_gsmrh = 0; sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET); /* Set sync/delimiters. */ sccp->scc_dsr = 0xd555; /* Set processing mode. Use Ethernet CRC, catch broadcast, and * start frame search 22 bit times after RENA. */ sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22); /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. */ #if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA)) immap->im_ioport.iop_pcpar |= PC_ENET_TENA; immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; #elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA)) cp->cp_pbpar |= PB_ENET_TENA; cp->cp_pbdir |= PB_ENET_TENA; #else #error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA #endif #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) /* And while we are here, set the configuration to enable ethernet. */ *((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK; *((volatile uint *)RPX_CSR_ADDR) |= (BCSR0_ETHEN | BCSR0_COLTESTDIS | BCSR0_FULLDPLXDIS); #endif #ifdef CONFIG_BSEIP /* BSE uses port B and C for PHY control. */ cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS); cp->cp_pbdir |= (PB_BSE_POWERUP | PB_BSE_FDXDIS); cp->cp_pbdat |= (PB_BSE_POWERUP | PB_BSE_FDXDIS); immap->im_ioport.iop_pcpar &= ~PC_BSE_LOOPBACK; immap->im_ioport.iop_pcdir |= PC_BSE_LOOPBACK; immap->im_ioport.iop_pcso &= ~PC_BSE_LOOPBACK; immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK; #endif #ifdef CONFIG_FADS cp->cp_pbpar |= PB_ENET_TENA; cp->cp_pbdir |= PB_ENET_TENA; /* Enable the EEST PHY. */ *((volatile uint *)BCSR1) &= ~BCSR1_ETHEN; #endif rtdev->base_addr = (unsigned long)ep; /* The CPM Ethernet specific entries in the device structure. */ rtdev->open = scc_enet_open; rtdev->hard_start_xmit = scc_enet_start_xmit; rtdev->stop = scc_enet_close; rtdev->hard_header = &rt_eth_header; rtdev->get_stats = scc_enet_get_stats; if (!rx_pool_size) rx_pool_size = RX_RING_SIZE * 2; if (rtskb_pool_init(&cep->skb_pool, rx_pool_size) < rx_pool_size) { rtdm_irq_disable(&cep->irq_handle); rtdm_irq_free(&cep->irq_handle); rtskb_pool_release(&cep->skb_pool); rtdev_free(rtdev); return -ENOMEM; } if ((i = rt_register_rtnetdev(rtdev))) { printk(KERN_ERR "Couldn't register rtdev\n"); rtdm_irq_disable(&cep->irq_handle); rtdm_irq_free(&cep->irq_handle); rtskb_pool_release(&cep->skb_pool); rtdev_free(rtdev); return i; } /* And last, enable the transmit and receive processing. */ sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); printk("%s: CPM ENET Version 0.2 on SCC%d, irq %d, addr %02x:%02x:%02x:%02x:%02x:%02x\n", rtdev->name, SCC_ENET+1, rtdev->irq, rtdev->dev_addr[0], rtdev->dev_addr[1], rtdev->dev_addr[2], rtdev->dev_addr[3], rtdev->dev_addr[4], rtdev->dev_addr[5]); return 0; }
static int uart_open_nrt(struct rtdm_dev_context *context,rtdm_user_info_t *user_info_t,int oflags_t) { MY_DEV *up=(MY_DEV *)context->device->device_data; // rtdm_lockctx_t context1; int retval; printk("Local struct up=%x\n",up); f_cir_buf(up); rtdm_lock_init(&up->lock); rtdm_event_init(&up->w_event_tx,0); rtdm_event_init(&up->w_event_rx,0); printk("name of irq=%s\n",up->name); retval = request_irq(up->irq, serial_omap_irq,0, up->name, up); // if (retval) // return retval; retval=rtdm_irq_request(&up->irq_handle,up->irq,rtdm_my_isr,0,up->name,up); if(retval<0) { rtdm_printk("error in requesting irq\n"); dev_err(up->dev, "failure requesting irq %i\n", up->irq); return retval; } dev_dbg(up->dev, "serial_omap_startup+%d\n", up->line); serial_omap_clear_fifos(up); serial_out(up,UART_MCR,UART_MCR_RTS); (void)serial_in(up,UART_LSR); if(serial_in(up,UART_LSR) & UART_LSR_DR) (void)serial_in(up,UART_RX); (void)serial_in(up,UART_IIR); (void)serial_in(up,UART_MSR); /* * Now, initialize the UART */ serial_out(up, UART_LCR, UART_LCR_WLEN8); printk("UART has word length of 8 bit\n"); up->msr_saved_flags=0; //enabling interrupts up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up,UART_IER,up->ier); printk("enabling RLSI and RDI interrupt\n"); //enable module level wake up serial_out(up,UART_OMAP_WER,OMAP_UART_WER_MOD_WKUP); printk("OMAP_UART_WER_MOD_WKUP\n"); // up->port_activity=jiffies; return 0; }
int init_mpu9150_irq(void) { void __iomem *mem; int retval, irq; uint regval; rtdm_printk("MPU9150-IRQ: Initializing interrupt interface...\n"); // Preliminary Setup: Step 1: Create a message pipe for use within the ISR retval = rt_pipe_create(&pipe_desc, "mpu9150", P_MINOR_AUTO, MPU9150_FIFO_DEPTH+synchSize); if( retval ) { rtdm_printk("MPU9150-IRQ: Error: Failed to create data flow pipe\n"); return retval; } // 1st Step: Request the GPIO lines for the IRQ channels and create the IRQ object retval = gpio_request_one(mpu9150_irq_desc.gpio_desc.gpio, mpu9150_irq_desc.gpio_desc.flags, mpu9150_irq_desc.gpio_desc.label); if(retval != 0) { irq_gpio_requested = 0; rtdm_printk("MPU9150-IRQ: Error: Failed to request GPIO pin#%i for IRQ (error %i)\n", mpu9150_irq_desc.gpio_desc.gpio, retval); return retval; } irq_gpio_requested = 1; irq = gpio_to_irq( mpu9150_irq_desc.gpio_desc.gpio ); if(irq >= 0) { irq_requested = 1; if((retval = rtdm_irq_request(&mpu9150_irq, irq, mpu9150_irq_desc.isr, 0, mpu9150_irq_desc.gpio_desc.label, NULL)) < 0) { switch( retval ) { case -EINVAL: rtdm_printk("MPU9150-IRQ: ERROR: Invalid parameter was given to rtdm_irq_request().\n"); break; case -EBUSY: rtdm_printk("MPU9150-IRQ: ERROR: The requested IRQ line#%i from GPIO#%i is already in use\n", irq, mpu9150_irq_desc.gpio_desc.gpio); break; default: rtdm_printk("MPU9150-IRQ: Unknown error occurred while requesting RTDM IRQ.\n"); } return retval; } rtdm_printk("MPU9150-IRQ: Initialized GPIO #%i to IRQ #%i\n", mpu9150_irq_desc.gpio_desc.gpio, irq); } else { irq_requested = 0; rtdm_printk("MPU9150-IRQ: ERROR: Failed to obtain IRQ number for GPIO #%i (error %i)\n", mpu9150_irq_desc.gpio_desc.gpio, retval); return retval; } // 2nd Step: Configure the pin for GPIO input rtdm_printk("MPU9150-IRQ: Configuring IRQ GPIO pin as follows: SLEW_FAST | INPUT_EN | PULLUP | PULLUPDOWN_DIS | MODE_7....\n"); mem = ioremap(GPMC_CONF_ADDR_START, GPMC_CONF_ADDR_SIZE); if( !mem ) { rtdm_printk("MPU9150-IRQ: ERROR: Failed to remap memory for IRQ pin configuration.\n"); return -ENOMEM; } // Configure GPIO2_4 pin 0-7 output // Write the pin configuration iowrite8((SLEW_FAST | INPUT_EN | PULLUP | PULLUPDOWN_DIS | M7), mem + CONF_GPMC_WEN); // close the pin conf address space iounmap( mem ); // GPIO Bank 2: Setup the IRQ registers with the appropriate values mem = ioremap(GPIO2_START_ADDR, GPIO2_SIZE); if( !mem ) { rtdm_printk("MPU9150-IRQ: ERROR: Failed to remap memory for GPIO Bank 2 IRQ pin configuration.\n"); return -ENOMEM; } // Enable the IRQ ability for GPIO2_4 regval = ioread32(mem + GPIO_IRQSTATUS_0); regval |= GPIO_4; iowrite32(regval, mem + GPIO_IRQSTATUS_0); // Set Pin 4 for rising- and falling- edge detection regval = ioread32(mem + GPIO_RISINGDETECT); regval |= GPIO_4; iowrite32(regval, mem + GPIO_RISINGDETECT); // Release the mapped memory iounmap( mem ); // 3rd Step: Setup the IRQ controller to read the H/W interrupts mem = ioremap(INTC_REG_START, INTC_REG_SIZE); if( !mem ) { rtdm_printk("MPU9150-IRQ: ERROR: Failed to remap IRQ Control Registers memory\n"); return -ENOMEM; } // Disable clock gating strategy for the. Will use more // power with this strategy disabled, but will decrease // latency. iowrite32(0x0, mem + INTC_SYSCONFIG); // Disable the input synchronizer auto-gating and the // functional clock auto-idle modes. This will use more // power, but will decrease latency. iowrite32(0x1, mem + INTC_IDLE); // For each IRQ line, set the highest priority (0) and // route to the IRQ, not the FIQ (GPIOs cannot be routed // to FIQ) iowrite8(0x0, mem + INTC_ILR68); // Unmask the the GPIO lines to enable interrupts on those GPIO lines iowrite32(GPIO_4, mem + INTC_MIR_CLEAR2); // Close the IRQ Control registers memory iounmap( mem ); rtdm_printk("MPU9150-IRQ: Interrupt interface initialization complete!\n"); return 0; }