From b681957ad439daf1ea67111463df783d3113c2da Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 10 May 2016 23:27:19 +0200 Subject: [PATCH 1/7] dsa: mv88e6xxx: Initialise the mutex as soon as it is created By initialising immediately it, we don't run the danger of using it before it is initialised. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 835126e90afdc..46564f4a96158 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -3132,8 +3132,6 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) ps->ds = ds; - mutex_init(&ps->smi_mutex); - INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) @@ -3580,6 +3578,7 @@ static const char *mv88e6xxx_probe(struct device *dsa_dev, ps->bus = bus; ps->sw_addr = sw_addr; ps->info = info; + mutex_init(&ps->smi_mutex); *priv = ps; From fcdce7d0751096bbc863d5db12726e9253abbc3c Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 10 May 2016 23:27:20 +0200 Subject: [PATCH 2/7] dsa: mv88e6xxx: Rename probe function to fit the normal pattern All other DSA drivers use _drv_ in there DSA probe function name, thus allowing for a true linux driver probe function to use the conventional name. Make mv88e6xxx fit this pattern. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 46564f4a96158..3d260da7caf50 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -3543,9 +3543,9 @@ mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table, return NULL; } -static const char *mv88e6xxx_probe(struct device *dsa_dev, - struct device *host_dev, int sw_addr, - void **priv) +static const char *mv88e6xxx_drv_probe(struct device *dsa_dev, + struct device *host_dev, int sw_addr, + void **priv) { const struct mv88e6xxx_info *info; struct mv88e6xxx_priv_state *ps; @@ -3590,7 +3590,7 @@ static const char *mv88e6xxx_probe(struct device *dsa_dev, struct dsa_switch_driver mv88e6xxx_switch_driver = { .tag_protocol = DSA_TAG_PROTO_EDSA, - .probe = mv88e6xxx_probe, + .probe = mv88e6xxx_drv_probe, .setup = mv88e6xxx_setup, .set_addr = mv88e6xxx_set_addr, .phy_read = mv88e6xxx_phy_read, From 14c7b3c3877075e6df22e071d4619cbdeac82ffd Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 10 May 2016 23:27:21 +0200 Subject: [PATCH 3/7] dsa: Add mdio device support to Marvell switches Allow Marvell switches to be mdio devices. Currently the driver just allocate the private structure and detects what device is on the bus. Later patches will make them register with the DSA framework. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- .../devicetree/bindings/net/dsa/marvell.txt | 27 ++++++ drivers/net/dsa/mv88e6xxx.c | 90 +++++++++++++++---- 2 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/dsa/marvell.txt diff --git a/Documentation/devicetree/bindings/net/dsa/marvell.txt b/Documentation/devicetree/bindings/net/dsa/marvell.txt new file mode 100644 index 0000000000000..cdd70cebdea71 --- /dev/null +++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt @@ -0,0 +1,27 @@ +Marvell DSA Switch Device Tree Bindings +--------------------------------------- + +WARNING: This binding is currently unstable. Do not program it into a +FLASH never to be changed again. Once this binding is stable, this +warning will be removed. + +If you need a stable binding, use the old dsa.txt binding. + +Marvell Switches are MDIO devices. The following properties should be +placed as a child node of an mdio device. + +Required properties: +- compatible : Should be one of "marvell,mv88e6085", +- reg : Address on the MII bus for the switch. + +Example: + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + switch0: switch@0 { + compatible = "marvell,mv88e6085"; + reg = <0>; + }; + }; diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 3d260da7caf50..ae1cb191a0e02 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -5,6 +5,8 @@ * Copyright (c) 2015 CMC Electronics, Inc. * Added support for VLAN Table Unit operations * + * Copyright (c) 2016 Andrew Lunn + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -17,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -3625,36 +3628,87 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = { .port_fdb_dump = mv88e6xxx_port_fdb_dump, }; -static int __init mv88e6xxx_init(void) +int mv88e6xxx_probe(struct mdio_device *mdiodev) { - register_switch_driver(&mv88e6xxx_switch_driver); + struct device *dev = &mdiodev->dev; + struct mv88e6xxx_priv_state *ps; + int id, prod_num, rev; + struct dsa_switch *ds; + + ds = devm_kzalloc(dev, sizeof(*ds) + sizeof(*ps), GFP_KERNEL); + if (!ds) + return -ENOMEM; + + ps = (struct mv88e6xxx_priv_state *)(ds + 1); + ds->priv = ps; + ps->dev = dev; + ps->ds = ds; + ps->bus = mdiodev->bus; + ps->sw_addr = mdiodev->addr; + mutex_init(&ps->smi_mutex); + + get_device(&ps->bus->dev); + + ds->drv = &mv88e6xxx_switch_driver; + + id = mv88e6xxx_reg_read(ps, REG_PORT(0), PORT_SWITCH_ID); + if (id < 0) + return id; + + prod_num = (id & 0xfff0) >> 4; + rev = id & 0x000f; + + ps->info = mv88e6xxx_lookup_info(prod_num, mv88e6xxx_table, + ARRAY_SIZE(mv88e6xxx_table)); + if (!ps->info) + return -ENODEV; + + dev_set_drvdata(dev, ds); + + dev_info(dev, "switch 0x%x probed: %s, revision %u\n", + prod_num, ps->info->name, rev); return 0; } + +static void mv88e6xxx_remove(struct mdio_device *mdiodev) +{ + struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev); + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + + put_device(&ps->bus->dev); +} + +static const struct of_device_id mv88e6xxx_of_match[] = { + { .compatible = "marvell,mv88e6085" }, + { /* sentinel */ }, +}; + +MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match); + +static struct mdio_driver mv88e6xxx_driver = { + .probe = mv88e6xxx_probe, + .remove = mv88e6xxx_remove, + .mdiodrv.driver = { + .name = "mv88e6085", + .of_match_table = mv88e6xxx_of_match, + }, +}; + +static int __init mv88e6xxx_init(void) +{ + register_switch_driver(&mv88e6xxx_switch_driver); + return mdio_driver_register(&mv88e6xxx_driver); +} module_init(mv88e6xxx_init); static void __exit mv88e6xxx_cleanup(void) { + mdio_driver_unregister(&mv88e6xxx_driver); unregister_switch_driver(&mv88e6xxx_switch_driver); } module_exit(mv88e6xxx_cleanup); -MODULE_ALIAS("platform:mv88e6085"); -MODULE_ALIAS("platform:mv88e6095"); -MODULE_ALIAS("platform:mv88e6095f"); -MODULE_ALIAS("platform:mv88e6123"); -MODULE_ALIAS("platform:mv88e6131"); -MODULE_ALIAS("platform:mv88e6161"); -MODULE_ALIAS("platform:mv88e6165"); -MODULE_ALIAS("platform:mv88e6171"); -MODULE_ALIAS("platform:mv88e6172"); -MODULE_ALIAS("platform:mv88e6175"); -MODULE_ALIAS("platform:mv88e6176"); -MODULE_ALIAS("platform:mv88e6320"); -MODULE_ALIAS("platform:mv88e6321"); -MODULE_ALIAS("platform:mv88e6350"); -MODULE_ALIAS("platform:mv88e6351"); -MODULE_ALIAS("platform:mv88e6352"); MODULE_AUTHOR("Lennert Buytenhek "); MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips"); MODULE_LICENSE("GPL"); From 52638f71fcff9386fe64c83a18a129b122333fdf Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 10 May 2016 23:27:22 +0200 Subject: [PATCH 4/7] dsa: Move gpio reset into switch driver Resetting the switch is something the driver does, not the framework. So move the parsing of this property into the driver. There are no in kernel users of this property, so moving it does not break anything. There is however a board which will make use of this property making its way into the kernel. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- .../devicetree/bindings/net/dsa/dsa.txt | 2 -- .../devicetree/bindings/net/dsa/marvell.txt | 8 ++++++++ drivers/net/dsa/mv88e6xxx.c | 14 +++++++++++++- drivers/net/dsa/mv88e6xxx.h | 7 +++++++ include/net/dsa.h | 8 -------- net/dsa/dsa.c | 16 ---------------- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt index 5fdbbcdf8c4b8..9f4807f90c31f 100644 --- a/Documentation/devicetree/bindings/net/dsa/dsa.txt +++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt @@ -31,8 +31,6 @@ A switch child node has the following optional property: switch. Must be set if the switch can not detect the presence and/or size of a connected EEPROM, otherwise optional. -- reset-gpios : phandle and specifier to a gpio line connected to - reset pin of the switch chip. A switch may have multiple "port" children nodes diff --git a/Documentation/devicetree/bindings/net/dsa/marvell.txt b/Documentation/devicetree/bindings/net/dsa/marvell.txt index cdd70cebdea71..7629189398aab 100644 --- a/Documentation/devicetree/bindings/net/dsa/marvell.txt +++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt @@ -10,10 +10,17 @@ If you need a stable binding, use the old dsa.txt binding. Marvell Switches are MDIO devices. The following properties should be placed as a child node of an mdio device. +The properties described here are those specific to Marvell devices. +Additional required and optional properties can be found in dsa.txt. + Required properties: - compatible : Should be one of "marvell,mv88e6085", - reg : Address on the MII bus for the switch. +Optional properties: + +- reset-gpios : Should be a gpio specifier for a reset line + Example: mdio { @@ -23,5 +30,6 @@ Example: switch0: switch@0 { compatible = "marvell,mv88e6085"; reg = <0>; + reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; }; }; diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index ae1cb191a0e02..e7e07eb7091dc 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2582,7 +2582,7 @@ static int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps) { bool ppu_active = mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE); u16 is_reset = (ppu_active ? 0x8800 : 0xc800); - struct gpio_desc *gpiod = ps->ds->pd->reset; + struct gpio_desc *gpiod = ps->reset; unsigned long timeout; int ret; int i; @@ -3634,6 +3634,7 @@ int mv88e6xxx_probe(struct mdio_device *mdiodev) struct mv88e6xxx_priv_state *ps; int id, prod_num, rev; struct dsa_switch *ds; + int err; ds = devm_kzalloc(dev, sizeof(*ds) + sizeof(*ps), GFP_KERNEL); if (!ds) @@ -3663,6 +3664,17 @@ int mv88e6xxx_probe(struct mdio_device *mdiodev) if (!ps->info) return -ENODEV; + ps->reset = devm_gpiod_get(&mdiodev->dev, "reset", GPIOD_ASIS); + if (IS_ERR(ps->reset)) { + err = PTR_ERR(ps->reset); + if (err == -ENOENT) { + /* Optional, so not an error */ + ps->reset = NULL; + } else { + return err; + } + } + dev_set_drvdata(dev, ds); dev_info(dev, "switch 0x%x probed: %s, revision %u\n", diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 5f09a4ea3cc57..9ef7673f0c61f 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -12,6 +12,7 @@ #define __MV88E6XXX_H #include +#include #ifndef UINT64_MAX #define UINT64_MAX (u64)(~((u64)0)) @@ -595,6 +596,12 @@ struct mv88e6xxx_priv_state { DECLARE_BITMAP(port_state_update_mask, DSA_MAX_PORTS); struct work_struct bridge_work; + + /* A switch may have a GPIO line tied to its reset pin. Parse + * this from the device tree, and use it before performing + * switch soft reset. + */ + struct gpio_desc *reset; }; enum stat_type { diff --git a/include/net/dsa.h b/include/net/dsa.h index 8e86af87c84fe..ecb52e265cc3d 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -65,13 +64,6 @@ struct dsa_chip_data { * NULL if there is only one switch chip. */ s8 *rtable; - - /* - * A switch may have a GPIO line tied to its reset pin. Parse - * this from the device tree, and use it before performing - * switch soft reset. - */ - struct gpio_desc *reset; }; struct dsa_platform_data { diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index d61ceed912be0..df169811f26d7 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -659,9 +659,6 @@ static int dsa_of_probe(struct device *dev) const char *port_name; int chip_index, port_index; const unsigned int *sw_addr, *port_reg; - int gpio; - enum of_gpio_flags of_flags; - unsigned long flags; u32 eeprom_len; int ret; @@ -740,19 +737,6 @@ static int dsa_of_probe(struct device *dev) put_device(cd->host_dev); cd->host_dev = &mdio_bus_switch->dev; } - gpio = of_get_named_gpio_flags(child, "reset-gpios", 0, - &of_flags); - if (gpio_is_valid(gpio)) { - flags = (of_flags == OF_GPIO_ACTIVE_LOW ? - GPIOF_ACTIVE_LOW : 0); - ret = devm_gpio_request_one(dev, gpio, flags, - "switch_reset"); - if (ret) - goto out_free_chip; - - cd->reset = gpio_to_desc(gpio); - gpiod_direction_output(cd->reset, 0); - } for_each_available_child_of_node(child, port) { port_reg = of_get_property(port, "reg", NULL); From c33063d6a0d83a553faacf32f3cb834e63d8ecd7 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 10 May 2016 23:27:23 +0200 Subject: [PATCH 5/7] dsa: Remove master_dev from switch structure The switch drivers only use the master_dev member for dev_info() messages. Now that the device is passed to the old style probe, and new style drivers are probed as true linux drivers, this is no longer needed. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 1 + include/net/dsa.h | 7 ++----- net/dsa/dsa.c | 2 +- net/dsa/slave.c | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index e7e07eb7091dc..8659cbaac9f9c 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -3642,6 +3642,7 @@ int mv88e6xxx_probe(struct mdio_device *mdiodev) ps = (struct mv88e6xxx_priv_state *)(ds + 1); ds->priv = ps; + ds->dev = dev; ps->dev = dev; ps->ds = ds; ps->bus = mdiodev->bus; diff --git a/include/net/dsa.h b/include/net/dsa.h index ecb52e265cc3d..f4c0bff8d9d64 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -120,6 +120,8 @@ struct dsa_switch_tree { }; struct dsa_switch { + struct device *dev; + /* * Parent switch tree, and switch index. */ @@ -142,11 +144,6 @@ struct dsa_switch { */ struct dsa_switch_driver *drv; - /* - * Reference to host device to use. - */ - struct device *master_dev; - #ifdef CONFIG_NET_DSA_HWMON /* * Hardware monitoring information diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index df169811f26d7..5db779c69a680 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -411,7 +411,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, ds->pd = pd; ds->drv = drv; ds->priv = priv; - ds->master_dev = host_dev; + ds->dev = parent; ret = dsa_switch_setup_one(ds, parent); if (ret) diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 5ea8a40c8d33d..f25dcd9e814a1 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -51,7 +51,7 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds) ds->slave_mii_bus->write = dsa_slave_phy_write; snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d:%.2x", ds->index, ds->pd->sw_addr); - ds->slave_mii_bus->parent = ds->master_dev; + ds->slave_mii_bus->parent = ds->dev; ds->slave_mii_bus->phy_mask = ~ds->phys_mii_mask; } From ff04955c2f678a2c4c3207e0184c4c389da9d1e2 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 10 May 2016 23:27:24 +0200 Subject: [PATCH 6/7] dsa: Rename switch chip data to cd The dsa_switch structure contains a dsa_chip_data member called pd. However in the rest of the code, pd is used for dsa_platform_data. This is confusing. Rename it cd, which is already often used in dsa.c and slave.c for this data type. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/bcm_sf2.c | 4 ++-- drivers/net/dsa/mv88e6xxx.c | 4 ++-- include/net/dsa.h | 4 ++-- net/dsa/dsa.c | 18 +++++++++--------- net/dsa/slave.c | 10 +++++----- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 448deb59b9a42..10ddd5a5dfb6e 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -949,8 +949,8 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds) /* All the interesting properties are at the parent device_node * level */ - dn = ds->pd->of_node->parent; - bcm_sf2_identify_ports(priv, ds->pd->of_node); + dn = ds->cd->of_node->parent; + bcm_sf2_identify_ports(priv, ds->cd->of_node); priv->irq0 = irq_of_parse_and_map(dn, 0); priv->irq1 = irq_of_parse_and_map(dn, 1); diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 8659cbaac9f9c..ee7830935a737 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -3023,9 +3023,9 @@ static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) for (i = 0; i < 32; i++) { int nexthop = 0x1f; - if (ps->ds->pd->rtable && + if (ps->ds->cd->rtable && i != ps->ds->index && i < ps->ds->dst->pd->nr_chips) - nexthop = ps->ds->pd->rtable[i] & 0x1f; + nexthop = ps->ds->cd->rtable[i] & 0x1f; err = _mv88e6xxx_reg_write( ps, REG_GLOBAL2, diff --git a/include/net/dsa.h b/include/net/dsa.h index f4c0bff8d9d64..17c3d37b67793 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -137,7 +137,7 @@ struct dsa_switch { /* * Configuration data for this switch. */ - struct dsa_chip_data *pd; + struct dsa_chip_data *cd; /* * The used switch driver. @@ -190,7 +190,7 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds) if (dst->cpu_switch == ds->index) return dst->cpu_port; else - return ds->pd->rtable[dst->cpu_switch]; + return ds->cd->rtable[dst->cpu_switch]; } struct switchdev_trans; diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 5db779c69a680..eff5dfc2e33fc 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -182,7 +182,7 @@ __ATTRIBUTE_GROUPS(dsa_hwmon); /* basic switch operations **************************************************/ static int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct net_device *master) { - struct dsa_chip_data *cd = ds->pd; + struct dsa_chip_data *cd = ds->cd; struct device_node *port_dn; struct phy_device *phydev; int ret, port, mode; @@ -219,7 +219,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) { struct dsa_switch_driver *drv = ds->drv; struct dsa_switch_tree *dst = ds->dst; - struct dsa_chip_data *pd = ds->pd; + struct dsa_chip_data *cd = ds->cd; bool valid_name_found = false; int index = ds->index; int i, ret; @@ -230,7 +230,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) for (i = 0; i < DSA_MAX_PORTS; i++) { char *name; - name = pd->port_names[i]; + name = cd->port_names[i]; if (name == NULL) continue; @@ -328,10 +328,10 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) if (!(ds->enabled_port_mask & (1 << i))) continue; - ret = dsa_slave_create(ds, parent, i, pd->port_names[i]); + ret = dsa_slave_create(ds, parent, i, cd->port_names[i]); if (ret < 0) { netdev_err(dst->master_netdev, "[%d]: can't create dsa slave device for port %d(%s): %d\n", - index, i, pd->port_names[i], ret); + index, i, cd->port_names[i], ret); ret = 0; } } @@ -379,7 +379,7 @@ static struct dsa_switch * dsa_switch_setup(struct dsa_switch_tree *dst, int index, struct device *parent, struct device *host_dev) { - struct dsa_chip_data *pd = dst->pd->chip + index; + struct dsa_chip_data *cd = dst->pd->chip + index; struct dsa_switch_driver *drv; struct dsa_switch *ds; int ret; @@ -389,7 +389,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, /* * Probe for switch model. */ - drv = dsa_switch_probe(parent, host_dev, pd->sw_addr, &name, &priv); + drv = dsa_switch_probe(parent, host_dev, cd->sw_addr, &name, &priv); if (drv == NULL) { netdev_err(dst->master_netdev, "[%d]: could not detect attached switch\n", index); @@ -408,7 +408,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, ds->dst = dst; ds->index = index; - ds->pd = pd; + ds->cd = cd; ds->drv = drv; ds->priv = priv; ds->dev = parent; @@ -424,7 +424,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds) { struct device_node *port_dn; struct phy_device *phydev; - struct dsa_chip_data *cd = ds->pd; + struct dsa_chip_data *cd = ds->cd; int port; #ifdef CONFIG_NET_DSA_HWMON diff --git a/net/dsa/slave.c b/net/dsa/slave.c index f25dcd9e814a1..152436cdab30a 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -50,7 +50,7 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds) ds->slave_mii_bus->read = dsa_slave_phy_read; ds->slave_mii_bus->write = dsa_slave_phy_write; snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d:%.2x", - ds->index, ds->pd->sw_addr); + ds->index, ds->cd->sw_addr); ds->slave_mii_bus->parent = ds->dev; ds->slave_mii_bus->phy_mask = ~ds->phys_mii_mask; } @@ -615,8 +615,8 @@ static int dsa_slave_get_eeprom_len(struct net_device *dev) struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_switch *ds = p->parent; - if (ds->pd->eeprom_len) - return ds->pd->eeprom_len; + if (ds->cd->eeprom_len) + return ds->cd->eeprom_len; if (ds->drv->get_eeprom_len) return ds->drv->get_eeprom_len(ds); @@ -999,7 +999,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p, struct net_device *slave_dev) { struct dsa_switch *ds = p->parent; - struct dsa_chip_data *cd = ds->pd; + struct dsa_chip_data *cd = ds->cd; struct device_node *phy_dn, *port_dn; bool phy_is_fixed = false; u32 phy_flags = 0; @@ -1147,7 +1147,7 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent, NULL); SET_NETDEV_DEV(slave_dev, parent); - slave_dev->dev.of_node = ds->pd->port_dn[port]; + slave_dev->dev.of_node = ds->cd->port_dn[port]; slave_dev->vlan_features = master->vlan_features; p = netdev_priv(slave_dev); From f8cd8753def081b92b93209265bce68a73885ed0 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 10 May 2016 23:27:25 +0200 Subject: [PATCH 7/7] dsa: mv88e6xxx: Handle eeprom-length property A switch can export an attached EEPROM using the standard ethtool API. However the switch itself cannot determine the size of the EEPROM, and multiple sizes are allowed. Thus a device tree property is supported to indicate the length of the EEPROM. Parse this property during device probe, and implement a callback function to retrieve it. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 17 +++++++++++++++++ drivers/net/dsa/mv88e6xxx.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index ee7830935a737..a3f0e7ec40676 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -869,6 +869,16 @@ static int mv88e6xxx_read_eeprom_word(struct dsa_switch *ds, int addr) return ret; } +static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) + return ps->eeprom_len; + + return 0; +} + static int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, u8 *data) { @@ -3610,6 +3620,7 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = { .set_temp_limit = mv88e6xxx_set_temp_limit, .get_temp_alarm = mv88e6xxx_get_temp_alarm, #endif + .get_eeprom_len = mv88e6xxx_get_eeprom_len, .get_eeprom = mv88e6xxx_get_eeprom, .set_eeprom = mv88e6xxx_set_eeprom, .get_regs_len = mv88e6xxx_get_regs_len, @@ -3631,9 +3642,11 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = { int mv88e6xxx_probe(struct mdio_device *mdiodev) { struct device *dev = &mdiodev->dev; + struct device_node *np = dev->of_node; struct mv88e6xxx_priv_state *ps; int id, prod_num, rev; struct dsa_switch *ds; + u32 eeprom_len; int err; ds = devm_kzalloc(dev, sizeof(*ds) + sizeof(*ps), GFP_KERNEL); @@ -3676,6 +3689,10 @@ int mv88e6xxx_probe(struct mdio_device *mdiodev) } } + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM) && + !of_property_read_u32(np, "eeprom-length", &eeprom_len)) + ps->eeprom_len = eeprom_len; + dev_set_drvdata(dev, ds); dev_info(dev, "switch 0x%x probed: %s, revision %u\n", diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 9ef7673f0c61f..40e8721ecfb1d 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -602,6 +602,9 @@ struct mv88e6xxx_priv_state { * switch soft reset. */ struct gpio_desc *reset; + + /* set to size of eeprom if supported by the switch */ + int eeprom_len; }; enum stat_type {