aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/caif
diff options
context:
space:
mode:
authorErwan Bracq <erwan.bracq@stericsson.com>2011-12-06 02:25:05 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-06 13:34:12 -0500
commitd5f43c1ea4260807a894150b680fa0a0dd386259 (patch)
treec777acc31527351630775b1a3f4b5c33322ecb84 /drivers/net/caif
parent9e998a7550b41b303c5aa5351e66ccd56f2e4c50 (diff)
caif-spi: Bugfix for dump upon device removal
Fix dump upon device removal, by moving deinitialization from platform-device-remove to network-interface-uninit. Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/caif')
-rw-r--r--drivers/net/caif/caif_spi.c176
1 files changed, 90 insertions, 86 deletions
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
index 05e791f46aef..761057b6f267 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,
226 "Tx data (Len: %d):\n", cfspi->tx_cpck_len); 226 "Tx data (Len: %d):\n", cfspi->tx_cpck_len);
227 227
228 len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), 228 len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len),
229 cfspi->xfer.va_tx, 229 cfspi->xfer.va_tx[0],
230 (cfspi->tx_cpck_len + SPI_CMD_SZ), 100); 230 (cfspi->tx_cpck_len + SPI_CMD_SZ), 100);
231 231
232 len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), 232 len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
@@ -599,48 +599,11 @@ static int cfspi_close(struct net_device *dev)
599 netif_stop_queue(dev); 599 netif_stop_queue(dev);
600 return 0; 600 return 0;
601} 601}
602static const struct net_device_ops cfspi_ops = {
603 .ndo_open = cfspi_open,
604 .ndo_stop = cfspi_close,
605 .ndo_start_xmit = cfspi_xmit
606};
607 602
608static void cfspi_setup(struct net_device *dev) 603static int cfspi_init(struct net_device *dev)
609{ 604{
605 int res = 0;
610 struct cfspi *cfspi = netdev_priv(dev); 606 struct cfspi *cfspi = netdev_priv(dev);
611 dev->features = 0;
612 dev->netdev_ops = &cfspi_ops;
613 dev->type = ARPHRD_CAIF;
614 dev->flags = IFF_NOARP | IFF_POINTOPOINT;
615 dev->tx_queue_len = 0;
616 dev->mtu = SPI_MAX_PAYLOAD_SIZE;
617 dev->destructor = free_netdev;
618 skb_queue_head_init(&cfspi->qhead);
619 skb_queue_head_init(&cfspi->chead);
620 cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
621 cfspi->cfdev.use_frag = false;
622 cfspi->cfdev.use_stx = false;
623 cfspi->cfdev.use_fcs = false;
624 cfspi->ndev = dev;
625}
626
627int cfspi_spi_probe(struct platform_device *pdev)
628{
629 struct cfspi *cfspi = NULL;
630 struct net_device *ndev;
631 struct cfspi_dev *dev;
632 int res;
633 dev = (struct cfspi_dev *)pdev->dev.platform_data;
634
635 ndev = alloc_netdev(sizeof(struct cfspi),
636 "cfspi%d", cfspi_setup);
637 if (!ndev)
638 return -ENOMEM;
639
640 cfspi = netdev_priv(ndev);
641 netif_stop_queue(ndev);
642 cfspi->ndev = ndev;
643 cfspi->pdev = pdev;
644 607
645 /* Set flow info. */ 608 /* Set flow info. */
646 cfspi->flow_off_sent = 0; 609 cfspi->flow_off_sent = 0;
@@ -656,16 +619,11 @@ int cfspi_spi_probe(struct platform_device *pdev)
656 cfspi->slave_talked = false; 619 cfspi->slave_talked = false;
657 } 620 }
658 621
659 /* Assign the SPI device. */
660 cfspi->dev = dev;
661 /* Assign the device ifc to this SPI interface. */
662 dev->ifc = &cfspi->ifc;
663
664 /* Allocate DMA buffers. */ 622 /* Allocate DMA buffers. */
665 cfspi->xfer.va_tx = dma_alloc(&cfspi->xfer.pa_tx); 623 cfspi->xfer.va_tx[0] = dma_alloc(&cfspi->xfer.pa_tx[0]);
666 if (!cfspi->xfer.va_tx) { 624 if (!cfspi->xfer.va_tx[0]) {
667 res = -ENODEV; 625 res = -ENODEV;
668 goto err_dma_alloc_tx; 626 goto err_dma_alloc_tx_0;
669 } 627 }
670 628
671 cfspi->xfer.va_rx = dma_alloc(&cfspi->xfer.pa_rx); 629 cfspi->xfer.va_rx = dma_alloc(&cfspi->xfer.pa_rx);
@@ -714,6 +672,87 @@ int cfspi_spi_probe(struct platform_device *pdev)
714 /* Schedule the work queue. */ 672 /* Schedule the work queue. */
715 queue_work(cfspi->wq, &cfspi->work); 673 queue_work(cfspi->wq, &cfspi->work);
716 674
675 return 0;
676
677 err_create_wq:
678 dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
679 err_dma_alloc_rx:
680 dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]);
681 err_dma_alloc_tx_0:
682 return res;
683}
684
685static void cfspi_uninit(struct net_device *dev)
686{
687 struct cfspi *cfspi = netdev_priv(dev);
688
689 /* Remove from list. */
690 spin_lock(&cfspi_list_lock);
691 list_del(&cfspi->list);
692 spin_unlock(&cfspi_list_lock);
693
694 cfspi->ndev = NULL;
695 /* Free DMA buffers. */
696 dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
697 dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]);
698 set_bit(SPI_TERMINATE, &cfspi->state);
699 wake_up_interruptible(&cfspi->wait);
700 destroy_workqueue(cfspi->wq);
701 /* Destroy debugfs directory and files. */
702 dev_debugfs_rem(cfspi);
703 return;
704}
705
706static const struct net_device_ops cfspi_ops = {
707 .ndo_open = cfspi_open,
708 .ndo_stop = cfspi_close,
709 .ndo_init = cfspi_init,
710 .ndo_uninit = cfspi_uninit,
711 .ndo_start_xmit = cfspi_xmit
712};
713
714static void cfspi_setup(struct net_device *dev)
715{
716 struct cfspi *cfspi = netdev_priv(dev);
717 dev->features = 0;
718 dev->netdev_ops = &cfspi_ops;
719 dev->type = ARPHRD_CAIF;
720 dev->flags = IFF_NOARP | IFF_POINTOPOINT;
721 dev->tx_queue_len = 0;
722 dev->mtu = SPI_MAX_PAYLOAD_SIZE;
723 dev->destructor = free_netdev;
724 skb_queue_head_init(&cfspi->qhead);
725 skb_queue_head_init(&cfspi->chead);
726 cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
727 cfspi->cfdev.use_frag = false;
728 cfspi->cfdev.use_stx = false;
729 cfspi->cfdev.use_fcs = false;
730 cfspi->ndev = dev;
731}
732
733int cfspi_spi_probe(struct platform_device *pdev)
734{
735 struct cfspi *cfspi = NULL;
736 struct net_device *ndev;
737 struct cfspi_dev *dev;
738 int res;
739 dev = (struct cfspi_dev *)pdev->dev.platform_data;
740
741 ndev = alloc_netdev(sizeof(struct cfspi),
742 "cfspi%d", cfspi_setup);
743 if (!dev)
744 return -ENODEV;
745
746 cfspi = netdev_priv(ndev);
747 netif_stop_queue(ndev);
748 cfspi->ndev = ndev;
749 cfspi->pdev = pdev;
750
751 /* Assign the SPI device. */
752 cfspi->dev = dev;
753 /* Assign the device ifc to this SPI interface. */
754 dev->ifc = &cfspi->ifc;
755
717 /* Register network device. */ 756 /* Register network device. */
718 res = register_netdev(ndev); 757 res = register_netdev(ndev);
719 if (res) { 758 if (res) {
@@ -723,15 +762,6 @@ int cfspi_spi_probe(struct platform_device *pdev)
723 return res; 762 return res;
724 763
725 err_net_reg: 764 err_net_reg:
726 dev_debugfs_rem(cfspi);
727 set_bit(SPI_TERMINATE, &cfspi->state);
728 wake_up_interruptible(&cfspi->wait);
729 destroy_workqueue(cfspi->wq);
730 err_create_wq:
731 dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
732 err_dma_alloc_rx:
733 dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx);
734 err_dma_alloc_tx:
735 free_netdev(ndev); 765 free_netdev(ndev);
736 766
737 return res; 767 return res;
@@ -739,34 +769,8 @@ int cfspi_spi_probe(struct platform_device *pdev)
739 769
740int cfspi_spi_remove(struct platform_device *pdev) 770int cfspi_spi_remove(struct platform_device *pdev)
741{ 771{
742 struct list_head *list_node; 772 /* Everything is done in cfspi_uninit(). */
743 struct list_head *n; 773 return 0;
744 struct cfspi *cfspi = NULL;
745 struct cfspi_dev *dev;
746
747 dev = (struct cfspi_dev *)pdev->dev.platform_data;
748 spin_lock(&cfspi_list_lock);
749 list_for_each_safe(list_node, n, &cfspi_list) {
750 cfspi = list_entry(list_node, struct cfspi, list);
751 /* Find the corresponding device. */
752 if (cfspi->dev == dev) {
753 /* Remove from list. */
754 list_del(list_node);
755 /* Free DMA buffers. */
756 dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
757 dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx);
758 set_bit(SPI_TERMINATE, &cfspi->state);
759 wake_up_interruptible(&cfspi->wait);
760 destroy_workqueue(cfspi->wq);
761 /* Destroy debugfs directory and files. */
762 dev_debugfs_rem(cfspi);
763 unregister_netdev(cfspi->ndev);
764 spin_unlock(&cfspi_list_lock);
765 return 0;
766 }
767 }
768 spin_unlock(&cfspi_list_lock);
769 return -ENODEV;
770} 774}
771 775
772static void __exit cfspi_exit_module(void) 776static void __exit cfspi_exit_module(void)
@@ -777,7 +781,7 @@ static void __exit cfspi_exit_module(void)
777 781
778 list_for_each_safe(list_node, n, &cfspi_list) { 782 list_for_each_safe(list_node, n, &cfspi_list) {
779 cfspi = list_entry(list_node, struct cfspi, list); 783 cfspi = list_entry(list_node, struct cfspi, list);
780 platform_device_unregister(cfspi->pdev); 784 unregister_netdev(cfspi->ndev);
781 } 785 }
782 786
783 /* Destroy sysfs files. */ 787 /* Destroy sysfs files. */