|
@@ -21,7 +21,8 @@
|
|
|
struct mdio_mux_mmioreg_state {
|
|
struct mdio_mux_mmioreg_state {
|
|
|
void *mux_handle;
|
|
void *mux_handle;
|
|
|
phys_addr_t phys;
|
|
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;
|
|
struct mdio_mux_mmioreg_state *s = data;
|
|
|
|
|
|
|
|
if (current_child ^ desired_child) {
|
|
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)
|
|
if (!p)
|
|
|
return -ENOMEM;
|
|
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);
|
|
iounmap(p);
|
|
@@ -88,8 +119,11 @@ static int mdio_mux_mmioreg_probe(struct platform_device *pdev)
|
|
|
}
|
|
}
|
|
|
s->phys = res.start;
|
|
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;
|
|
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");
|
|
dev_err(&pdev->dev, "missing or invalid mux-mask property\n");
|
|
|
return -ENODEV;
|
|
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;
|
|
return -EINVAL;
|
|
|
}
|
|
}
|
|
|
s->mask = be32_to_cpup(iprop);
|
|
s->mask = be32_to_cpup(iprop);
|