diff mbox series

[net-next] net: dsa: mv88e6xxx: scratch registers and external MDIO pins

Message ID 1519177012-16165-1-git-send-email-andrew@lunn.ch
State Superseded, archived
Delegated to: David Miller
Headers show
Series [net-next] net: dsa: mv88e6xxx: scratch registers and external MDIO pins | expand

Commit Message

Andrew Lunn Feb. 21, 2018, 1:36 a.m. UTC
MV88E6352 and later switches support GPIO control through the "Scratch
& Misc" global2 register. Two of the pins controlled this way on the
mv88e6390 family are the external MDIO pins. They can either by used
as part of the MII interface for port 0, GPIOs, or MDIO. Add a
function to configure them for MDIO, if possible, and call it when
registering the external MDIO bus.

Suggested-by: Russell King <rmk@armlinux.org.uk>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c            |  9 +++++
 drivers/net/dsa/mv88e6xxx/global2.h         | 14 ++++++++
 drivers/net/dsa/mv88e6xxx/global2_scratch.c | 51 +++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+)

Comments

kernel test robot Feb. 21, 2018, 9:40 a.m. UTC | #1
Hi Andrew,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Andrew-Lunn/net-dsa-mv88e6xxx-scratch-registers-and-external-MDIO-pins/20180221-150325
config: i386-randconfig-i0-201807 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/net/dsa/mv88e6xxx/serdes.o: In function `mv88e6xxx_g2_scratch_gpio_set_ext_smi':
>> drivers/net/dsa/mv88e6xxx/global2.h:478: multiple definition of `mv88e6xxx_g2_scratch_gpio_set_ext_smi'
   drivers/net/dsa/mv88e6xxx/chip.o:drivers/net/dsa/mv88e6xxx/global2.h:478: first defined here

vim +478 drivers/net/dsa/mv88e6xxx/global2.h

   475	
   476	int mv88e6xxx_g2_scratch_gpio_set_ext_smi(struct mv88e6xxx_chip *chip,
   477						  bool external)
 > 478	{
   479		return -EOPNOTSUPP;
   480	}
   481	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Andrew Lunn Feb. 21, 2018, 2:46 p.m. UTC | #2
On Wed, Feb 21, 2018 at 05:40:29PM +0800, kbuild test robot wrote:
> Hi Andrew,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on net-next/master]
> 
> url:    https://github.com/0day-ci/linux/commits/Andrew-Lunn/net-dsa-mv88e6xxx-scratch-registers-and-external-MDIO-pins/20180221-150325
> config: i386-randconfig-i0-201807 (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=i386 
> 
> All errors (new ones prefixed by >>):
> 
>    drivers/net/dsa/mv88e6xxx/serdes.o: In function `mv88e6xxx_g2_scratch_gpio_set_ext_smi':
> >> drivers/net/dsa/mv88e6xxx/global2.h:478: multiple definition of `mv88e6xxx_g2_scratch_gpio_set_ext_smi'
>    drivers/net/dsa/mv88e6xxx/chip.o:drivers/net/dsa/mv88e6xxx/global2.h:478: first defined here
> 
> vim +478 drivers/net/dsa/mv88e6xxx/global2.h
> 
>    475	
>    476	int mv88e6xxx_g2_scratch_gpio_set_ext_smi(struct mv88e6xxx_chip *chip,
>    477						  bool external)
>  > 478	{
>    479		return -EOPNOTSUPP;
>    480	}

The stub function needs to be inline. I will fix up in v2.

    Andrew
diff mbox series

Patch

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 39c7ad7e490f..f9ed612a6e39 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2165,6 +2165,15 @@  static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
 	struct mii_bus *bus;
 	int err;
 
+	if (external) {
+		mutex_lock(&chip->reg_lock);
+		err = mv88e6xxx_g2_scratch_gpio_set_ext_smi(chip, true);
+		mutex_unlock(&chip->reg_lock);
+
+		if (err)
+			return err;
+	}
+
 	bus = devm_mdiobus_alloc_size(chip->dev, sizeof(*mdio_bus));
 	if (!bus)
 		return -ENOMEM;
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index 25f92b3d7157..c1c7df133d3f 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -266,6 +266,11 @@ 
 #define MV88E6352_G2_SCRATCH_GPIO_PCTL5		0x6D
 #define MV88E6352_G2_SCRATCH_GPIO_PCTL6		0x6E
 #define MV88E6352_G2_SCRATCH_GPIO_PCTL7		0x6F
+#define MV88E6352_G2_SCRATCH_CONFIG_DATA0	0x70
+#define MV88E6352_G2_SCRATCH_CONFIG_DATA1	0x71
+#define MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU	BIT(2)
+#define MV88E6352_G2_SCRATCH_CONFIG_DATA2	0x72
+#define MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK	0x3
 
 #define MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO	0
 #define MV88E6352_G2_SCRATCH_GPIO_PCTL_TRIG	1
@@ -325,6 +330,9 @@  extern const struct mv88e6xxx_avb_ops mv88e6390_avb_ops;
 
 extern const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops;
 
+int mv88e6xxx_g2_scratch_gpio_set_ext_smi(struct mv88e6xxx_chip *chip,
+					  bool external);
+
 #else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
 
 static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip)
