From: Vladimir Oltean Date: Thu, 30 May 2024 16:33:32 +0000 (+0300) Subject: net: dsa: ocelot: common probing code X-Git-Tag: v6.11-rc1~163^2~266^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=efdbee7d07916d994bc0ff0235d00d46fa991b61;p=thirdparty%2Flinux.git net: dsa: ocelot: common probing code Russell King suggested that felix_vsc9959, seville_vsc9953 and ocelot_ext have a large portion of duplicated init code, which could be made common [1]. [1]: https://lore.kernel.org/all/Zh1GvcOTXqb7CpQt@shell.armlinux.org.uk/ Here, we take the following common steps: - "felix" and "ds" structure allocation - "felix", "ocelot" and "ds" basic structure initialization - dsa_register_switch() call and we make a common function out of them. For every driver except felix_vsc9959, this is also the entire probing procedure. For felix_vsc9959, we also need to do some PCI-specific stuff, which can easily be reordered to be done before, and unwound on failure. We also have to convert the bus-specific platform_set_drvdata() and pci_set_drvdata() calls into dev_set_drvdata(). But this should have no impact on the behavior. Suggested-by: "Russell King (Oracle)" Signed-off-by: Vladimir Oltean Tested-by: Colin Foster Signed-off-by: David S. Miller --- diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 09c0800b18ab4..accf737f7b69b 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -2195,6 +2195,53 @@ const struct dsa_switch_ops felix_switch_ops = { }; EXPORT_SYMBOL_GPL(felix_switch_ops); +int felix_register_switch(struct device *dev, resource_size_t switch_base, + int num_flooding_pgids, bool ptp, + bool mm_supported, + enum dsa_tag_protocol init_tag_proto, + const struct felix_info *info) +{ + struct dsa_switch *ds; + struct ocelot *ocelot; + struct felix *felix; + int err; + + felix = devm_kzalloc(dev, sizeof(*felix), GFP_KERNEL); + if (!felix) + return -ENOMEM; + + ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL); + if (!ds) + return -ENOMEM; + + dev_set_drvdata(dev, felix); + + ocelot = &felix->ocelot; + ocelot->dev = dev; + ocelot->num_flooding_pgids = num_flooding_pgids; + ocelot->ptp = ptp; + ocelot->mm_supported = mm_supported; + + felix->info = info; + felix->switch_base = switch_base; + felix->ds = ds; + felix->tag_proto = init_tag_proto; + + ds->dev = dev; + ds->num_ports = info->num_ports; + ds->num_tx_queues = OCELOT_NUM_TC; + ds->ops = &felix_switch_ops; + ds->phylink_mac_ops = &felix_phylink_mac_ops; + ds->priv = ocelot; + + err = dsa_register_switch(ds); + if (err) + dev_err_probe(dev, err, "Failed to register DSA switch\n"); + + return err; +} +EXPORT_SYMBOL_GPL(felix_register_switch); + struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port) { struct felix *felix = ocelot_to_felix(ocelot); diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index e0bfea10ff525..85b4f8616003c 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -100,6 +100,11 @@ struct felix { unsigned long host_flood_mc_mask; }; +int felix_register_switch(struct device *dev, resource_size_t switch_base, + int num_flooding_pgids, bool ptp, + bool mm_supported, + enum dsa_tag_protocol init_tag_proto, + const struct felix_info *info); struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port); int felix_netdev_to_port(struct net_device *dev); diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index ec8b124e8f618..ba37a566da39a 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -2673,9 +2673,7 @@ static int felix_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct device *dev = &pdev->dev; - struct dsa_switch *ds; - struct ocelot *ocelot; - struct felix *felix; + resource_size_t switch_base; int err; err = pci_enable_device(pdev); @@ -2684,45 +2682,15 @@ static int felix_pci_probe(struct pci_dev *pdev, return err; } - felix = devm_kzalloc(dev, sizeof(struct felix), GFP_KERNEL); - if (!felix) { - err = -ENOMEM; - goto out_disable; - } - - pci_set_drvdata(pdev, felix); - ocelot = &felix->ocelot; - ocelot->dev = dev; - ocelot->num_flooding_pgids = OCELOT_NUM_TC; - felix->info = &felix_info_vsc9959; - felix->switch_base = pci_resource_start(pdev, VSC9959_SWITCH_PCI_BAR); - pci_set_master(pdev); - ocelot->ptp = 1; - ocelot->mm_supported = true; + switch_base = pci_resource_start(pdev, VSC9959_SWITCH_PCI_BAR); - ds = devm_kzalloc(dev, sizeof(struct dsa_switch), GFP_KERNEL); - if (!ds) { - err = -ENOMEM; + err = felix_register_switch(dev, switch_base, OCELOT_NUM_TC, + true, true, DSA_TAG_PROTO_OCELOT, + &felix_info_vsc9959); + if (err) goto out_disable; - } - - ds->dev = dev; - ds->num_ports = felix->info->num_ports; - ds->num_tx_queues = OCELOT_NUM_TC; - - ds->ops = &felix_switch_ops; - ds->phylink_mac_ops = &felix_phylink_mac_ops; - ds->priv = ocelot; - felix->ds = ds; - felix->tag_proto = DSA_TAG_PROTO_OCELOT; - - err = dsa_register_switch(ds); - if (err) { - dev_err_probe(dev, err, "Failed to register DSA switch\n"); - goto out_disable; - } return 0; diff --git a/drivers/net/dsa/ocelot/ocelot_ext.c b/drivers/net/dsa/ocelot/ocelot_ext.c index 9cd24f77dc49b..5632a7248cd41 100644 --- a/drivers/net/dsa/ocelot/ocelot_ext.c +++ b/drivers/net/dsa/ocelot/ocelot_ext.c @@ -64,44 +64,8 @@ static const struct felix_info vsc7512_info = { static int ocelot_ext_probe(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct dsa_switch *ds; - struct ocelot *ocelot; - struct felix *felix; - int err; - - felix = devm_kzalloc(dev, sizeof(*felix), GFP_KERNEL); - if (!felix) - return -ENOMEM; - - dev_set_drvdata(dev, felix); - - ocelot = &felix->ocelot; - ocelot->dev = dev; - - ocelot->num_flooding_pgids = 1; - - felix->info = &vsc7512_info; - - ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL); - if (!ds) - return -ENOMEM; - - ds->dev = dev; - ds->num_ports = felix->info->num_ports; - ds->num_tx_queues = OCELOT_NUM_TC; - - ds->ops = &felix_switch_ops; - ds->phylink_mac_ops = &felix_phylink_mac_ops; - ds->priv = ocelot; - felix->ds = ds; - felix->tag_proto = DSA_TAG_PROTO_OCELOT; - - err = dsa_register_switch(ds); - if (err) - dev_err_probe(dev, err, "Failed to register DSA switch\n"); - - return err; + return felix_register_switch(&pdev->dev, 0, 1, false, false, + DSA_TAG_PROTO_OCELOT, &vsc7512_info); } static void ocelot_ext_remove(struct platform_device *pdev) diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c index 83bd0e1ee692b..70782649c3957 100644 --- a/drivers/net/dsa/ocelot/seville_vsc9953.c +++ b/drivers/net/dsa/ocelot/seville_vsc9953.c @@ -971,49 +971,17 @@ static const struct felix_info seville_info_vsc9953 = { static int seville_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct dsa_switch *ds; - struct ocelot *ocelot; struct resource *res; - struct felix *felix; - int err; - - felix = devm_kzalloc(dev, sizeof(struct felix), GFP_KERNEL); - if (!felix) - return -ENOMEM; - - platform_set_drvdata(pdev, felix); - - ocelot = &felix->ocelot; - ocelot->dev = dev; - ocelot->num_flooding_pgids = 1; - felix->info = &seville_info_vsc9953; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "Invalid resource\n"); return -EINVAL; } - felix->switch_base = res->start; - - ds = devm_kzalloc(dev, sizeof(struct dsa_switch), GFP_KERNEL); - if (!ds) - return -ENOMEM; - - ds->dev = dev; - ds->num_ports = felix->info->num_ports; - ds->num_tx_queues = OCELOT_NUM_TC; - - ds->ops = &felix_switch_ops; - ds->phylink_mac_ops = &felix_phylink_mac_ops; - ds->priv = ocelot; - felix->ds = ds; - felix->tag_proto = DSA_TAG_PROTO_SEVILLE; - - err = dsa_register_switch(ds); - if (err) - dev_err(dev, "Failed to register DSA switch: %d\n", err); - return err; + return felix_register_switch(dev, res->start, 1, false, false, + DSA_TAG_PROTO_SEVILLE, + &seville_info_vsc9953); } static void seville_remove(struct platform_device *pdev)