summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2016-04-13 02:40:42 +0200
committerDavid S. Miller <davem@davemloft.net>2016-04-13 18:15:23 -0400
commita77d43f1e9d59791b138b9903c58b89fffb0df97 (patch)
treed878967d148d62ceb9739bc4e5a9fdd63b363559
parent5feebd0a8a799fe076c606b7c3bc267ae8c4344a (diff)
downloadblackbird-op-linux-a77d43f1e9d59791b138b9903c58b89fffb0df97.tar.gz
blackbird-op-linux-a77d43f1e9d59791b138b9903c58b89fffb0df97.zip
net: dsa: Keep the mii bus and address in the private structure
Rather than looking up the mii bus and address every time, do it once at probe, and keep it in the private structure. Centralise this probe code in mv88e6xxx. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Acked-by: Florian Fainelli <f.fainelli@gmail.com> Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/dsa/mv88e6060.c44
-rw-r--r--drivers/net/dsa/mv88e6060.h11
-rw-r--r--drivers/net/dsa/mv88e6123.c15
-rw-r--r--drivers/net/dsa/mv88e6131.c15
-rw-r--r--drivers/net/dsa/mv88e6171.c15
-rw-r--r--drivers/net/dsa/mv88e6352.c15
-rw-r--r--drivers/net/dsa/mv88e6xxx.c43
-rw-r--r--drivers/net/dsa/mv88e6xxx.h14
8 files changed, 89 insertions, 83 deletions
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 41195f1417f1..46fe5dc65a99 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -19,12 +19,9 @@
static int reg_read(struct dsa_switch *ds, int addr, int reg)
{
- struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+ struct mv88e6060_priv *priv = ds_to_priv(ds);
- if (bus == NULL)
- return -EINVAL;
-
- return mdiobus_read_nested(bus, ds->pd->sw_addr + addr, reg);
+ return mdiobus_read_nested(priv->bus, priv->sw_addr + addr, reg);
}
#define REG_READ(addr, reg) \
@@ -40,12 +37,9 @@ static int reg_read(struct dsa_switch *ds, int addr, int reg)
static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
{
- struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
-
- if (bus == NULL)
- return -EINVAL;
+ struct mv88e6060_priv *priv = ds_to_priv(ds);
- return mdiobus_write_nested(bus, ds->pd->sw_addr + addr, reg, val);
+ return mdiobus_write_nested(priv->bus, priv->sw_addr + addr, reg, val);
}
#define REG_WRITE(addr, reg, val) \
@@ -57,16 +51,10 @@ static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
return __ret; \
})
-static char *mv88e6060_probe(struct device *dsa_dev, struct device *host_dev,
- int sw_addr, void **priv)
+static char *mv88e6060_get_name(struct mii_bus *bus, int sw_addr)
{
- struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
int ret;
- *priv = NULL;
- if (bus == NULL)
- return NULL;
-
ret = mdiobus_read(bus, sw_addr + REG_PORT(0), PORT_SWITCH_ID);
if (ret >= 0) {
if (ret == PORT_SWITCH_ID_6060)
@@ -81,6 +69,26 @@ static char *mv88e6060_probe(struct device *dsa_dev, struct device *host_dev,
return NULL;
}
+static char *mv88e6060_probe(struct device *dsa_dev, struct device *host_dev,
+ int sw_addr, void **_priv)
+{
+ struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
+ struct mv88e6060_priv *priv;
+ char *name;
+
+ name = mv88e6060_get_name(bus, sw_addr);
+ if (name) {
+ priv = devm_kzalloc(dsa_dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return NULL;
+ *_priv = priv;
+ priv->bus = bus;
+ priv->sw_addr = sw_addr;
+ }
+
+ return name;
+}
+
static int mv88e6060_switch_reset(struct dsa_switch *ds)
{
int i;
@@ -176,8 +184,8 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
static int mv88e6060_setup(struct dsa_switch *ds)
{
- int i;
int ret;
+ int i;
ret = mv88e6060_switch_reset(ds);
if (ret < 0)
diff --git a/drivers/net/dsa/mv88e6060.h b/drivers/net/dsa/mv88e6060.h
index cc9b2ed4aff4..10249bd16292 100644
--- a/drivers/net/dsa/mv88e6060.h
+++ b/drivers/net/dsa/mv88e6060.h
@@ -108,4 +108,15 @@
#define GLOBAL_ATU_MAC_23 0x0e
#define GLOBAL_ATU_MAC_45 0x0f
+struct mv88e6060_priv {
+ /* MDIO bus and address on bus to use. When in single chip
+ * mode, address is 0, and the switch uses multiple addresses
+ * on the bus. When in multi-chip mode, the switch uses a
+ * single address which contains two registers used for
+ * indirect access to more registers.
+ */
+ struct mii_bus *bus;
+ int sw_addr;
+};
+
#endif
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index bcab3ef22448..8aaac0894752 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -32,18 +32,9 @@ static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
static char *mv88e6123_probe(struct device *dsa_dev, struct device *host_dev,
int sw_addr, void **priv)
{
- struct mv88e6xxx_priv_state *ps;
- char *name;
-
- name = mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6123_table,
- ARRAY_SIZE(mv88e6123_table));
- if (name) {
- ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
- if (!ps)
- return NULL;
- *priv = ps;
- }
- return name;
+ return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
+ mv88e6123_table,
+ ARRAY_SIZE(mv88e6123_table));
}
static int mv88e6123_setup_global(struct dsa_switch *ds)
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index b9f9b009f65a..9e6edf94a855 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -28,18 +28,9 @@ static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
static char *mv88e6131_probe(struct device *dsa_dev, struct device *host_dev,
int sw_addr, void **priv)
{
- struct mv88e6xxx_priv_state *ps;
- char *name;
-
- name = mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6131_table,
- ARRAY_SIZE(mv88e6131_table));
- if (name) {
- ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
- if (!ps)
- return NULL;
- *priv = ps;
- }
- return name;
+ return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
+ mv88e6131_table,
+ ARRAY_SIZE(mv88e6131_table));
}
static int mv88e6131_setup_global(struct dsa_switch *ds)
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 15200928cecc..6ab86071391f 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -27,18 +27,9 @@ static const struct mv88e6xxx_switch_id mv88e6171_table[] = {
static char *mv88e6171_probe(struct device *dsa_dev, struct device *host_dev,
int sw_addr, void **priv)
{
- struct mv88e6xxx_priv_state *ps;
- char *name;
-
- name = mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6171_table,
- ARRAY_SIZE(mv88e6171_table));
- if (name) {
- ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
- if (!ps)
- return NULL;
- *priv = ps;
- }
- return name;
+ return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
+ mv88e6171_table,
+ ARRAY_SIZE(mv88e6171_table));
}
static int mv88e6171_setup_global(struct dsa_switch *ds)
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 7081a78a67e1..764b10ffb631 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -40,18 +40,9 @@ static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
static char *mv88e6352_probe(struct device *dsa_dev, struct device *host_dev,
int sw_addr, void **priv)
{
- struct mv88e6xxx_priv_state *ps;
- char *name;
-
- name = mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6352_table,
- ARRAY_SIZE(mv88e6352_table));
- if (name) {
- ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
- if (!ps)
- return NULL;
- *priv = ps;
- }
- return name;
+ return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
+ mv88e6352_table,
+ ARRAY_SIZE(mv88e6352_table));
}
static int mv88e6352_setup_global(struct dsa_switch *ds)
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 085fc4a49eb2..c242ffd8eb09 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -94,15 +94,12 @@ static int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr,
static int _mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
{
- struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
assert_smi_lock(ds);
- if (bus == NULL)
- return -EINVAL;
-
- ret = __mv88e6xxx_reg_read(bus, ds->pd->sw_addr, addr, reg);
+ ret = __mv88e6xxx_reg_read(ps->bus, ps->sw_addr, addr, reg);
if (ret < 0)
return ret;
@@ -159,17 +156,14 @@ static int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
static int _mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg,
u16 val)
{
- struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
assert_smi_lock(ds);
- if (bus == NULL)
- return -EINVAL;
-
dev_dbg(ds->master_dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
addr, reg, val);
- return __mv88e6xxx_reg_write(bus, ds->pd->sw_addr, addr, reg, val);
+ return __mv88e6xxx_reg_write(ps->bus, ps->sw_addr, addr, reg, val);
}
int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
@@ -2671,7 +2665,6 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds)
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
ps->ds = ds;
-
mutex_init(&ps->smi_mutex);
ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0;
@@ -3075,9 +3068,9 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
}
#endif /* CONFIG_NET_DSA_HWMON */
-char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
- const struct mv88e6xxx_switch_id *table,
- unsigned int num)
+static char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
+ const struct mv88e6xxx_switch_id *table,
+ unsigned int num)
{
struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
int i, ret;
@@ -3107,6 +3100,28 @@ char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
return NULL;
}
+char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
+ int sw_addr, void **priv,
+ const struct mv88e6xxx_switch_id *table,
+ unsigned int num)
+{
+ struct mv88e6xxx_priv_state *ps;
+ char *name;
+
+ name = mv88e6xxx_lookup_name(host_dev, sw_addr, table, num);
+ if (name) {
+ ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
+ if (!ps)
+ return NULL;
+ *priv = ps;
+ ps->bus = dsa_host_dev_to_mii_bus(host_dev);
+ if (!ps->bus)
+ return NULL;
+ ps->sw_addr = sw_addr;
+ }
+ return name;
+}
+
static int __init mv88e6xxx_init(void)
{
#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 0322e3e0e7d9..5d27decc85cb 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -406,6 +406,12 @@ struct mv88e6xxx_priv_state {
*/
struct mutex smi_mutex;
+ /* The MII bus and the address on the bus that is used to
+ * communication with the switch
+ */
+ struct mii_bus *bus;
+ int sw_addr;
+
#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
/* Handles automatic disabling and re-enabling of the PHY
* polling unit.
@@ -456,9 +462,11 @@ struct mv88e6xxx_hw_stat {
};
int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
-char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
- const struct mv88e6xxx_switch_id *table,
- unsigned int num);
+char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
+ int sw_addr, void **priv,
+ const struct mv88e6xxx_switch_id *table,
+ unsigned int num);
+
int mv88e6xxx_setup_ports(struct dsa_switch *ds);
int mv88e6xxx_setup_common(struct dsa_switch *ds);
int mv88e6xxx_setup_global(struct dsa_switch *ds);
OpenPOWER on IntegriCloud