diff options
author | Erwan Bracq <erwan.bracq@stericsson.com> | 2011-12-06 02:25:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-06 13:34:12 -0500 |
commit | d5f43c1ea4260807a894150b680fa0a0dd386259 (patch) | |
tree | c777acc31527351630775b1a3f4b5c33322ecb84 /drivers/net/caif | |
parent | 9e998a7550b41b303c5aa5351e66ccd56f2e4c50 (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.c | 176 |
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 | } |
602 | static 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 | ||
608 | static void cfspi_setup(struct net_device *dev) | 603 | static 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 | |||
627 | int 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 | |||
685 | static 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 | |||
706 | static 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 | |||
714 | static 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 | |||
733 | int 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 | ||
740 | int cfspi_spi_remove(struct platform_device *pdev) | 770 | int 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 | ||
772 | static void __exit cfspi_exit_module(void) | 776 | static 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. */ |