diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2015-03-05 15:35:08 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-06 00:18:20 -0500 |
commit | c86e59b9e63659bb7fc2ba1781aabe2f37aaf10b (patch) | |
tree | 9b62ef1646e406ee2a7d70fb2fdcf8de782c3e4d /net/dsa/dsa.c | |
parent | 59299031038f3ea92cf484bc4a68d16ad4bb3050 (diff) |
net: dsa: extract dsa switch tree setup and removal
Extract the core logic that setups a 'struct dsa_switch_tree' and
removes it, update dsa_probe() and dsa_remove() to use the two helper
functions. This will be useful to allow for other callers to setup
this structure differently.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa/dsa.c')
-rw-r--r-- | net/dsa/dsa.c | 91 |
1 files changed, 52 insertions, 39 deletions
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 4cc995664fdf..b40f11bb419c 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c | |||
@@ -710,12 +710,55 @@ static inline void dsa_of_remove(struct device *dev) | |||
710 | } | 710 | } |
711 | #endif | 711 | #endif |
712 | 712 | ||
713 | static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev, | ||
714 | struct device *parent, struct dsa_platform_data *pd) | ||
715 | { | ||
716 | int i; | ||
717 | |||
718 | dst->pd = pd; | ||
719 | dst->master_netdev = dev; | ||
720 | dst->cpu_switch = -1; | ||
721 | dst->cpu_port = -1; | ||
722 | |||
723 | for (i = 0; i < pd->nr_chips; i++) { | ||
724 | struct dsa_switch *ds; | ||
725 | |||
726 | ds = dsa_switch_setup(dst, i, parent, pd->chip[i].host_dev); | ||
727 | if (IS_ERR(ds)) { | ||
728 | netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n", | ||
729 | i, PTR_ERR(ds)); | ||
730 | continue; | ||
731 | } | ||
732 | |||
733 | dst->ds[i] = ds; | ||
734 | if (ds->drv->poll_link != NULL) | ||
735 | dst->link_poll_needed = 1; | ||
736 | } | ||
737 | |||
738 | /* | ||
739 | * If we use a tagging format that doesn't have an ethertype | ||
740 | * field, make sure that all packets from this point on get | ||
741 | * sent to the tag format's receive function. | ||
742 | */ | ||
743 | wmb(); | ||
744 | dev->dsa_ptr = (void *)dst; | ||
745 | |||
746 | if (dst->link_poll_needed) { | ||
747 | INIT_WORK(&dst->link_poll_work, dsa_link_poll_work); | ||
748 | init_timer(&dst->link_poll_timer); | ||
749 | dst->link_poll_timer.data = (unsigned long)dst; | ||
750 | dst->link_poll_timer.function = dsa_link_poll_timer; | ||
751 | dst->link_poll_timer.expires = round_jiffies(jiffies + HZ); | ||
752 | add_timer(&dst->link_poll_timer); | ||
753 | } | ||
754 | } | ||
755 | |||
713 | static int dsa_probe(struct platform_device *pdev) | 756 | static int dsa_probe(struct platform_device *pdev) |
714 | { | 757 | { |
715 | struct dsa_platform_data *pd = pdev->dev.platform_data; | 758 | struct dsa_platform_data *pd = pdev->dev.platform_data; |
716 | struct net_device *dev; | 759 | struct net_device *dev; |
717 | struct dsa_switch_tree *dst; | 760 | struct dsa_switch_tree *dst; |
718 | int i, ret; | 761 | int ret; |
719 | 762 | ||
720 | pr_notice_once("Distributed Switch Architecture driver version %s\n", | 763 | pr_notice_once("Distributed Switch Architecture driver version %s\n", |
721 | dsa_driver_version); | 764 | dsa_driver_version); |
@@ -752,42 +795,7 @@ static int dsa_probe(struct platform_device *pdev) | |||
752 | 795 | ||
753 | platform_set_drvdata(pdev, dst); | 796 | platform_set_drvdata(pdev, dst); |
754 | 797 | ||
755 | dst->pd = pd; | 798 | dsa_setup_dst(dst, dev, &pdev->dev, pd); |
756 | dst->master_netdev = dev; | ||
757 | dst->cpu_switch = -1; | ||
758 | dst->cpu_port = -1; | ||
759 | |||
760 | for (i = 0; i < pd->nr_chips; i++) { | ||
761 | struct dsa_switch *ds; | ||
762 | |||
763 | ds = dsa_switch_setup(dst, i, &pdev->dev, pd->chip[i].host_dev); | ||
764 | if (IS_ERR(ds)) { | ||
765 | netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n", | ||
766 | i, PTR_ERR(ds)); | ||
767 | continue; | ||
768 | } | ||
769 | |||
770 | dst->ds[i] = ds; | ||
771 | if (ds->drv->poll_link != NULL) | ||
772 | dst->link_poll_needed = 1; | ||
773 | } | ||
774 | |||
775 | /* | ||
776 | * If we use a tagging format that doesn't have an ethertype | ||
777 | * field, make sure that all packets from this point on get | ||
778 | * sent to the tag format's receive function. | ||
779 | */ | ||
780 | wmb(); | ||
781 | dev->dsa_ptr = (void *)dst; | ||
782 | |||
783 | if (dst->link_poll_needed) { | ||
784 | INIT_WORK(&dst->link_poll_work, dsa_link_poll_work); | ||
785 | init_timer(&dst->link_poll_timer); | ||
786 | dst->link_poll_timer.data = (unsigned long)dst; | ||
787 | dst->link_poll_timer.function = dsa_link_poll_timer; | ||
788 | dst->link_poll_timer.expires = round_jiffies(jiffies + HZ); | ||
789 | add_timer(&dst->link_poll_timer); | ||
790 | } | ||
791 | 799 | ||
792 | return 0; | 800 | return 0; |
793 | 801 | ||
@@ -797,9 +805,8 @@ out: | |||
797 | return ret; | 805 | return ret; |
798 | } | 806 | } |
799 | 807 | ||
800 | static int dsa_remove(struct platform_device *pdev) | 808 | static void dsa_remove_dst(struct dsa_switch_tree *dst) |
801 | { | 809 | { |
802 | struct dsa_switch_tree *dst = platform_get_drvdata(pdev); | ||
803 | int i; | 810 | int i; |
804 | 811 | ||
805 | if (dst->link_poll_needed) | 812 | if (dst->link_poll_needed) |
@@ -813,7 +820,13 @@ static int dsa_remove(struct platform_device *pdev) | |||
813 | if (ds != NULL) | 820 | if (ds != NULL) |
814 | dsa_switch_destroy(ds); | 821 | dsa_switch_destroy(ds); |
815 | } | 822 | } |
823 | } | ||
824 | |||
825 | static int dsa_remove(struct platform_device *pdev) | ||
826 | { | ||
827 | struct dsa_switch_tree *dst = platform_get_drvdata(pdev); | ||
816 | 828 | ||
829 | dsa_remove_dst(dst); | ||
817 | dsa_of_remove(&pdev->dev); | 830 | dsa_of_remove(&pdev->dev); |
818 | 831 | ||
819 | return 0; | 832 | return 0; |