@@ -465,6 +473,12 @@  static const struct mv88e6xxx_avb_ops mv88e6390_avb_ops = {};
 
 static const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {};
 
+int mv88e6xxx_g2_scratch_gpio_set_ext_smi(struct mv88e6xxx_chip *chip,
+					  bool external)
+{
+	return -EOPNOTSUPP;
+}
+
 #endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
 
 #endif /* _MV88E6XXX_GLOBAL2_H */
diff --git a/drivers/net/dsa/mv88e6xxx/global2_scratch.c b/drivers/net/dsa/mv88e6xxx/global2_scratch.c
index 0ff12bff9f0e..632fd4d91c44 100644
--- a/drivers/net/dsa/mv88e6xxx/global2_scratch.c
+++ b/drivers/net/dsa/mv88e6xxx/global2_scratch.c
@@ -238,3 +238,54 @@  const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {
 	.get_pctl = mv88e6352_g2_scratch_gpio_get_pctl,
 	.set_pctl = mv88e6352_g2_scratch_gpio_set_pctl,
 };
+
+/**
+ * mv88e6xxx_g2_gpio_set_ext_smi - set gpio muxing for external smi
+ * @chip: chip private data
+ * @external: set mux for external smi, or free for gpio usage
+ *
+ * Some mv88e6xxx models have GPIO pins that may be configured as
+ * an external SMI interface, or they may be made free for other
+ * GPIO uses.
+ */
+int mv88e6xxx_g2_scratch_gpio_set_ext_smi(struct mv88e6xxx_chip *chip,
+					  bool external)
+{
+	int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG;
+	int config_data1 = MV88E6352_G2_SCRATCH_CONFIG_DATA1;
+	int config_data2 = MV88E6352_G2_SCRATCH_CONFIG_DATA2;
+	bool no_cpu;
+	u8 p0_mode;
+	int err;
+	u8 val;
+
+	err = mv88e6xxx_g2_scratch_read(chip, config_data2, &val);
+	if (err)
+		return err;
+
+	p0_mode = val & MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK;
+
+	if (p0_mode == 0x01 || p0_mode == 0x02)
+		return -EBUSY;
+
+	err = mv88e6xxx_g2_scratch_read(chip, config_data1, &val);
+	if (err)
+		return err;
+
+	no_cpu = !!(val & MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU);
+
+	err = mv88e6xxx_g2_scratch_read(chip, misc_cfg, &val);
+	if (err)
+		return err;
+
+	/* NO_CPU being 0 inverts the meaning of the bit */
+	if (!no_cpu)
+		external = !external;
+
+	if (external)
+		val |= MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
+	else
+		val &= ~MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
+
+	return mv88e6xxx_g2_scratch_write(chip, misc_cfg, val);
+}