From 5af1f6af3f137719b431ed5e99ea6c4b0d921b5e Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 5 Sep 2011 15:14:06 +0200 Subject: cleopatre/devkit/plcdrv: change open and stop sequences, refs #2701 Most notable change: request IRQ before their first use, release them after their last use. --- cleopatre/devkit/plcdrv/arm/src/linux_drv.c | 98 ++++++++++++++--------------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c index 11fa1c8029..970afd8f04 100644 --- a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c +++ b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c @@ -1582,9 +1582,16 @@ int plcdrv_open(struct net_device *dev) return -EPERM; } + //Prepare mutex + spin_lock_init(&priv->lock); + //Prepare sk_buff in used list INIT_LIST_HEAD(&priv->list_head_skbs); + //Configure AFE with the default configuration + if (init_afe()) + return -EFAULT; + //Allocate rings for each mailbox if((priv->virt_ring_base_addr = (uint32_t)dma_alloc_coherent(NULL, @@ -1601,34 +1608,49 @@ int plcdrv_open(struct net_device *dev) //Flush rings for each mailbox memset((void*)priv->virt_ring_base_addr, 0, A2L_RING_SIZE+L2A_RING_SIZE); - //Configure AFE with the default configuration - if (init_afe()) - return -EFAULT; + //Request Receive IRQ + if(request_irq(priv->num_mbx_it, plcdrv_it_rx, 0, dev->name, dev) != 0) + { + printk(KERN_ERR DRV_NAME ": %s - interrupt %d request fail\n", dev->name, dev->irq); + result = -ENODEV; + goto err_open; + } - //Prepare mutex - spin_lock_init(&priv->lock); + //Request Transmit Acknowledge IRQ + if(request_irq(priv->num_mbx_it_ack, plcdrv_it_txdone, 0, dev->name, dev) != 0) + { + printk(KERN_ERR DRV_NAME ": %s - interrupt %d request fail\n", dev->name, dev->irq); + result = -ENODEV; + goto err_rq_ack; + } - //Prepare init structure from lower layers - info.ring_base_addr = priv->virt_ring_base_addr; - info.phys_ring_base_addr = priv->phys_ring_base_addr; - info.mbx_reg_base_addr = dev->base_addr; - info.debug_mode = debug; - info.launch_leon = &plcdrv_launch_leon; - memcpy(info.mac_addr, dev->dev_addr, sizeof(info.mac_addr)); + //Request Leon Watchdog IRQ + if(request_irq(priv->num_mbx_it_wd, plcdrv_it_wd, 0, dev->name, dev) != 0) + { + printk(KERN_ERR DRV_NAME ": %s - interrupt %d request fail\n", dev->name, dev->irq); + result = -ENODEV; + goto err_rq_wd; + } //Unreset Leon Processor if(plcdrv_reset_leon(0)) { result = -1; - goto err_open; + goto err_rq_wd; } //Start lower Layers + info.ring_base_addr = priv->virt_ring_base_addr; + info.phys_ring_base_addr = priv->phys_ring_base_addr; + info.mbx_reg_base_addr = dev->base_addr; + info.debug_mode = debug; + info.launch_leon = &plcdrv_launch_leon; + memcpy(info.mac_addr, dev->dev_addr, sizeof(info.mac_addr)); if(processing_init(&info, dev)) { printk(KERN_ERR DRV_NAME ": %s: Error initializing hardware (firmware)\n", dev->name); result = -1; - goto err_open; + goto err_rq_wd; } //Allocate RX buffer pool to give to CESAR @@ -1638,7 +1660,7 @@ int plcdrv_open(struct net_device *dev) { printk(KERN_ERR DRV_NAME ": %s: Error creating DATA buffer pool\n", dev->name); result = -1; - goto err_open; + goto err_rq_wd; } // update plc stats priv->plc_stats.rx_pool++; @@ -1649,7 +1671,7 @@ int plcdrv_open(struct net_device *dev) { printk(KERN_ERR DRV_NAME ": %s: Error creating MME buffer pool\n", dev->name); result = -1; - goto err_open; + goto err_rq_wd; } } for(i=0 ; iname); result = -1; - goto err_open; + goto err_rq_wd; } // update plc stats priv->plc_stats.rx_pool++; } - //Prepare Linux as link up - netif_carrier_on(dev); - netif_start_queue(dev); - - //Request Receive IRQ - if(request_irq(priv->num_mbx_it, plcdrv_it_rx, 0, dev->name, dev) != 0) - { - printk(KERN_ERR DRV_NAME ": %s - interrupt %d request fail\n", dev->name, dev->irq); - result = -ENODEV; - goto err_open; - } - - //Request Transmit Acknowledge IRQ - if(request_irq(priv->num_mbx_it_ack, plcdrv_it_txdone, 0, dev->name, dev) != 0) - { - printk(KERN_ERR DRV_NAME ": %s - interrupt %d request fail\n", dev->name, dev->irq); - result = -ENODEV; - goto err_rq_ack; - } - - //Request Leon Watchdog IRQ - if(request_irq(priv->num_mbx_it_wd, plcdrv_it_wd, 0, dev->name, dev) != 0) - { - printk(KERN_ERR DRV_NAME ": %s - interrupt %d request fail\n", dev->name, dev->irq); - result = -ENODEV; - goto err_rq_wd; - } - //Enable tasklet for reception tasklet_enable(&priv->tasklet_it_rx); @@ -1699,6 +1693,10 @@ int plcdrv_open(struct net_device *dev) priv->nl_drv_sock = netlink_kernel_create(&init_net, NETLINK_PLC_DRV, 0, plcdrv_netlink_drv_tx, NULL, THIS_MODULE); priv->nl_mme_sock = netlink_kernel_create(&init_net, NETLINK_PLC_MME, 0, plcdrv_netlink_mme_tx, NULL, THIS_MODULE); + //Prepare Linux as link up + netif_carrier_on(dev); + netif_start_queue(dev); + return 0; err_rq_wd: @@ -1744,11 +1742,6 @@ int plcdrv_stop(struct net_device *dev) //Stop tasklet for reception tasklet_disable(&priv->tasklet_it_rx); - //Disconnect from IRQ - free_irq(priv->num_mbx_it, dev); - free_irq(priv->num_mbx_it_ack, dev); - free_irq(priv->num_mbx_it_wd, dev); - //Stop lower layers processing_uninit(); @@ -1757,6 +1750,11 @@ int plcdrv_stop(struct net_device *dev) plcdrv_reset_dsp(1); plcdrv_reset_dsp(0); + //Disconnect from IRQ + free_irq(priv->num_mbx_it, dev); + free_irq(priv->num_mbx_it_ack, dev); + free_irq(priv->num_mbx_it_wd, dev); + //Free mailboxes ring dma_free_coherent(NULL, A2L_RING_SIZE+L2A_RING_SIZE, -- cgit v1.2.3