net: dsa: rework switch parsing
When parsing a switch, we have to identify to which tree it belongs and parse its ports. Provide two functions to separate the OF and platform data specific paths. Also use the of_property_read_variable_u32_array function to parse the OF member array instead of calling of_property_read_u32_index twice. Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
0eefe2c173
Коммит
975e6e3221
115
net/dsa/dsa2.c
115
net/dsa/dsa2.c
|
@ -617,7 +617,8 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsa_parse_ports_of(struct device_node *dn, struct dsa_switch *ds)
|
static int dsa_switch_parse_ports_of(struct dsa_switch *ds,
|
||||||
|
struct device_node *dn)
|
||||||
{
|
{
|
||||||
struct device_node *ports, *port;
|
struct device_node *ports, *port;
|
||||||
struct dsa_port *dp;
|
struct dsa_port *dp;
|
||||||
|
@ -648,6 +649,39 @@ static int dsa_parse_ports_of(struct device_node *dn, struct dsa_switch *ds)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dsa_switch_parse_member_of(struct dsa_switch *ds,
|
||||||
|
struct device_node *dn)
|
||||||
|
{
|
||||||
|
u32 m[2] = { 0, 0 };
|
||||||
|
int sz;
|
||||||
|
|
||||||
|
/* Don't error out if this optional property isn't found */
|
||||||
|
sz = of_property_read_variable_u32_array(dn, "dsa,member", m, 2, 2);
|
||||||
|
if (sz < 0 && sz != -EINVAL)
|
||||||
|
return sz;
|
||||||
|
|
||||||
|
ds->index = m[1];
|
||||||
|
if (ds->index >= DSA_MAX_SWITCHES)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ds->dst = dsa_tree_touch(m[0]);
|
||||||
|
if (!ds->dst)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsa_switch_parse_of(struct dsa_switch *ds, struct device_node *dn)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = dsa_switch_parse_member_of(ds, dn);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return dsa_switch_parse_ports_of(ds, dn);
|
||||||
|
}
|
||||||
|
|
||||||
static int dsa_port_parse(struct dsa_port *dp, const char *name,
|
static int dsa_port_parse(struct dsa_port *dp, const char *name,
|
||||||
struct device *dev)
|
struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -673,7 +707,8 @@ static int dsa_port_parse(struct dsa_port *dp, const char *name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsa_parse_ports(struct dsa_chip_data *cd, struct dsa_switch *ds)
|
static int dsa_switch_parse_ports(struct dsa_switch *ds,
|
||||||
|
struct dsa_chip_data *cd)
|
||||||
{
|
{
|
||||||
bool valid_name_found = false;
|
bool valid_name_found = false;
|
||||||
struct dsa_port *dp;
|
struct dsa_port *dp;
|
||||||
|
@ -703,40 +738,19 @@ static int dsa_parse_ports(struct dsa_chip_data *cd, struct dsa_switch *ds)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsa_parse_member_dn(struct device_node *np, u32 *tree, u32 *index)
|
static int dsa_switch_parse(struct dsa_switch *ds, struct dsa_chip_data *cd)
|
||||||
{
|
{
|
||||||
int err;
|
ds->cd = cd;
|
||||||
|
|
||||||
*tree = *index = 0;
|
/* We don't support interconnected switches nor multiple trees via
|
||||||
|
* platform data, so this is the unique switch of the tree.
|
||||||
|
*/
|
||||||
|
ds->index = 0;
|
||||||
|
ds->dst = dsa_tree_touch(0);
|
||||||
|
if (!ds->dst)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
err = of_property_read_u32_index(np, "dsa,member", 0, tree);
|
return dsa_switch_parse_ports(ds, cd);
|
||||||
if (err) {
|
|
||||||
/* Does not exist, but it is optional */
|
|
||||||
if (err == -EINVAL)
|
|
||||||
return 0;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = of_property_read_u32_index(np, "dsa,member", 1, index);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (*index >= DSA_MAX_SWITCHES)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dsa_parse_member(struct dsa_chip_data *pd, u32 *tree, u32 *index)
|
|
||||||
{
|
|
||||||
if (!pd)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
/* We do not support complex trees with dsa_chip_data */
|
|
||||||
*tree = 0;
|
|
||||||
*index = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dsa_register_switch(struct dsa_switch *ds)
|
static int _dsa_register_switch(struct dsa_switch *ds)
|
||||||
|
@ -744,36 +758,21 @@ static int _dsa_register_switch(struct dsa_switch *ds)
|
||||||
struct dsa_chip_data *pdata = ds->dev->platform_data;
|
struct dsa_chip_data *pdata = ds->dev->platform_data;
|
||||||
struct device_node *np = ds->dev->of_node;
|
struct device_node *np = ds->dev->of_node;
|
||||||
struct dsa_switch_tree *dst;
|
struct dsa_switch_tree *dst;
|
||||||
u32 tree, index;
|
unsigned int index;
|
||||||
int i, err;
|
int i, err;
|
||||||
|
|
||||||
if (np) {
|
if (np)
|
||||||
err = dsa_parse_member_dn(np, &tree, &index);
|
err = dsa_switch_parse_of(ds, np);
|
||||||
if (err)
|
else if (pdata)
|
||||||
return err;
|
err = dsa_switch_parse(ds, pdata);
|
||||||
} else {
|
else
|
||||||
err = dsa_parse_member(pdata, &tree, &index);
|
err = -ENODEV;
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst = dsa_tree_touch(tree);
|
|
||||||
if (!dst)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
ds->dst = dst;
|
|
||||||
ds->index = index;
|
|
||||||
ds->cd = pdata;
|
|
||||||
|
|
||||||
if (np) {
|
|
||||||
err = dsa_parse_ports_of(np, ds);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
} else {
|
|
||||||
err = dsa_parse_ports(pdata, ds);
|
index = ds->index;
|
||||||
if (err)
|
dst = ds->dst;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the routing table */
|
/* Initialize the routing table */
|
||||||
for (i = 0; i < DSA_MAX_SWITCHES; ++i)
|
for (i = 0; i < DSA_MAX_SWITCHES; ++i)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче