Skip to content

Commit

Permalink
net: dsa: mv88e6xxx: Add minimal platform_data support
Browse files Browse the repository at this point in the history
Not all the world uses device tree. Some parts of the world still use
platform devices and platform data. Add basic support for probing a
Marvell switch via platform data.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Andrew Lunn authored and David S. Miller committed May 20, 2018
1 parent 577941e commit 877b7cb
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 7 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -8466,6 +8466,7 @@ M: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/dsa/mv88e6xxx/
F: linux/platform_data/mv88e6xxx.h
F: Documentation/devicetree/bindings/net/dsa/marvell.txt

MARVELL ARMADA DRM SUPPORT
Expand Down
56 changes: 49 additions & 7 deletions drivers/net/dsa/mv88e6xxx/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/of_mdio.h>
#include <linux/platform_data/mv88e6xxx.h>
#include <linux/netdevice.h>
#include <linux/gpio/consumer.h>
#include <linux/phy.h>
Expand Down Expand Up @@ -4350,6 +4351,7 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
return -ENOMEM;

ds->priv = chip;
ds->dev = dev;
ds->ops = &mv88e6xxx_switch_ops;
ds->ageing_time_min = chip->info->age_time_coeff;
ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
Expand All @@ -4364,36 +4366,73 @@ static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
dsa_unregister_switch(chip->ds);
}

static const void *pdata_device_get_match_data(struct device *dev)
{
const struct of_device_id *matches = dev->driver->of_match_table;
const struct dsa_mv88e6xxx_pdata *pdata = dev->platform_data;

for (; matches->name[0] || matches->type[0] || matches->compatible[0];
matches++) {
if (!strcmp(pdata->compatible, matches->compatible))
return matches->data;
}
return NULL;
}

static int mv88e6xxx_probe(struct mdio_device *mdiodev)
{
struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data;
struct device *dev = &mdiodev->dev;
struct device_node *np = dev->of_node;
const struct mv88e6xxx_info *compat_info;
struct mv88e6xxx_chip *chip;
u32 eeprom_len;
int port;
int err;

compat_info = of_device_get_match_data(dev);
if (np)
compat_info = of_device_get_match_data(dev);

if (pdata) {
compat_info = pdata_device_get_match_data(dev);

if (!pdata->netdev)
return -EINVAL;

for (port = 0; port < DSA_MAX_PORTS; port++) {
if (!(pdata->enabled_ports & (1 << port)))
continue;
if (strcmp(pdata->cd.port_names[port], "cpu"))
continue;
pdata->cd.netdev[port] = &pdata->netdev->dev;
break;
}
}

if (!compat_info)
return -EINVAL;

chip = mv88e6xxx_alloc_chip(dev);
if (!chip)
return -ENOMEM;
if (!chip) {
err = -ENOMEM;
goto out;
}

chip->info = compat_info;

err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
if (err)
return err;
goto out;

chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(chip->reset))
return PTR_ERR(chip->reset);
if (IS_ERR(chip->reset)) {
err = PTR_ERR(chip->reset);
goto out;
}

err = mv88e6xxx_detect(chip);
if (err)
return err;
goto out;

mv88e6xxx_phy_init(chip);

Expand Down Expand Up @@ -4468,6 +4507,9 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
mv88e6xxx_irq_poll_free(chip);
mutex_unlock(&chip->reg_lock);
out:
if (pdata)
dev_put(pdata->netdev);

return err;
}

Expand Down
17 changes: 17 additions & 0 deletions include/linux/platform_data/mv88e6xxx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __DSA_MV88E6XXX_H
#define __DSA_MV88E6XXX_H

#include <net/dsa.h>

struct dsa_mv88e6xxx_pdata {
/* Must be first, such that dsa_register_switch() can access this
* without gory pointer manipulations
*/
struct dsa_chip_data cd;
const char *compatible;
unsigned int enabled_ports;
struct net_device *netdev;
};

#endif

0 comments on commit 877b7cb

Please sign in to comment.