diff options
author | Andrew Lunn <andrew@lunn.ch> | 2015-06-20 16:42:33 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-06-23 13:33:42 (GMT) |
commit | 56d95e2220fc3582eef1b124abc2b7a4735d198a (patch) | |
tree | 6550d9546fdadd04d45717d40345cd74627e2d0d /drivers/net/dsa | |
parent | d35bd876afe88e4fe781a4edc376d03eb9d3dcf3 (diff) | |
download | linux-56d95e2220fc3582eef1b124abc2b7a4735d198a.tar.xz |
dsa: mv88x6xxx: Add debugfs interface for scratch registers
Allow the contents of the scratch registers to be shown in debugfs.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx.c | 54 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx.h | 3 |
2 files changed, 57 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 7e12a31..c938d7c 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -901,6 +901,13 @@ static int _mv88e6xxx_atu_wait(struct dsa_switch *ds) GLOBAL_ATU_OP_BUSY); } +/* Must be called with SMI lock held */ +static int _mv88e6xxx_scratch_wait(struct dsa_switch *ds) +{ + return _mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_SCRATCH_MISC, + GLOBAL2_SCRATCH_BUSY); +} + /* Must be called with SMI mutex held */ static int _mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum) @@ -1825,6 +1832,50 @@ static const struct file_operations mv88e6xxx_device_map_fops = { .owner = THIS_MODULE, }; +static int mv88e6xxx_scratch_show(struct seq_file *s, void *p) +{ + struct dsa_switch *ds = s->private; + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int reg, ret; + + seq_puts(s, "Register Value\n"); + + mutex_lock(&ps->smi_mutex); + for (reg = 0; reg < 0x80; reg++) { + ret = _mv88e6xxx_reg_write( + ds, REG_GLOBAL2, GLOBAL2_SCRATCH_MISC, + reg << GLOBAL2_SCRATCH_REGISTER_SHIFT); + if (ret < 0) + goto out; + + ret = _mv88e6xxx_scratch_wait(ds); + if (ret < 0) + goto out; + + ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL2, + GLOBAL2_SCRATCH_MISC); + seq_printf(s, " %2x %2x\n", reg, + ret & GLOBAL2_SCRATCH_VALUE_MASK); + } +out: + mutex_unlock(&ps->smi_mutex); + + return 0; +} + +static int mv88e6xxx_scratch_open(struct inode *inode, struct file *file) +{ + return single_open(file, mv88e6xxx_scratch_show, inode->i_private); +} + +static const struct file_operations mv88e6xxx_scratch_fops = { + .open = mv88e6xxx_scratch_open, + .read = seq_read, + .llseek = no_llseek, + .release = single_release, + .owner = THIS_MODULE, +}; + int mv88e6xxx_setup_common(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -1853,6 +1904,9 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds) debugfs_create_file("device_map", S_IRUGO, ps->dbgfs, ds, &mv88e6xxx_device_map_fops); + + debugfs_create_file("scratch", S_IRUGO, ps->dbgfs, ds, + &mv88e6xxx_scratch_fops); return 0; } diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index a2c9ac0..a650b26 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -297,6 +297,9 @@ #define GLOBAL2_SMI_OP_45_READ_DATA ((2 << 10) | GLOBAL2_SMI_OP_BUSY) #define GLOBAL2_SMI_DATA 0x19 #define GLOBAL2_SCRATCH_MISC 0x1a +#define GLOBAL2_SCRATCH_BUSY BIT(15) +#define GLOBAL2_SCRATCH_REGISTER_SHIFT 8 +#define GLOBAL2_SCRATCH_VALUE_MASK 0xff #define GLOBAL2_WDOG_CONTROL 0x1b #define GLOBAL2_QOS_WEIGHT 0x1c #define GLOBAL2_MISC 0x1d |