aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2016-08-18 18:30:14 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-19 20:15:36 -0400
commitd9338023fb8e60aa09014034a993f8ddc86c65fa (patch)
tree0ddb59520c731a0940d9de4a92cffc90b2296d38 /drivers/net/dsa
parenta85fad1436b0fd0fe9d7f1d23387e83e7cd21c0a (diff)
net: dsa: bcm_sf2: Make it a real platform device driver
The Broadcom Starfighter 2 switch driver should be a proper platform driver, now that the DSA code has been updated to allow that, register a switch device, feed it with the proper configuration data coming from Device Tree and register our switch device with DSA. The bulk of the changes consist in moving what bcm_sf2_sw_setup() did into the platform driver probe function. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r--drivers/net/dsa/bcm_sf2.c178
1 files changed, 118 insertions, 60 deletions
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index b2b838724a9b..fe1cc92f72a8 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -1571,23 +1571,84 @@ static int bcm_sf2_sw_vlan_dump(struct dsa_switch *ds, int port,
1571 1571
1572static int bcm_sf2_sw_setup(struct dsa_switch *ds) 1572static int bcm_sf2_sw_setup(struct dsa_switch *ds)
1573{ 1573{
1574 const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
1575 struct bcm_sf2_priv *priv = ds_to_priv(ds); 1574 struct bcm_sf2_priv *priv = ds_to_priv(ds);
1576 struct device_node *dn;
1577 void __iomem **base;
1578 unsigned int port; 1575 unsigned int port;
1576
1577 /* Enable all valid ports and disable those unused */
1578 for (port = 0; port < priv->hw_params.num_ports; port++) {
1579 /* IMP port receives special treatment */
1580 if ((1 << port) & ds->enabled_port_mask)
1581 bcm_sf2_port_setup(ds, port, NULL);
1582 else if (dsa_is_cpu_port(ds, port))
1583 bcm_sf2_imp_setup(ds, port);
1584 else
1585 bcm_sf2_port_disable(ds, port, NULL);
1586 }
1587
1588 bcm_sf2_sw_configure_vlan(ds);
1589
1590 return 0;
1591}
1592
1593static struct dsa_switch_driver bcm_sf2_switch_driver = {
1594 .tag_protocol = DSA_TAG_PROTO_BRCM,
1595 .probe = bcm_sf2_sw_drv_probe,
1596 .setup = bcm_sf2_sw_setup,
1597 .set_addr = bcm_sf2_sw_set_addr,
1598 .get_phy_flags = bcm_sf2_sw_get_phy_flags,
1599 .get_strings = bcm_sf2_sw_get_strings,
1600 .get_ethtool_stats = bcm_sf2_sw_get_ethtool_stats,
1601 .get_sset_count = bcm_sf2_sw_get_sset_count,
1602 .adjust_link = bcm_sf2_sw_adjust_link,
1603 .fixed_link_update = bcm_sf2_sw_fixed_link_update,
1604 .suspend = bcm_sf2_sw_suspend,
1605 .resume = bcm_sf2_sw_resume,
1606 .get_wol = bcm_sf2_sw_get_wol,
1607 .set_wol = bcm_sf2_sw_set_wol,
1608 .port_enable = bcm_sf2_port_setup,
1609 .port_disable = bcm_sf2_port_disable,
1610 .get_eee = bcm_sf2_sw_get_eee,
1611 .set_eee = bcm_sf2_sw_set_eee,
1612 .port_bridge_join = bcm_sf2_sw_br_join,
1613 .port_bridge_leave = bcm_sf2_sw_br_leave,
1614 .port_stp_state_set = bcm_sf2_sw_br_set_stp_state,
1615 .port_fdb_prepare = bcm_sf2_sw_fdb_prepare,
1616 .port_fdb_add = bcm_sf2_sw_fdb_add,
1617 .port_fdb_del = bcm_sf2_sw_fdb_del,
1618 .port_fdb_dump = bcm_sf2_sw_fdb_dump,
1619 .port_vlan_filtering = bcm_sf2_sw_vlan_filtering,
1620 .port_vlan_prepare = bcm_sf2_sw_vlan_prepare,
1621 .port_vlan_add = bcm_sf2_sw_vlan_add,
1622 .port_vlan_del = bcm_sf2_sw_vlan_del,
1623 .port_vlan_dump = bcm_sf2_sw_vlan_dump,
1624};
1625
1626static int bcm_sf2_sw_probe(struct platform_device *pdev)
1627{
1628 const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
1629 struct device_node *dn = pdev->dev.of_node;
1630 struct bcm_sf2_priv *priv;
1631 struct dsa_switch *ds;
1632 void __iomem **base;
1579 unsigned int i; 1633 unsigned int i;
1580 u32 reg, rev; 1634 u32 reg, rev;
1581 int ret; 1635 int ret;
1582 1636
1637 ds = devm_kzalloc(&pdev->dev, sizeof(*ds) + sizeof(*priv), GFP_KERNEL);
1638 if (!ds)
1639 return -ENOMEM;
1640
1641 priv = (struct bcm_sf2_priv *)(ds + 1);
1642 ds->priv = priv;
1643 ds->dev = &pdev->dev;
1644 ds->drv = &bcm_sf2_switch_driver;
1645
1646 dev_set_drvdata(&pdev->dev, ds);
1647
1583 spin_lock_init(&priv->indir_lock); 1648 spin_lock_init(&priv->indir_lock);
1584 mutex_init(&priv->stats_mutex); 1649 mutex_init(&priv->stats_mutex);
1585 1650
1586 /* All the interesting properties are at the parent device_node 1651 bcm_sf2_identify_ports(priv, dn->child);
1587 * level
1588 */
1589 dn = ds->cd->of_node->parent;
1590 bcm_sf2_identify_ports(priv, ds->cd->of_node);
1591 1652
1592 priv->irq0 = irq_of_parse_and_map(dn, 0); 1653 priv->irq0 = irq_of_parse_and_map(dn, 0);
1593 priv->irq1 = irq_of_parse_and_map(dn, 1); 1654 priv->irq1 = irq_of_parse_and_map(dn, 1);
@@ -1649,19 +1710,6 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
1649 &priv->hw_params.num_gphy)) 1710 &priv->hw_params.num_gphy))
1650 priv->hw_params.num_gphy = 1; 1711 priv->hw_params.num_gphy = 1;
1651 1712
1652 /* Enable all valid ports and disable those unused */
1653 for (port = 0; port < priv->hw_params.num_ports; port++) {
1654 /* IMP port receives special treatment */
1655 if ((1 << port) & ds->enabled_port_mask)
1656 bcm_sf2_port_setup(ds, port, NULL);
1657 else if (dsa_is_cpu_port(ds, port))
1658 bcm_sf2_imp_setup(ds, port);
1659 else
1660 bcm_sf2_port_disable(ds, port, NULL);
1661 }
1662
1663 bcm_sf2_sw_configure_vlan(ds);
1664
1665 rev = reg_readl(priv, REG_SWITCH_REVISION); 1713 rev = reg_readl(priv, REG_SWITCH_REVISION);
1666 priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) & 1714 priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) &
1667 SWITCH_TOP_REV_MASK; 1715 SWITCH_TOP_REV_MASK;
@@ -1670,6 +1718,10 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
1670 rev = reg_readl(priv, REG_PHY_REVISION); 1718 rev = reg_readl(priv, REG_PHY_REVISION);
1671 priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK; 1719 priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
1672 1720
1721 ret = dsa_register_switch(ds, dn);
1722 if (ret)
1723 goto out_free_irq1;
1724
1673 pr_info("Starfighter 2 top: %x.%02x, core: %x.%02x base: 0x%p, IRQs: %d, %d\n", 1725 pr_info("Starfighter 2 top: %x.%02x, core: %x.%02x base: 0x%p, IRQs: %d, %d\n",
1674 priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff, 1726 priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff,
1675 priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff, 1727 priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
@@ -1677,6 +1729,8 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
1677 1729
1678 return 0; 1730 return 0;
1679 1731
1732out_free_irq1:
1733 free_irq(priv->irq1, priv);
1680out_free_irq0: 1734out_free_irq0:
1681 free_irq(priv->irq0, priv); 1735 free_irq(priv->irq0, priv);
1682out_mdio: 1736out_mdio:
@@ -1691,52 +1745,56 @@ out_unmap:
1691 return ret; 1745 return ret;
1692} 1746}
1693 1747
1694static struct dsa_switch_driver bcm_sf2_switch_driver = { 1748static int bcm_sf2_sw_remove(struct platform_device *pdev)
1695 .tag_protocol = DSA_TAG_PROTO_BRCM,
1696 .probe = bcm_sf2_sw_drv_probe,
1697 .setup = bcm_sf2_sw_setup,
1698 .set_addr = bcm_sf2_sw_set_addr,
1699 .get_phy_flags = bcm_sf2_sw_get_phy_flags,
1700 .get_strings = bcm_sf2_sw_get_strings,
1701 .get_ethtool_stats = bcm_sf2_sw_get_ethtool_stats,
1702 .get_sset_count = bcm_sf2_sw_get_sset_count,
1703 .adjust_link = bcm_sf2_sw_adjust_link,
1704 .fixed_link_update = bcm_sf2_sw_fixed_link_update,
1705 .suspend = bcm_sf2_sw_suspend,
1706 .resume = bcm_sf2_sw_resume,
1707 .get_wol = bcm_sf2_sw_get_wol,
1708 .set_wol = bcm_sf2_sw_set_wol,
1709 .port_enable = bcm_sf2_port_setup,
1710 .port_disable = bcm_sf2_port_disable,
1711 .get_eee = bcm_sf2_sw_get_eee,
1712 .set_eee = bcm_sf2_sw_set_eee,
1713 .port_bridge_join = bcm_sf2_sw_br_join,
1714 .port_bridge_leave = bcm_sf2_sw_br_leave,
1715 .port_stp_state_set = bcm_sf2_sw_br_set_stp_state,
1716 .port_fdb_prepare = bcm_sf2_sw_fdb_prepare,
1717 .port_fdb_add = bcm_sf2_sw_fdb_add,
1718 .port_fdb_del = bcm_sf2_sw_fdb_del,
1719 .port_fdb_dump = bcm_sf2_sw_fdb_dump,
1720 .port_vlan_filtering = bcm_sf2_sw_vlan_filtering,
1721 .port_vlan_prepare = bcm_sf2_sw_vlan_prepare,
1722 .port_vlan_add = bcm_sf2_sw_vlan_add,
1723 .port_vlan_del = bcm_sf2_sw_vlan_del,
1724 .port_vlan_dump = bcm_sf2_sw_vlan_dump,
1725};
1726
1727static int __init bcm_sf2_init(void)
1728{ 1749{
1729 register_switch_driver(&bcm_sf2_switch_driver); 1750 struct dsa_switch *ds = platform_get_drvdata(pdev);
1751 struct bcm_sf2_priv *priv = ds_to_priv(ds);
1752
1753 /* Disable all ports and interrupts */
1754 priv->wol_ports_mask = 0;
1755 bcm_sf2_sw_suspend(ds);
1756 dsa_unregister_switch(ds);
1757 bcm_sf2_mdio_unregister(priv);
1730 1758
1731 return 0; 1759 return 0;
1732} 1760}
1733module_init(bcm_sf2_init);
1734 1761
1735static void __exit bcm_sf2_exit(void) 1762#ifdef CONFIG_PM_SLEEP
1763static int bcm_sf2_suspend(struct device *dev)
1736{ 1764{
1737 unregister_switch_driver(&bcm_sf2_switch_driver); 1765 struct platform_device *pdev = to_platform_device(dev);
1766 struct dsa_switch *ds = platform_get_drvdata(pdev);
1767
1768 return dsa_switch_suspend(ds);
1738} 1769}
1739module_exit(bcm_sf2_exit); 1770
1771static int bcm_sf2_resume(struct device *dev)
1772{
1773 struct platform_device *pdev = to_platform_device(dev);
1774 struct dsa_switch *ds = platform_get_drvdata(pdev);
1775
1776 return dsa_switch_resume(ds);
1777}
1778#endif /* CONFIG_PM_SLEEP */
1779
1780static SIMPLE_DEV_PM_OPS(bcm_sf2_pm_ops,
1781 bcm_sf2_suspend, bcm_sf2_resume);
1782
1783static const struct of_device_id bcm_sf2_of_match[] = {
1784 { .compatible = "brcm,bcm7445-switch-v4.0" },
1785 { /* sentinel */ },
1786};
1787
1788static struct platform_driver bcm_sf2_driver = {
1789 .probe = bcm_sf2_sw_probe,
1790 .remove = bcm_sf2_sw_remove,
1791 .driver = {
1792 .name = "brcm-sf2",
1793 .of_match_table = bcm_sf2_of_match,
1794 .pm = &bcm_sf2_pm_ops,
1795 },
1796};
1797module_platform_driver(bcm_sf2_driver);
1740 1798
1741MODULE_AUTHOR("Broadcom Corporation"); 1799MODULE_AUTHOR("Broadcom Corporation");
1742MODULE_DESCRIPTION("Driver for Broadcom Starfighter 2 ethernet switch chip"); 1800MODULE_DESCRIPTION("Driver for Broadcom Starfighter 2 ethernet switch chip");