Skip to content

Commit c1869d5

Browse files
committed
Merge branch 'more-dsa-probing'
Andrew Lunn says: ==================== More enabler patches for DSA probing The complete set of patches for the reworked DSA probing is too big to post as once. These subset contains some enablers which are easy to review. Eventually, the Marvell driver will instantiate its own internal MDIO bus, rather than have the framework do it, thus allows devices on the bus to be listed in the device tree. Initialize the main mutex as soon as it is created, to avoid lifetime issues with the mdio bus. A previous patch renamed all the DSA probe functions to make room for a true device probe. However the recent merging of all the Marvell switch drivers resulted in mv88e6xxx going back to the old probe name. Rename it again, so we can have a driver probe function. Add minimum support for the Marvell switch driver to probe as an MDIO device, as well as an DSA driver. Later patches will then register this device with the new DSA core framework. Move the GPIO reset code out of the DSA code. Different drivers may need different reset mechanisms, e.g. via a reset controller for memory mapped devices. Don't clutter up the core with this. Let each driver implement what it needs. master_dev is no longer needed in the switch drivers, since they have access to a device pointer from the probe function. Remove it. Let the switch parse the eeprom length from its one device tree node. This is required with the new binding when the central DSA platform device no longer exists. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents cb9b902 + f8cd875 commit c1869d5

File tree

8 files changed

+177
-78
lines changed

8 files changed

+177
-78
lines changed

Documentation/devicetree/bindings/net/dsa/dsa.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ A switch child node has the following optional property:
3131
switch. Must be set if the switch can not detect
3232
the presence and/or size of a connected EEPROM,
3333
otherwise optional.
34-
- reset-gpios : phandle and specifier to a gpio line connected to
35-
reset pin of the switch chip.
3634

3735
A switch may have multiple "port" children nodes
3836

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Marvell DSA Switch Device Tree Bindings
2+
---------------------------------------
3+
4+
WARNING: This binding is currently unstable. Do not program it into a
5+
FLASH never to be changed again. Once this binding is stable, this
6+
warning will be removed.
7+
8+
If you need a stable binding, use the old dsa.txt binding.
9+
10+
Marvell Switches are MDIO devices. The following properties should be
11+
placed as a child node of an mdio device.
12+
13+
The properties described here are those specific to Marvell devices.
14+
Additional required and optional properties can be found in dsa.txt.
15+
16+
Required properties:
17+
- compatible : Should be one of "marvell,mv88e6085",
18+
- reg : Address on the MII bus for the switch.
19+
20+
Optional properties:
21+
22+
- reset-gpios : Should be a gpio specifier for a reset line
23+
24+
Example:
25+
26+
mdio {
27+
#address-cells = <1>;
28+
#size-cells = <0>;
29+
30+
switch0: switch@0 {
31+
compatible = "marvell,mv88e6085";
32+
reg = <0>;
33+
reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
34+
};
35+
};

drivers/net/dsa/bcm_sf2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -949,8 +949,8 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
949949
/* All the interesting properties are at the parent device_node
950950
* level
951951
*/
952-
dn = ds->pd->of_node->parent;
953-
bcm_sf2_identify_ports(priv, ds->pd->of_node);
952+
dn = ds->cd->of_node->parent;
953+
bcm_sf2_identify_ports(priv, ds->cd->of_node);
954954

955955
priv->irq0 = irq_of_parse_and_map(dn, 0);
956956
priv->irq1 = irq_of_parse_and_map(dn, 1);

drivers/net/dsa/mv88e6xxx.c

Lines changed: 110 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* Copyright (c) 2015 CMC Electronics, Inc.
66
* Added support for VLAN Table Unit operations
77
*
8+
* Copyright (c) 2016 Andrew Lunn <[email protected]>
9+
*
810
* This program is free software; you can redistribute it and/or modify
911
* it under the terms of the GNU General Public License as published by
1012
* the Free Software Foundation; either version 2 of the License, or
@@ -17,6 +19,7 @@
1719
#include <linux/if_bridge.h>
1820
#include <linux/jiffies.h>
1921
#include <linux/list.h>
22+
#include <linux/mdio.h>
2023
#include <linux/module.h>
2124
#include <linux/netdevice.h>
2225
#include <linux/gpio/consumer.h>
@@ -866,6 +869,16 @@ static int mv88e6xxx_read_eeprom_word(struct dsa_switch *ds, int addr)
866869
return ret;
867870
}
868871

