From 323835b45793a71ce6b47ac105a44258c1db0569 Mon Sep 17 00:00:00 2001 From: Erwan Bracq Date: Sat, 23 Apr 2011 12:32:31 +0200 Subject: CAIF: Minor alignment with internal CAIF git Some added blank line and BUGON for CAIF serial. Change-Id: If3452ed104b93203fc86fe6a95fd957946447876 Signed-off-by: Erwan Bracq Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/21527 Reviewed-by: QATEST Reviewed-by: Jonas ABERG --- drivers/net/caif/caif_serial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 23406e62c0b..1738685d586 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -182,6 +182,7 @@ static void ldisc_receive(struct tty_struct *tty, const u8 *data, * This is not yet handled. */ + BUG_ON(ser->dev == NULL); /* * Workaround for garbage at start of transmission, -- cgit v1.2.3 From d5d8255d87dd72e163350b36d5cc2720699a34e1 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Wed, 11 May 2011 10:01:12 +0200 Subject: CAIF: Alignment with internal CAIF development git Code changes from internal git that will / are submitted to kernel upstream. - CAIF SPI. Multiple bug fixes, power management. Change-Id: I7e0f989ec5508358efeb3459c561d40dc94ed0a8 Signed-off-by: Erwan Bracq Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/21536 Reviewed-by: QATEST Reviewed-by: Jonas ABERG --- drivers/net/caif/caif_spi.c | 176 +++++++++++++++++++------------------- drivers/net/caif/caif_spi_slave.c | 8 +- include/net/caif/caif_spi.h | 5 +- 3 files changed, 97 insertions(+), 92 deletions(-) diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index 0f8defc7330..40fb6249c0d 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -226,7 +226,7 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf, "Tx data (Len: %d):\n", cfspi->tx_cpck_len); len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), - cfspi->xfer.va_tx, + cfspi->xfer.va_tx[0], (cfspi->tx_cpck_len + SPI_CMD_SZ), 100); len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), @@ -599,48 +599,11 @@ static int cfspi_close(struct net_device *dev) netif_stop_queue(dev); return 0; } -static const struct net_device_ops cfspi_ops = { - .ndo_open = cfspi_open, - .ndo_stop = cfspi_close, - .ndo_start_xmit = cfspi_xmit -}; -static void cfspi_setup(struct net_device *dev) +static int cfspi_init(struct net_device *dev) { + int res = 0; struct cfspi *cfspi = netdev_priv(dev); - dev->features = 0; - dev->netdev_ops = &cfspi_ops; - dev->type = ARPHRD_CAIF; - dev->flags = IFF_NOARP | IFF_POINTOPOINT; - dev->tx_queue_len = 0; - dev->mtu = SPI_MAX_PAYLOAD_SIZE; - dev->destructor = free_netdev; - skb_queue_head_init(&cfspi->qhead); - skb_queue_head_init(&cfspi->chead); - cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW; - cfspi->cfdev.use_frag = false; - cfspi->cfdev.use_stx = false; - cfspi->cfdev.use_fcs = false; - cfspi->ndev = dev; -} - -int cfspi_spi_probe(struct platform_device *pdev) -{ - struct cfspi *cfspi = NULL; - struct net_device *ndev; - struct cfspi_dev *dev; - int res; - dev = (struct cfspi_dev *)pdev->dev.platform_data; - - ndev = alloc_netdev(sizeof(struct cfspi), - "cfspi%d", cfspi_setup); - if (!ndev) - return -ENOMEM; - - cfspi = netdev_priv(ndev); - netif_stop_queue(ndev); - cfspi->ndev = ndev; - cfspi->pdev = pdev; /* Set flow info. */ cfspi->flow_off_sent = 0; @@ -656,18 +619,13 @@ int cfspi_spi_probe(struct platform_device *pdev) cfspi->slave_talked = false; } - /* Assign the SPI device. */ - cfspi->dev = dev; - /* Assign the device ifc to this SPI interface. */ - dev->ifc = &cfspi->ifc; - /* Allocate DMA buffers. */ - cfspi->xfer.va_tx = dma_alloc(&cfspi->xfer.pa_tx); - if (!cfspi->xfer.va_tx) { + cfspi->xfer.va_tx[0] = dma_alloc(&cfspi->xfer.pa_tx[0]); + if (!cfspi->xfer.va_tx[0]) { printk(KERN_WARNING "CFSPI: failed to allocate dma TX buffer.\n"); res = -ENODEV; - goto err_dma_alloc_tx; + goto err_dma_alloc_tx_0; } cfspi->xfer.va_rx = dma_alloc(&cfspi->xfer.pa_rx); @@ -718,6 +676,87 @@ int cfspi_spi_probe(struct platform_device *pdev) /* Schedule the work queue. */ queue_work(cfspi->wq, &cfspi->work); + return 0; + + err_create_wq: + dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx); + err_dma_alloc_rx: + dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]); + err_dma_alloc_tx_0: + return res; +} + +static void cfspi_uninit(struct net_device *dev) +{ + struct cfspi *cfspi = netdev_priv(dev); + + /* Remove from list. */ + spin_lock(&cfspi_list_lock); + list_del(&cfspi->list); + spin_unlock(&cfspi_list_lock); + + cfspi->ndev = NULL; + /* Free DMA buffers. */ + dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx); + dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]); + set_bit(SPI_TERMINATE, &cfspi->state); + wake_up_interruptible(&cfspi->wait); + destroy_workqueue(cfspi->wq); + /* Destroy debugfs directory and files. */ + dev_debugfs_rem(cfspi); + return; +} + +static const struct net_device_ops cfspi_ops = { + .ndo_open = cfspi_open, + .ndo_stop = cfspi_close, + .ndo_init = cfspi_init, + .ndo_uninit = cfspi_uninit, + .ndo_start_xmit = cfspi_xmit +}; + +static void cfspi_setup(struct net_device *dev) +{ + struct cfspi *cfspi = netdev_priv(dev); + dev->features = 0; + dev->netdev_ops = &cfspi_ops; + dev->type = ARPHRD_CAIF; + dev->flags = IFF_NOARP | IFF_POINTOPOINT; + dev->tx_queue_len = 0; + dev->mtu = SPI_MAX_PAYLOAD_SIZE; + dev->destructor = free_netdev; + skb_queue_head_init(&cfspi->qhead); + skb_queue_head_init(&cfspi->chead); + cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW; + cfspi->cfdev.use_frag = false; + cfspi->cfdev.use_stx = false; + cfspi->cfdev.use_fcs = false; + cfspi->ndev = dev; +} + +int cfspi_spi_probe(struct platform_device *pdev) +{ + struct cfspi *cfspi = NULL; + struct net_device *ndev; + struct cfspi_dev *dev; + int res; + dev = (struct cfspi_dev *)pdev->dev.platform_data; + + ndev = alloc_netdev(sizeof(struct cfspi), + "cfspi%d", cfspi_setup); + if (!dev) + return -ENODEV; + + cfspi = netdev_priv(ndev); + netif_stop_queue(ndev); + cfspi->ndev = ndev; + cfspi->pdev = pdev; + + /* Assign the SPI device. */ + cfspi->dev = dev; + /* Assign the device ifc to this SPI interface. */ + dev->ifc = &cfspi->ifc; + /* Register network device. */ res = register_netdev(ndev); if (res) { @@ -727,15 +766,6 @@ int cfspi_spi_probe(struct platform_device *pdev) return res; err_net_reg: - dev_debugfs_rem(cfspi); - set_bit(SPI_TERMINATE, &cfspi->state); - wake_up_interruptible(&cfspi->wait); - destroy_workqueue(cfspi->wq); - err_create_wq: - dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx); - err_dma_alloc_rx: - dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx); - err_dma_alloc_tx: free_netdev(ndev); return res; @@ -743,34 +773,8 @@ int cfspi_spi_probe(struct platform_device *pdev) int cfspi_spi_remove(struct platform_device *pdev) { - struct list_head *list_node; - struct list_head *n; - struct cfspi *cfspi = NULL; - struct cfspi_dev *dev; - - dev = (struct cfspi_dev *)pdev->dev.platform_data; - spin_lock(&cfspi_list_lock); - list_for_each_safe(list_node, n, &cfspi_list) { - cfspi = list_entry(list_node, struct cfspi, list); - /* Find the corresponding device. */ - if (cfspi->dev == dev) { - /* Remove from list. */ - list_del(list_node); - /* Free DMA buffers. */ - dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx); - dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx); - set_bit(SPI_TERMINATE, &cfspi->state); - wake_up_interruptible(&cfspi->wait); - destroy_workqueue(cfspi->wq); - /* Destroy debugfs directory and files. */ - dev_debugfs_rem(cfspi); - unregister_netdev(cfspi->ndev); - spin_unlock(&cfspi_list_lock); - return 0; - } - } - spin_unlock(&cfspi_list_lock); - return -ENODEV; + /* Everything is done in cfspi_uninit(). */ + return 0; } static void __exit cfspi_exit_module(void) @@ -781,7 +785,7 @@ static void __exit cfspi_exit_module(void) list_for_each_safe(list_node, n, &cfspi_list) { cfspi = list_entry(list_node, struct cfspi, list); - platform_device_unregister(cfspi->pdev); + unregister_netdev(cfspi->ndev); } /* Destroy sysfs files. */ diff --git a/drivers/net/caif/caif_spi_slave.c b/drivers/net/caif/caif_spi_slave.c index e139e133fc7..3baa572407c 100644 --- a/drivers/net/caif/caif_spi_slave.c +++ b/drivers/net/caif/caif_spi_slave.c @@ -85,13 +85,13 @@ void cfspi_xfer(struct work_struct *work) #if CFSPI_DBG_PREFILL /* Prefill buffers for easier debugging. */ - memset(cfspi->xfer.va_tx, 0xFF, SPI_DMA_BUF_LEN); + memset(cfspi->xfer.va_tx[0], 0xFF, SPI_DMA_BUF_LEN); memset(cfspi->xfer.va_rx, 0xFF, SPI_DMA_BUF_LEN); #endif /* CFSPI_DBG_PREFILL */ cfspi_dbg_state(cfspi, CFSPI_STATE_AWAKE); - /* Check whether we have a committed frame. */ + /* Check whether we have a committed frame. */ if (cfspi->tx_cpck_len) { int len; @@ -102,7 +102,7 @@ void cfspi_xfer(struct work_struct *work) ptr += SPI_IND_SZ; len = cfspi_xmitfrm(cfspi, ptr, cfspi->tx_cpck_len); WARN_ON(len != cfspi->tx_cpck_len); - } + } cfspi_dbg_state(cfspi, CFSPI_STATE_GET_NEXT); @@ -115,7 +115,7 @@ void cfspi_xfer(struct work_struct *work) * Add indication and length at the beginning of the frame, * using little endian. */ - ptr = (u8 *) cfspi->xfer.va_tx; + ptr = (u8 *) cfspi->xfer.va_tx[0]; *ptr++ = SPI_CMD_IND; *ptr++ = (SPI_CMD_IND & 0xFF00) >> 8; *ptr++ = cfspi->tx_npck_len & 0x00FF; diff --git a/include/net/caif/caif_spi.h b/include/net/caif/caif_spi.h index 87c3d11b8e5..914810614d0 100644 --- a/include/net/caif/caif_spi.h +++ b/include/net/caif/caif_spi.h @@ -55,10 +55,11 @@ struct cfspi_xfer { u16 tx_dma_len; u16 rx_dma_len; - void *va_tx; - dma_addr_t pa_tx; + void *va_tx[2]; + dma_addr_t pa_tx[2]; void *va_rx; dma_addr_t pa_rx; + int idx_tx; }; /* Structure implemented by the SPI interface. */ -- cgit v1.2.3 From 37467e539596eafa87e884e85da7237080dd13df Mon Sep 17 00:00:00 2001 From: Arun Murthy Date: Fri, 9 Sep 2011 18:49:22 +0530 Subject: caif-shm: Fix deadlock caused due to improper locking Improper usage of spin lock, which leads to deadlock. Tx: acquire_lock1 -> trying to acquire lock2 Rx: acquire_lock2 -> trying to acquire lock1 Fix: locking was done through out the function which is not required. Only in placed where list has be accessed or modified locking is required. ST-Ericsson Linux next: NA ST-Ericsson ID: 360284 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I962fcb35f44b6030d6f1151f118d35e328b69156 Signed-off-by: Arun Murthy Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30980 Reviewed-by: Hemant-vilas RAMDASI Tested-by: Hemant-vilas RAMDASI Reviewed-by: Durga Prasada Rao BATHINA --- drivers/net/caif/caif_shmcore.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index d4b26fb24ed..27392cd05fd 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c @@ -238,11 +238,11 @@ int caif_shmdrv_rx_cb(u32 mbx_msg, void *priv) if ((avail_emptybuff > HIGH_WATERMARK) && (!pshm_drv->tx_empty_available)) { pshm_drv->tx_empty_available = 1; + spin_unlock_irqrestore(&pshm_drv->lock, flags); pshm_drv->cfdev.flowctrl (pshm_drv->pshm_dev->pshm_netdev, CAIF_FLOW_ON); - spin_unlock_irqrestore(&pshm_drv->lock, flags); /* Schedule the work queue. if required */ if (!work_pending(&pshm_drv->shm_tx_work)) @@ -285,6 +285,7 @@ static void shm_rx_work_func(struct work_struct *rx_work) list_entry(pshm_drv->rx_full_list.next, struct buf_list, list); list_del_init(&pbuf->list); + spin_unlock_irqrestore(&pshm_drv->lock, flags); /* Retrieve pointer to start of the packet descriptor area. */ pck_desc = (struct shm_pck_desc *) pbuf->desc_vptr; @@ -360,6 +361,7 @@ static void shm_rx_work_func(struct work_struct *rx_work) pck_desc++; } + spin_lock_irqsave(&pshm_drv->lock, flags); list_add_tail(&pbuf->list, &pshm_drv->rx_pend_list); spin_unlock_irqrestore(&pshm_drv->lock, flags); @@ -412,7 +414,6 @@ static void shm_tx_work_func(struct work_struct *tx_work) if (skb == NULL) goto send_msg; - /* Check the available no. of buffers in the empty list */ list_for_each(pos, &pshm_drv->tx_empty_list) avail_emptybuff++; @@ -421,9 +422,11 @@ static void shm_tx_work_func(struct work_struct *tx_work) pshm_drv->tx_empty_available) { /* Update blocking condition. */ pshm_drv->tx_empty_available = 0; + spin_unlock_irqrestore(&pshm_drv->lock, flags); pshm_drv->cfdev.flowctrl (pshm_drv->pshm_dev->pshm_netdev, CAIF_FLOW_OFF); + spin_lock_irqsave(&pshm_drv->lock, flags); } /* * We simply return back to the caller if we do not have space @@ -512,16 +515,11 @@ send_msg: static int shm_netdev_tx(struct sk_buff *skb, struct net_device *shm_netdev) { struct shmdrv_layer *pshm_drv; - unsigned long flags = 0; pshm_drv = netdev_priv(shm_netdev); - spin_lock_irqsave(&pshm_drv->lock, flags); - skb_queue_tail(&pshm_drv->sk_qhead, skb); - spin_unlock_irqrestore(&pshm_drv->lock, flags); - /* Schedule Tx work queue. for deferred processing of skbs*/ if (!work_pending(&pshm_drv->shm_tx_work)) queue_work(pshm_drv->pshm_tx_workqueue, &pshm_drv->shm_tx_work); -- cgit v1.2.3 From 7dd431c4691793b86b628a0d2f0f7a11416eaa93 Mon Sep 17 00:00:00 2001 From: Durga Prasada Rao BATHINA Date: Wed, 24 Aug 2011 19:34:19 +0530 Subject: CAIF SHM: coverity issues dereferencing NULL pointer,if skb_dequeue returns NULL. ST-Ericsson ID: 358051 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: NA Change-Id: Ib88648e68c631cc8eaf839f96af7e847c12922b1 Signed-off-by: Durga Prasada Rao BATHINA Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/31750 Reviewed-by: Bibek BASU Tested-by: Bibek BASU --- drivers/net/caif/caif_shmcore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index 27392cd05fd..7fe33417997 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c @@ -472,6 +472,8 @@ static void shm_tx_work_func(struct work_struct *tx_work) } skb = skb_dequeue(&pshm_drv->sk_qhead); + if (skb == NULL) + break; /* Copy in CAIF frame. */ skb_copy_bits(skb, 0, pbuf->desc_vptr + pbuf->frm_ofs + SHM_HDR_LEN + -- cgit v1.2.3 From 45edfaa5dbdebb38d0eddd6d30e9d323e697b655 Mon Sep 17 00:00:00 2001 From: Durga Prasada Rao BATHINA Date: Wed, 24 Aug 2011 19:17:21 +0530 Subject: CAIF : coverity issues free phy_driver memory and initialize linkid to 0. ST-Ericsson ID: 358047 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: NA Change-Id: Icb295648b23bd836b9f5a40a0b605e4792a8511d Signed-off-by: Durga Prasada Rao BATHINA Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/31751 Reviewed-by: Bibek BASU Tested-by: Bibek BASU --- include/net/caif/cfserl.h | 1 + net/caif/cfcnfg.c | 2 ++ net/caif/cfserl.c | 6 ++++++ 3 files changed, 9 insertions(+) diff --git a/include/net/caif/cfserl.h b/include/net/caif/cfserl.h index b8374321b36..8ac284c5de2 100644 --- a/include/net/caif/cfserl.h +++ b/include/net/caif/cfserl.h @@ -9,4 +9,5 @@ #include struct cflayer *cfserl_create(int type, int instance, bool use_stx); +void cfserl_destroy(struct cflayer *layer); #endif /* CFSERL_H_ */ diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 52fe33bee02..7debfd4a031 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -521,6 +521,8 @@ got_phyid: frml = cffrml_create(phyid, fcs); if (!frml) { + if (phy_driver) + cfserl_destroy(phy_driver); pr_warn("Out of memory\n"); kfree(phyinfo); goto out; diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c index 2715c84cfa8..403d57ad305 100644 --- a/net/caif/cfserl.c +++ b/net/caif/cfserl.c @@ -190,3 +190,9 @@ static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, { layr->up->ctrlcmd(layr->up, ctrl, phyid); } + +void cfserl_destroy(struct cflayer *layer) +{ + struct cfserl *cfserl = container_obj(layer); + kfree(cfserl); +} -- cgit v1.2.3 From 242d6610ee69a048de8bbbd84d78fc819fa4df08 Mon Sep 17 00:00:00 2001 From: Bibek Basu Date: Wed, 17 Aug 2011 15:54:00 +0530 Subject: ux500_ing05160_mailboxPD_0.1:Lockdeb correctness fix for modem_irq Commit ID: Ib94dcbf6: U5500 : Lockdeb correctness fix for modem_irq Build and boot test only done for 8500 config Booting will only happend properly if used Initramfs Change-Id: I5da03baa7b8ee8f32de5712b7136442fbe2cec1c Signed-off-by: Bibek Basu Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/28923 --- drivers/net/caif/caif_shmcore.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index 7fe33417997..d20711f3a13 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c @@ -606,6 +606,7 @@ int caif_shmcore_probe(struct shmdev_layer *pshm_dev) pshm_drv->shm_rx_addr = pshm_dev->shm_base_addr + (NR_TX_BUF * TX_BUF_SZ); + spin_lock_init(&pshm_drv->lock); INIT_LIST_HEAD(&pshm_drv->tx_empty_list); INIT_LIST_HEAD(&pshm_drv->tx_pend_list); INIT_LIST_HEAD(&pshm_drv->tx_full_list); -- cgit v1.2.3