net: mdio-mux-mmioreg: Add support for 16bit and 32bit register sizes
authorNeil Armstrong <narmstrong@baylibre.com>
Fri, 4 Nov 2016 15:51:22 +0000 (16:51 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 9 Nov 2016 17:50:55 +0000 (12:50 -0500)
In order to support PHY switching on Amlogic GXL SoCs, add support for
16bit and 32bit registers sizes.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/devicetree/bindings/net/mdio-mux-mmioreg.txt
drivers/net/phy/mdio-mux-mmioreg.c

index 8516929c7251877615b0081ae6d3c971b8a0c920..065e8bdb957d9d577e987dca04ce49c84afb2935 100644 (file)
@@ -3,7 +3,7 @@ Properties for an MDIO bus multiplexer controlled by a memory-mapped device
 This is a special case of a MDIO bus multiplexer.  A memory-mapped device,
 like an FPGA, is used to control which child bus is connected.  The mdio-mux
 node must be a child of the memory-mapped device.  The driver currently only
-supports devices with eight-bit registers.
+supports devices with 8, 16 or 32-bit registers.
 
 Required properties in addition to the generic multiplexer properties:
 
@@ -11,7 +11,7 @@ Required properties in addition to the generic multiplexer properties:
 
 - reg : integer, contains the offset of the register that controls the bus
        multiplexer.  The size field in the 'reg' property is the size of
-       register, and must therefore be 1.
+       register, and must therefore be 1, 2, or 4.
 
 - mux-mask : integer, contains an eight-bit mask that specifies which
        bits in the register control the actual bus multiplexer.  The
index d0bed52c8d1617237df3cd6e31b0af2711503b5c..6a33646bdf05d5af5455ea2b2862e5bd22a70008 100644 (file)
@@ -21,7 +21,8 @@
 struct mdio_mux_mmioreg_state {
        void *mux_handle;
        phys_addr_t phys;
-       uint8_t mask;
+       unsigned int iosize;
+       unsigned int mask;
 };
 
 /*
@@ -47,17 +48,47 @@ static int mdio_mux_mmioreg_switch_fn(int current_child, int desired_child,
        struct mdio_mux_mmioreg_state *s = data;
 
        if (current_child ^ desired_child) {
-               void __iomem *p = ioremap(s->phys, 1);
-               uint8_t x, y;
-
+               void __iomem *p = ioremap(s->phys, s->iosize);
                if (!p)
                        return -ENOMEM;
 
-               x = ioread8(p);
-               y = (x & ~s->mask) | desired_child;
-               if (x != y) {
-                       iowrite8((x & ~s->mask) | desired_child, p);
-                       pr_debug("%s: %02x -> %02x\n", __func__, x, y);
+               switch (s->iosize) {
+               case sizeof(uint8_t): {
+                       uint8_t x, y;
+
+                       x = ioread8(p);
+                       y = (x & ~s->mask) | desired_child;
+                       if (x != y) {
+                               iowrite8((x & ~s->mask) | desired_child, p);
+                               pr_debug("%s: %02x -> %02x\n", __func__, x, y);
+                       }
+
+                       break;
+               }
+               case sizeof(uint16_t): {
+                       uint16_t x, y;
+
+                       x = ioread16(p);
+                       y = (x & ~s->mask) | desired_child;
+                       if (x != y) {
+                               iowrite16((x & ~s->mask) | desired_child, p);
+                               pr_debug("%s: %04x -> %04x\n", __func__, x, y);
+                       }
+
+                       break;
+               }
+               case sizeof(uint32_t): {
+                       uint32_t x, y;
+
+                       x = ioread32(p);
+                       y = (x & ~s->mask) | desired_child;
+                       if (x != y) {
+                               iowrite32((x & ~s->mask) | desired_child, p);
+                               pr_debug("%s: %08x -> %08x\n", __func__, x, y);
+                       }
+
+                       break;
+               }
                }
 
                iounmap(p);
@@ -88,8 +119,11 @@ static int mdio_mux_mmioreg_probe(struct platform_device *pdev)
        }
        s->phys = res.start;
 
-       if (resource_size(&res) != sizeof(uint8_t)) {
-               dev_err(&pdev->dev, "only 8-bit registers are supported\n");
+       s->iosize = resource_size(&res);
+       if (s->iosize != sizeof(uint8_t) &&
+           s->iosize != sizeof(uint16_t) &&
+           s->iosize != sizeof(uint32_t)) {
+               dev_err(&pdev->dev, "only 8/16/32-bit registers are supported\n");
                return -EINVAL;
        }
 
@@ -98,8 +132,8 @@ static int mdio_mux_mmioreg_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "missing or invalid mux-mask property\n");
                return -ENODEV;
        }
-       if (be32_to_cpup(iprop) > 255) {
-               dev_err(&pdev->dev, "only 8-bit registers are supported\n");
+       if (be32_to_cpup(iprop) >= BIT(s->iosize * 8)) {
+               dev_err(&pdev->dev, "only 8/16/32-bit registers are supported\n");
                return -EINVAL;
        }
        s->mask = be32_to_cpup(iprop);