872+
static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
873+
{
874+
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
875+
876+
if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
877+
return ps->eeprom_len;
878+
879+
return 0;
880+
}
881+
869882
static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
870883
struct ethtool_eeprom *eeprom, u8 *data)
871884
{
@@ -2579,7 +2592,7 @@ static int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps)
25792592
{
25802593
bool ppu_active = mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE);
25812594
u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
2582-
struct gpio_desc *gpiod = ps->ds->pd->reset;
2595+
struct gpio_desc *gpiod = ps->reset;
25832596
unsigned long timeout;
25842597
int ret;
25852598
int i;
@@ -3020,9 +3033,9 @@ static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
30203033
for (i = 0; i < 32; i++) {
30213034
int nexthop = 0x1f;
30223035

3023-
if (ps->ds->pd->rtable &&
3036+
if (ps->ds->cd->rtable &&
30243037
i != ps->ds->index && i < ps->ds->dst->pd->nr_chips)
3025-
nexthop = ps->ds->pd->rtable[i] & 0x1f;
3038+
nexthop = ps->ds->cd->rtable[i] & 0x1f;
30263039

30273040
err = _mv88e6xxx_reg_write(
30283041
ps, REG_GLOBAL2,
@@ -3132,8 +3145,6 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
31323145

31333146
ps->ds = ds;
31343147

3135-
mutex_init(&ps->smi_mutex);
3136-
31373148
INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
31383149

31393150
if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
@@ -3545,9 +3556,9 @@ mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table,
35453556
return NULL;
35463557
}
35473558

3548-
static const char *mv88e6xxx_probe(struct device *dsa_dev,
3549-
struct device *host_dev, int sw_addr,
3550-
void **priv)
3559+
static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
3560+
struct device *host_dev, int sw_addr,
3561+
void **priv)
35513562
{
35523563
const struct mv88e6xxx_info *info;
35533564
struct mv88e6xxx_priv_state *ps;
@@ -3580,6 +3591,7 @@ static const char *mv88e6xxx_probe(struct device *dsa_dev,
35803591
ps->bus = bus;
35813592
ps->sw_addr = sw_addr;
35823593
ps->info = info;
3594+
mutex_init(&ps->smi_mutex);
35833595

35843596
*priv = ps;
35853597

@@ -3591,7 +3603,7 @@ static const char *mv88e6xxx_probe(struct device *dsa_dev,
35913603

35923604
struct dsa_switch_driver mv88e6xxx_switch_driver = {
35933605
.tag_protocol = DSA_TAG_PROTO_EDSA,
3594-
.probe = mv88e6xxx_probe,
3606+
.probe = mv88e6xxx_drv_probe,
35953607
.setup = mv88e6xxx_setup,
35963608
.set_addr = mv88e6xxx_set_addr,
35973609
.phy_read = mv88e6xxx_phy_read,
@@ -3608,6 +3620,7 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = {
36083620
.set_temp_limit = mv88e6xxx_set_temp_limit,
36093621
.get_temp_alarm = mv88e6xxx_get_temp_alarm,
36103622
#endif
3623+
.get_eeprom_len = mv88e6xxx_get_eeprom_len,
36113624
.get_eeprom = mv88e6xxx_get_eeprom,
36123625
.set_eeprom = mv88e6xxx_set_eeprom,
36133626
.get_regs_len = mv88e6xxx_get_regs_len,
@@ -3626,36 +3639,106 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = {
36263639
.port_fdb_dump = mv88e6xxx_port_fdb_dump,
36273640
};
36283641

3629-
static int __init mv88e6xxx_init(void)
3642+
int mv88e6xxx_probe(struct mdio_device *mdiodev)
36303643
{
3631-
register_switch_driver(&mv88e6xxx_switch_driver);
3644+
struct device *dev = &mdiodev->dev;
3645+
struct device_node *np = dev->of_node;
3646+
struct mv88e6xxx_priv_state *ps;
3647+
int id, prod_num, rev;
3648+
struct dsa_switch *ds;
3649+
u32 eeprom_len;
3650+
int err;
3651+
3652+
ds = devm_kzalloc(dev, sizeof(*ds) + sizeof(*ps), GFP_KERNEL);
3653+
if (!ds)
3654+
return -ENOMEM;
3655+
3656+
ps = (struct mv88e6xxx_priv_state *)(ds + 1);
3657+
ds->priv = ps;
3658+
ds->dev = dev;
3659+
ps->dev = dev;
3660+
ps->ds = ds;
3661+
ps->bus = mdiodev->bus;
3662+
ps->sw_addr = mdiodev->addr;
3663+
mutex_init(&ps->smi_mutex);
3664+
3665+
get_device(&ps->bus->dev);
3666+
3667+
ds->drv = &mv88e6xxx_switch_driver;
3668+
3669+
id = mv88e6xxx_reg_read(ps, REG_PORT(0), PORT_SWITCH_ID);
3670+
if (id < 0)
3671+
return id;
3672+
3673+
prod_num = (id & 0xfff0) >> 4;
3674+
rev = id & 0x000f;
3675+
3676+
ps->info = mv88e6xxx_lookup_info(prod_num, mv88e6xxx_table,
3677+
ARRAY_SIZE(mv88e6xxx_table));
3678+
if (!ps->info)
3679+
return -ENODEV;
3680+
3681+
ps->reset = devm_gpiod_get(&mdiodev->dev, "reset", GPIOD_ASIS);
3682+
if (IS_ERR(ps->reset)) {
3683+
err = PTR_ERR(ps->reset);
3684+
if (err == -ENOENT) {
3685+
/* Optional, so not an error */
3686+
ps->reset = NULL;
3687+
} else {
3688+
return err;
3689+
}
3690+
}
3691+
3692+
if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM) &&
3693+
!of_property_read_u32(np, "eeprom-length", &eeprom_len))
3694+
ps->eeprom_len = eeprom_len;
3695+
3696+
dev_set_drvdata(dev, ds);
3697+
3698+
dev_info(dev, "switch 0x%x probed: %s, revision %u\n",
3699+
prod_num, ps->info->name, rev);
36323700

36333701
return 0;
36343702
}
3703+
3704+
static void mv88e6xxx_remove(struct mdio_device *mdiodev)
3705+
{
3706+
struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
3707+
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3708+
3709+
put_device(&ps->bus->dev);
3710+
}
3711+
3712+
static const struct of_device_id mv88e6xxx_of_match[] = {
3713+
{ .compatible = "marvell,mv88e6085" },
3714+
{ /* sentinel */ },
3715+
};
3716+
3717+
MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);
3718+
3719+
static struct mdio_driver mv88e6xxx_driver = {
3720+
.probe = mv88e6xxx_probe,
3721+
.remove = mv88e6xxx_remove,
3722+
.mdiodrv.driver = {
3723+
.name = "mv88e6085",
3724+
.of_match_table = mv88e6xxx_of_match,
3725+
},
3726+
};
3727+
3728+
static int __init mv88e6xxx_init(void)
3729+
{
3730+
register_switch_driver(&mv88e6xxx_switch_driver);
3731+
return mdio_driver_register(&mv88e6xxx_driver);
3732+
}
36353733
module_init(mv88e6xxx_init);
36363734

36373735
static void __exit mv88e6xxx_cleanup(void)
36383736
{
3737+
mdio_driver_unregister(&mv88e6xxx_driver);
36393738
unregister_switch_driver(&mv88e6xxx_switch_driver);
36403739
}
36413740
module_exit(mv88e6xxx_cleanup);
36423741

3643-
MODULE_ALIAS("platform:mv88e6085");
3644-
MODULE_ALIAS("platform:mv88e6095");
3645-
MODULE_ALIAS("platform:mv88e6095f");
3646-
MODULE_ALIAS("platform:mv88e6123");
3647-
MODULE_ALIAS("platform:mv88e6131");
3648-
MODULE_ALIAS("platform:mv88e6161");
3649-
MODULE_ALIAS("platform:mv88e6165");
3650-
MODULE_ALIAS("platform:mv88e6171");
3651-
MODULE_ALIAS("platform:mv88e6172");
3652-
MODULE_ALIAS("platform:mv88e6175");
3653-
MODULE_ALIAS("platform:mv88e6176");
3654-
MODULE_ALIAS("platform:mv88e6320");
3655-
MODULE_ALIAS("platform:mv88e6321");
3656-
MODULE_ALIAS("platform:mv88e6350");
3657-
MODULE_ALIAS("platform:mv88e6351");
3658-
MODULE_ALIAS("platform:mv88e6352");
36593742
MODULE_AUTHOR("Lennert Buytenhek <[email protected]>");
36603743
MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
36613744
MODULE_LICENSE("GPL");

drivers/net/dsa/mv88e6xxx.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#define __MV88E6XXX_H
1313

1414
#include <linux/if_vlan.h>
15+
#include <linux/gpio/consumer.h>
1516

1617
#ifndef UINT64_MAX
1718
#define UINT64_MAX (u64)(~((u64)0))
@@ -595,6 +596,15 @@ struct mv88e6xxx_priv_state {
595596
DECLARE_BITMAP(port_state_update_mask, DSA_MAX_PORTS);
596597

597598
struct work_struct bridge_work;
599+
600+
/* A switch may have a GPIO line tied to its reset pin. Parse
601+
* this from the device tree, and use it before performing
602+
* switch soft reset.
603+
*/
604+
struct gpio_desc *reset;
605+
606+
/* set to size of eeprom if supported by the switch */
607+
int eeprom_len;
598608
};
599609

600610
enum stat_type {

include/net/dsa.h

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <linux/timer.h>
1717
#include <linux/workqueue.h>
1818
#include <linux/of.h>
19-
#include <linux/of_gpio.h>
2019
#include <linux/phy.h>
2120
#include <linux/phy_fixed.h>
2221
#include <linux/ethtool.h>
@@ -65,13 +64,6 @@ struct dsa_chip_data {
6564
* NULL if there is only one switch chip.
6665
*/
6766
s8 *rtable;
68-
69-
/*
70-
* A switch may have a GPIO line tied to its reset pin. Parse
71-
* this from the device tree, and use it before performing
72-
* switch soft reset.
73-
*/
74-
struct gpio_desc *reset;
7567
};
7668

7769
struct dsa_platform_data {
@@ -128,6 +120,8 @@ struct dsa_switch_tree {
128120
};
129121

130122
struct dsa_switch {
123+
struct device *dev;
124+
131125
/*
132126
* Parent switch tree, and switch index.
133127
*/
@@ -143,18 +137,13 @@ struct dsa_switch {
143137
/*
144138
* Configuration data for this switch.
145139
*/
146-
struct dsa_chip_data *pd;
140+
struct dsa_chip_data *cd;
147141

148142
/*
149143
* The used switch driver.
150144
*/
151145
struct dsa_switch_driver *drv;
152146

153-
/*
154-
* Reference to host device to use.
155-
*/
156-
struct device *master_dev;
157-
158147
#ifdef CONFIG_NET_DSA_HWMON
159148
/*
160149
* Hardware monitoring information
@@ -201,7 +190,7 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
201190
if (dst->cpu_switch == ds->index)
202191
return dst->cpu_port;
203192
else
204-
return ds->pd->rtable[dst->cpu_switch];
193+
return ds->cd->rtable[dst->cpu_switch];
205194
}
206195

207196
struct switchdev_trans;

0 commit comments

Comments
 (0)