Commit bf4bd7a7 authored by David S. Miller's avatar David S. Miller

Merge branch 'mv88exxx-pdata'

Andrew Lunn says:

====================
Platform data support for mv88exxx

There are a few Intel based platforms making use of the mv88exxx.
These don't easily have access to device tree in order to instantiate
the switch driver. These patches allow the use of platform data to
hold the configuration.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 81ee33d8 00baabe5
...@@ -8466,6 +8466,7 @@ M: Vivien Didelot <vivien.didelot@savoirfairelinux.com> ...@@ -8466,6 +8466,7 @@ M: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: drivers/net/dsa/mv88e6xxx/ F: drivers/net/dsa/mv88e6xxx/
F: linux/platform_data/mv88e6xxx.h
F: Documentation/devicetree/bindings/net/dsa/marvell.txt F: Documentation/devicetree/bindings/net/dsa/marvell.txt
MARVELL ARMADA DRM SUPPORT MARVELL ARMADA DRM SUPPORT
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_mdio.h> #include <linux/of_mdio.h>
#include <linux/platform_data/mv88e6xxx.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/phy.h> #include <linux/phy.h>
...@@ -4350,6 +4351,7 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip) ...@@ -4350,6 +4351,7 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
return -ENOMEM; return -ENOMEM;
ds->priv = chip; ds->priv = chip;
ds->dev = dev;
ds->ops = &mv88e6xxx_switch_ops; ds->ops = &mv88e6xxx_switch_ops;
ds->ageing_time_min = chip->info->age_time_coeff; ds->ageing_time_min = chip->info->age_time_coeff;
ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
...@@ -4364,42 +4366,82 @@ static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip) ...@@ -4364,42 +4366,82 @@ static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
dsa_unregister_switch(chip->ds); 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) static int mv88e6xxx_probe(struct mdio_device *mdiodev)
{ {
struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data;
struct device *dev = &mdiodev->dev; struct device *dev = &mdiodev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
const struct mv88e6xxx_info *compat_info; const struct mv88e6xxx_info *compat_info;
struct mv88e6xxx_chip *chip; struct mv88e6xxx_chip *chip;
u32 eeprom_len; int port;
int err; 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) if (!compat_info)
return -EINVAL; return -EINVAL;
chip = mv88e6xxx_alloc_chip(dev); chip = mv88e6xxx_alloc_chip(dev);
if (!chip) if (!chip) {
return -ENOMEM; err = -ENOMEM;
goto out;
}
chip->info = compat_info; chip->info = compat_info;
err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr); err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
if (err) if (err)
return err; goto out;
chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(chip->reset)) if (IS_ERR(chip->reset)) {
return PTR_ERR(chip->reset); err = PTR_ERR(chip->reset);
goto out;
}
err = mv88e6xxx_detect(chip); err = mv88e6xxx_detect(chip);
if (err) if (err)
return err; goto out;
mv88e6xxx_phy_init(chip); mv88e6xxx_phy_init(chip);
if (chip->info->ops->get_eeprom && if (chip->info->ops->get_eeprom) {
!of_property_read_u32(np, "eeprom-length", &eeprom_len)) if (np)
chip->eeprom_len = eeprom_len; of_property_read_u32(np, "eeprom-length",
&chip->eeprom_len);
else
chip->eeprom_len = pdata->eeprom_len;
}
mutex_lock(&chip->reg_lock); mutex_lock(&chip->reg_lock);
err = mv88e6xxx_switch_reset(chip); err = mv88e6xxx_switch_reset(chip);
...@@ -4468,6 +4510,9 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev) ...@@ -4468,6 +4510,9 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
mv88e6xxx_irq_poll_free(chip); mv88e6xxx_irq_poll_free(chip);
mutex_unlock(&chip->reg_lock); mutex_unlock(&chip->reg_lock);
out: out:
if (pdata)
dev_put(pdata->netdev);
return err; return err;
} }
......
...@@ -238,7 +238,7 @@ struct mv88e6xxx_chip { ...@@ -238,7 +238,7 @@ struct mv88e6xxx_chip {
struct gpio_desc *reset; struct gpio_desc *reset;
/* set to size of eeprom if supported by the switch */ /* set to size of eeprom if supported by the switch */
int eeprom_len; u32 eeprom_len;
/* List of mdio busses */ /* List of mdio busses */
struct list_head mdios; struct list_head mdios;
......
...@@ -1047,9 +1047,6 @@ int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip) ...@@ -1047,9 +1047,6 @@ int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
{ {
int err, irq, virq; int err, irq, virq;
if (!chip->dev->of_node)
return -EINVAL;
chip->g2_irq.domain = irq_domain_add_simple( chip->g2_irq.domain = irq_domain_add_simple(
chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip); chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
if (!chip->g2_irq.domain) if (!chip->g2_irq.domain)
......
/* 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;
u32 eeprom_len;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment