* [PATCH v2 00/17] MV88E6xxx switch family support
@ 2018-10-09 17:37 Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 01/17] ARM: Do not expose ARMv8 functions on ARMv7 Andrey Smirnov
` (16 more replies)
0 siblings, 17 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Everyone:
Patches in this series are a result of my work on porting Linux code
for MV88E6xxx switches to Barebox.
- Patch 1 is loosely related header fix
- Patches 2 and 3 add clocksource support for ARM global time,
needed on VF610 in order to get an accurate
clocksource. MV88E6xxx EEPROM supporte code turned out to be
dependent on that.
- Pathes 4 and 5 are clocksource related fixes
- Patches 6, 7, 8, 9 update the device naming scheme used by
Barebox driver code. Old scheme couldn't handle devices created
for DT nodes with identical names. This was the case on ZII
VF610 Development Board Rev. C which had two switch devices.
- Patch 10 is documentation/small code fix for generic MDIO bus
code
- Patches 11, 12 bring needed preprocessor constants from Linux kernel
- Patch 13 prevents PHYs masked by MDIO bus's phy_maks from being
probed
- Patch 14 allows custom platform deviecs to be attached to an MDIO bus
- Patch 15 exposes internal MDIO bus on MV88E6xxx devices
- Patch 16 support for EEPROM devices attached to MV88E6xxx devices
- Patch 17 exposes ports that don't have a PHY attached as
"virtual" PHY devices (RPU2 needs this code to properly
configure port connected to FEC)
NOTE: This is quite a mix and I am more than happy to split this
series in several if current patch grouping is problematic.
Tested on the following H/W:
- ZII i.MX6Q RDU2, MV88E6352 switch
- ZII i.MX51 RDU1, MV88E6161 switch
- ZII i.MX7D RPU2, MV88E6352 switch
- ZII VF610 CFU1, MV88E6352 switch
- ZII VF610 SPU3, MV88E6390X switch
- ZII VF610 Development Board Rev. C, MV88E6390X switch x 2
Feedback is welcome!
Changes since [v1]:
- CONFIG_CLOCKSOURCE_ARM_GLOBAL_TIMER is not selected by
default. VF610 now selects it explicitly
- Incorrect logic in patch 14/17 was fixed to correctly handle PHY
nodes that have "compatible" property
- Added more documentation for dev_set_name()
[v1] http://lists.infradead.org/pipermail/barebox/2018-October/034963.html
Thanks,
Andrey Smirnov
Andrey Smirnov (17):
ARM: Do not expose ARMv8 functions on ARMv7
clocksource: Add ARM global timer support
VFxxx: Select CLOCKSOURCE_ARM_GLOBAL_TIMER
i.MX: Move GPT driver to drivers/clocksource
clocksource: Introduce ARCH_HAS_IMX_GPT
of: Demote "Bad cell count for" to debug
drivers: Introduce dev_set_name()
linux: string: Port kbasename()
of: Port latest of_device_make_bus_id() implementation
mdio_bus: Fix documentation for mdio_bus_match()
include: linux: phy: Add missing PHY_INTERFACE_* constants
include: linux: ethtool: Add missing *_UNKNOWN constants
net: phy: Check phy_mask in get_phy_device()
mdio_bus: Allow for non PHY-devices on MDIO buses
net: phy: Add basic driver for MV88E6XXX switches from Marvell
net: phy: mv88e6xxx: Port EEPROM support code
net: phy: mv88e6xxx: Add support for MAC ports
arch/arm/include/asm/system.h | 2 +-
arch/arm/mach-imx/Kconfig | 12 +
arch/arm/mach-imx/Makefile | 1 -
arch/arm/mach-imx/iim.c | 2 +-
.../arm/mach-imx/include/mach/devices-imx51.h | 2 +-
.../arm/mach-imx/include/mach/devices-imx53.h | 2 +-
arch/arm/mach-mxs/include/mach/devices.h | 2 +-
arch/arm/mach-mxs/ocotp.c | 2 +-
arch/sandbox/board/console.c | 2 +-
common/console.c | 4 +-
common/state/state.c | 2 +-
drivers/aiodev/core.c | 2 +-
drivers/amba/bus.c | 2 +-
drivers/ata/disk_ata_drive.c | 4 +-
drivers/base/bus.c | 2 +-
drivers/base/driver.c | 47 +-
drivers/base/resource.c | 2 +-
drivers/clocksource/Kconfig | 10 +
drivers/clocksource/Makefile | 2 +
drivers/clocksource/arm_global_timer.c | 113 +++
.../clocksource/timer-imx-gpt.c | 0
drivers/efi/efi-device.c | 2 +-
drivers/firmware/socfpga.c | 2 +-
drivers/i2c/i2c.c | 4 +-
drivers/mci/mci-core.c | 4 +-
drivers/mfd/rave-sp.c | 2 +-
drivers/mtd/core.c | 2 +-
drivers/mtd/spi-nor/cadence-quadspi.c | 2 +-
drivers/mtd/ubi/build.c | 2 +-
drivers/mtd/ubi/vmt.c | 4 +-
drivers/net/cpsw.c | 2 +-
drivers/net/e1000/eeprom.c | 2 +-
drivers/net/orion-gbe.c | 2 +-
drivers/net/phy/Kconfig | 6 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/mdio_bus.c | 27 +-
drivers/net/phy/mv88e6xxx/Makefile | 5 +
drivers/net/phy/mv88e6xxx/chip.c | 945 ++++++++++++++++++
drivers/net/phy/mv88e6xxx/chip.h | 143 +++
drivers/net/phy/mv88e6xxx/global2.c | 389 +++++++
drivers/net/phy/mv88e6xxx/global2.h | 70 ++
drivers/net/phy/mv88e6xxx/port.c | 666 ++++++++++++
drivers/net/phy/mv88e6xxx/port.h | 127 +++
drivers/net/phy/phy.c | 15 +-
drivers/nvmem/core.c | 2 +-
drivers/nvmem/ocotp.c | 2 +-
drivers/of/address.c | 4 +-
drivers/of/platform.c | 80 +-
drivers/pci/bus.c | 3 +-
drivers/phy/phy-core.c | 2 +-
drivers/pwm/core.c | 2 +-
drivers/rtc/class.c | 2 +-
drivers/spi/spi.c | 2 +-
drivers/usb/core/usb.c | 5 +-
drivers/usb/gadget/udc-core.c | 4 +-
drivers/usb/musb/musb_dsps.c | 2 +-
drivers/video/backlight.c | 2 +-
drivers/video/fb.c | 2 +-
drivers/w1/w1.c | 4 +-
drivers/watchdog/wd_core.c | 2 +-
fs/fs.c | 2 +-
include/driver.h | 11 +-
include/linux/ethtool.h | 3 +
include/linux/phy.h | 9 +
include/linux/string.h | 12 +
net/eth.c | 2 +-
66 files changed, 2669 insertions(+), 131 deletions(-)
create mode 100644 drivers/clocksource/arm_global_timer.c
rename arch/arm/mach-imx/clocksource.c => drivers/clocksource/timer-imx-gpt.c (100%)
create mode 100644 drivers/net/phy/mv88e6xxx/Makefile
create mode 100644 drivers/net/phy/mv88e6xxx/chip.c
create mode 100644 drivers/net/phy/mv88e6xxx/chip.h
create mode 100644 drivers/net/phy/mv88e6xxx/global2.c
create mode 100644 drivers/net/phy/mv88e6xxx/global2.h
create mode 100644 drivers/net/phy/mv88e6xxx/port.c
create mode 100644 drivers/net/phy/mv88e6xxx/port.h
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 01/17] ARM: Do not expose ARMv8 functions on ARMv7
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 02/17] clocksource: Add ARM global timer support Andrey Smirnov
` (15 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Assembly implementing current_el(), read_mpidr(), set_cntfrq(),
get_cntfrq() and get_cntpct() is ARMv8 specific, so change #if guard
protecting it to reflect that fact.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
arch/arm/include/asm/system.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 5cf828ea3..2f13e2b98 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -61,7 +61,7 @@
#define CR_TE (1 << 30) /* Thumb exception enable */
#ifndef __ASSEMBLY__
-#if __LINUX_ARM_ARCH__ >= 7
+#if __LINUX_ARM_ARCH__ > 7
static inline unsigned int current_el(void)
{
unsigned int el;
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 02/17] clocksource: Add ARM global timer support
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 01/17] ARM: Do not expose ARMv8 functions on ARMv7 Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-11 8:28 ` Sascha Hauer
2018-10-09 17:37 ` [PATCH v2 03/17] VFxxx: Select CLOCKSOURCE_ARM_GLOBAL_TIMER Andrey Smirnov
` (14 subsequent siblings)
16 siblings, 1 reply; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port corresponding Linux kernel driver. Currently VFxxx SoC is the
intended consumer because it doesn't include common i.MX GPT block
used as clocksource by other i.MX SoCs.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/clocksource/Kconfig | 4 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/arm_global_timer.c | 113 +++++++++++++++++++++++++
3 files changed, 118 insertions(+)
create mode 100644 drivers/clocksource/arm_global_timer.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 3d63f7ff1..6a6c9362a 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -70,3 +70,7 @@ config CLOCKSOURCE_ARMV8_TIMER
bool
default y
depends on ARM && CPU_64v8
+
+config CLOCKSOURCE_ARM_GLOBAL_TIMER
+ bool
+ depends on ARM && CPU_V7
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index ea33fff50..51f6cb2f4 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_CLOCKSOURCE_UEMD) += uemd.o
obj-$(CONFIG_CLOCKSOURCE_ROCKCHIP)+= rk_timer.o
obj-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += timer-atmel-pit.o
obj-$(CONFIG_CLOCKSOURCE_ARMV8_TIMER) += armv8-timer.o
+obj-$(CONFIG_CLOCKSOURCE_ARM_GLOBAL_TIMER) += arm_global_timer.o
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
new file mode 100644
index 000000000..44e3a3c76
--- /dev/null
+++ b/drivers/clocksource/arm_global_timer.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Clocksource driver for generic Cortex A9 timer block
+ *
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * based on corresponding driver from Linux kernel with the following
+ * copyright:
+ *
+ * drivers/clocksource/arm_global_timer.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Stuart Menefy <stuart.menefy@st.com>
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ */
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <asm/system.h>
+
+#define GT_COUNTER0 0x00
+#define GT_COUNTER1 0x04
+
+#define GT_CONTROL 0x08
+#define GT_CONTROL_TIMER_ENABLE BIT(0) /* this bit is NOT banked */
+
+static void __iomem *gt_base;
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ * different to the 32-bit upper value read previously, go back to step 2.
+ * Otherwise the 64-bit timer counter value is correct.
+ */
+static uint64_t arm_global_clocksource_read(void)
+{
+ uint64_t counter;
+ uint32_t lower;
+ uint32_t upper, old_upper;
+
+ upper = readl(gt_base + GT_COUNTER1);
+ do {
+ old_upper = upper;
+ lower = readl(gt_base + GT_COUNTER0);
+ upper = readl(gt_base + GT_COUNTER1);
+ } while (upper != old_upper);
+
+ counter = upper;
+ counter <<= 32;
+ counter |= lower;
+ return counter;
+}
+
+static struct clocksource cs = {
+ .read = arm_global_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .shift = 0,
+};
+
+static int arm_global_timer_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ struct clk *clk;
+ int ret;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+
+ clk = clk_get(dev, NULL);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "clock not found: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_enable(clk);
+ if (ret) {
+ dev_err(dev, "clock failed to enable: %d\n", ret);
+ return ret;
+ }
+
+ gt_base = IOMEM(iores->start);
+
+ cs.mult = clocksource_hz2mult(clk_get_rate(clk), cs.shift);
+
+ writel(0, gt_base + GT_CONTROL);
+ writel(0, gt_base + GT_COUNTER0);
+ writel(0, gt_base + GT_COUNTER1);
+ /* enables timer on all the cores */
+ writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
+
+ return init_clock(&cs);
+}
+
+static struct of_device_id arm_global_timer_dt_ids[] = {
+ { .compatible = "arm,cortex-a9-global-timer", },
+ { }
+};
+
+static struct driver_d arm_global_timer_driver = {
+ .name = "arm-global-timer",
+ .probe = arm_global_timer_probe,
+ .of_compatible = DRV_OF_COMPAT(arm_global_timer_dt_ids),
+};
+postcore_platform_driver(arm_global_timer_driver);
+
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 03/17] VFxxx: Select CLOCKSOURCE_ARM_GLOBAL_TIMER
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 01/17] ARM: Do not expose ARMv8 functions on ARMv7 Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 02/17] clocksource: Add ARM global timer support Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 04/17] i.MX: Move GPT driver to drivers/clocksource Andrey Smirnov
` (13 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
arch/arm/mach-imx/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 4a56fb9f4..8d161bee2 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -185,6 +185,7 @@ config ARCH_VF610
select COMMON_CLK_OF_PROVIDER
select NVMEM
select IMX_OCOTP # Needed for clock adjustement
+ select CLOCKSOURCE_ARM_GLOBAL_TIMER
config IMX_MULTI_BOARDS
bool "Allow multiple boards to be selected"
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 04/17] i.MX: Move GPT driver to drivers/clocksource
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (2 preceding siblings ...)
2018-10-09 17:37 ` [PATCH v2 03/17] VFxxx: Select CLOCKSOURCE_ARM_GLOBAL_TIMER Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 05/17] clocksource: Introduce ARCH_HAS_IMX_GPT Andrey Smirnov
` (12 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Move GPT driver to drivers/clocksource and rename it to
timer-imx-gpt.c to match Linux kernel as well as to keep all
clocksource drivers in a common location.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
arch/arm/mach-imx/Makefile | 1 -
drivers/clocksource/Kconfig | 3 +++
drivers/clocksource/Makefile | 1 +
.../clocksource.c => drivers/clocksource/timer-imx-gpt.c | 0
4 files changed, 4 insertions(+), 1 deletion(-)
rename arch/arm/mach-imx/clocksource.c => drivers/clocksource/timer-imx-gpt.c (100%)
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 5a01dd57e..97c54406e 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,4 +1,3 @@
-obj-y += clocksource.o
obj-$(CONFIG_ARCH_IMX1) += imx1.o
obj-$(CONFIG_ARCH_IMX25) += imx25.o
obj-$(CONFIG_ARCH_IMX21) += imx21.o
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 6a6c9362a..c65066ccf 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -74,3 +74,6 @@ config CLOCKSOURCE_ARMV8_TIMER
config CLOCKSOURCE_ARM_GLOBAL_TIMER
bool
depends on ARM && CPU_V7
+config CLOCKSOURCE_IMX_GPT
+ def_bool y
+ depends on ARCH_IMX
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 51f6cb2f4..ce4d74137 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_CLOCKSOURCE_ROCKCHIP)+= rk_timer.o
obj-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += timer-atmel-pit.o
obj-$(CONFIG_CLOCKSOURCE_ARMV8_TIMER) += armv8-timer.o
obj-$(CONFIG_CLOCKSOURCE_ARM_GLOBAL_TIMER) += arm_global_timer.o
+obj-$(CONFIG_CLOCKSOURCE_IMX_GPT) += timer-imx-gpt.o
diff --git a/arch/arm/mach-imx/clocksource.c b/drivers/clocksource/timer-imx-gpt.c
similarity index 100%
rename from arch/arm/mach-imx/clocksource.c
rename to drivers/clocksource/timer-imx-gpt.c
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 05/17] clocksource: Introduce ARCH_HAS_IMX_GPT
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (3 preceding siblings ...)
2018-10-09 17:37 ` [PATCH v2 04/17] i.MX: Move GPT driver to drivers/clocksource Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 06/17] of: Demote "Bad cell count for" to debug Andrey Smirnov
` (11 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Not all SoCs use i.MX GPT block as a clocksource, so introduce
ARCH_HAS_IMX_GPT to mark the ones that do.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
arch/arm/mach-imx/Kconfig | 11 +++++++++++
drivers/clocksource/Kconfig | 5 ++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 8d161bee2..3aff62d89 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -85,58 +85,68 @@ comment "Freescale i.MX System-on-Chip"
config ARCH_IMX1
bool
select CPU_ARM920T
+ select ARCH_HAS_IMX_GPT
select PINCTRL_IMX_IOMUX_V1
config ARCH_IMX21
bool
select CPU_ARM926T
+ select ARCH_HAS_IMX_GPT
select PINCTRL_IMX_IOMUX_V1
config ARCH_IMX25
bool
select CPU_ARM926T
select ARCH_HAS_FEC_IMX
+ select ARCH_HAS_IMX_GPT
select PINCTRL_IMX_IOMUX_V3
config ARCH_IMX27
bool
select CPU_ARM926T
select ARCH_HAS_FEC_IMX
+ select ARCH_HAS_IMX_GPT
select PINCTRL_IMX_IOMUX_V1
config ARCH_IMX31
select CPU_V6
bool
+ select ARCH_HAS_IMX_GPT
select PINCTRL_IMX_IOMUX_V2
config ARCH_IMX35
bool
select CPU_V6
select ARCH_HAS_FEC_IMX
+ select ARCH_HAS_IMX_GPT
select PINCTRL_IMX_IOMUX_V3
config ARCH_IMX50
bool
select CPU_V7
select ARCH_HAS_FEC_IMX
+ select ARCH_HAS_IMX_GPT
select PINCTRL_IMX_IOMUX_V3
config ARCH_IMX51
bool
select CPU_V7
select ARCH_HAS_FEC_IMX
+ select ARCH_HAS_IMX_GPT
select PINCTRL_IMX_IOMUX_V3
config ARCH_IMX53
bool
select CPU_V7
select ARCH_HAS_FEC_IMX
+ select ARCH_HAS_IMX_GPT
select PINCTRL_IMX_IOMUX_V3
config ARCH_IMX6
bool
select ARCH_HAS_L2X0
select ARCH_HAS_FEC_IMX
+ select ARCH_HAS_IMX_GPT
select CPU_V7
select PINCTRL_IMX_IOMUX_V3
select OFTREE
@@ -164,6 +174,7 @@ config ARCH_IMX7
select OFTREE
select COMMON_CLK_OF_PROVIDER
select ARCH_HAS_FEC_IMX
+ select ARCH_HAS_IMX_GPT
config ARCH_IMX8MQ
bool
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index c65066ccf..a33532652 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -1,3 +1,6 @@
+config ARCH_HAS_IMX_GPT
+ bool
+
config AMBA_SP804
bool
depends on ARM_AMBA
@@ -76,4 +79,4 @@ config CLOCKSOURCE_ARM_GLOBAL_TIMER
depends on ARM && CPU_V7
config CLOCKSOURCE_IMX_GPT
def_bool y
- depends on ARCH_IMX
+ depends on ARCH_HAS_IMX_GPT
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 06/17] of: Demote "Bad cell count for" to debug
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (4 preceding siblings ...)
2018-10-09 17:37 ` [PATCH v2 05/17] clocksource: Introduce ARCH_HAS_IMX_GPT Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 07/17] drivers: Introduce dev_set_name() Andrey Smirnov
` (10 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
There are valid use-cases where getting OF_BAD_ADDR via that codepath
is expected. In addition to that analogous code in Linux kernel uses
pr_debug as well.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/of/address.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 14db08041..4e12522a0 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -379,8 +379,8 @@ static u64 __of_translate_address(struct device_node *dev,
/* Count address cells & copy address locally */
bus->count_cells(dev, &na, &ns);
if (!OF_CHECK_COUNTS(na, ns)) {
- printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
- dev->full_name);
+ pr_debug("prom_parse: Bad cell count for %s\n",
+ dev->full_name);
return OF_BAD_ADDR;
}
memcpy(addr, in_addr, na * 4);
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 07/17] drivers: Introduce dev_set_name()
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (5 preceding siblings ...)
2018-10-09 17:37 ` [PATCH v2 06/17] of: Demote "Bad cell count for" to debug Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-10 2:57 ` Andrey Smirnov
2018-10-10 9:41 ` Lucas Stach
2018-10-09 17:37 ` [PATCH v2 08/17] linux: string: Port kbasename() Andrey Smirnov
` (9 subsequent siblings)
16 siblings, 2 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
In order to allow device names that are longer than MAX_DRIVER_NAME,
port Linux kernel function of the same name, and convert all of the
code to use it.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
arch/arm/mach-imx/iim.c | 2 +-
.../arm/mach-imx/include/mach/devices-imx51.h | 2 +-
.../arm/mach-imx/include/mach/devices-imx53.h | 2 +-
arch/arm/mach-mxs/include/mach/devices.h | 2 +-
arch/arm/mach-mxs/ocotp.c | 2 +-
arch/sandbox/board/console.c | 2 +-
common/console.c | 4 +-
common/state/state.c | 2 +-
drivers/aiodev/core.c | 2 +-
drivers/amba/bus.c | 2 +-
drivers/ata/disk_ata_drive.c | 4 +-
drivers/base/bus.c | 2 +-
drivers/base/driver.c | 47 +++++++++++++++++--
drivers/base/resource.c | 2 +-
drivers/efi/efi-device.c | 2 +-
drivers/firmware/socfpga.c | 2 +-
drivers/i2c/i2c.c | 4 +-
drivers/mci/mci-core.c | 4 +-
drivers/mfd/rave-sp.c | 2 +-
drivers/mtd/core.c | 2 +-
drivers/mtd/spi-nor/cadence-quadspi.c | 2 +-
drivers/mtd/ubi/build.c | 2 +-
drivers/mtd/ubi/vmt.c | 4 +-
drivers/net/cpsw.c | 2 +-
drivers/net/e1000/eeprom.c | 2 +-
drivers/net/orion-gbe.c | 2 +-
drivers/net/phy/mdio_bus.c | 2 +-
drivers/net/phy/phy.c | 8 ++--
drivers/nvmem/core.c | 2 +-
drivers/nvmem/ocotp.c | 2 +-
drivers/of/platform.c | 12 ++---
drivers/pci/bus.c | 3 +-
drivers/phy/phy-core.c | 2 +-
drivers/pwm/core.c | 2 +-
drivers/rtc/class.c | 2 +-
drivers/spi/spi.c | 2 +-
drivers/usb/core/usb.c | 5 +-
drivers/usb/gadget/udc-core.c | 4 +-
drivers/usb/musb/musb_dsps.c | 2 +-
drivers/video/backlight.c | 2 +-
drivers/video/fb.c | 2 +-
drivers/w1/w1.c | 4 +-
drivers/watchdog/wd_core.c | 2 +-
fs/fs.c | 2 +-
include/driver.h | 11 +++--
net/eth.c | 2 +-
46 files changed, 113 insertions(+), 67 deletions(-)
diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c
index d4794cbac..207e1879c 100644
--- a/arch/arm/mach-imx/iim.c
+++ b/arch/arm/mach-imx/iim.c
@@ -474,7 +474,7 @@ static int imx_iim_probe(struct device_d *dev)
imx_iim = iim;
- strcpy(iim->dev.name, "iim");
+ dev_set_name(&iim->dev, "iim");
iim->dev.parent = dev;
iim->dev.id = DEVICE_ID_SINGLE;
ret = register_device(&iim->dev);
diff --git a/arch/arm/mach-imx/include/mach/devices-imx51.h b/arch/arm/mach-imx/include/mach/devices-imx51.h
index cccd8f461..66fe643f8 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx51.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx51.h
@@ -81,7 +81,7 @@ static inline struct device_d *imx51_add_nand(struct imx_nand_platform_data *pda
dev->resource = xzalloc(sizeof(struct resource) * ARRAY_SIZE(res));
memcpy(dev->resource, res, sizeof(struct resource) * ARRAY_SIZE(res));
dev->num_resources = ARRAY_SIZE(res);
- strcpy(dev->name, "imx_nand");
+ dev_set_name(dev, "imx_nand");
dev->id = DEVICE_ID_DYNAMIC;
dev->platform_data = pdata;
diff --git a/arch/arm/mach-imx/include/mach/devices-imx53.h b/arch/arm/mach-imx/include/mach/devices-imx53.h
index 10caae8c9..27200a26d 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx53.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx53.h
@@ -95,7 +95,7 @@ static inline struct device_d *imx53_add_nand(struct imx_nand_platform_data *pda
dev->resource = xzalloc(sizeof(struct resource) * ARRAY_SIZE(res));
memcpy(dev->resource, res, sizeof(struct resource) * ARRAY_SIZE(res));
dev->num_resources = ARRAY_SIZE(res);
- strcpy(dev->name, "imx_nand");
+ dev_set_name(dev, "imx_nand");
dev->id = DEVICE_ID_DYNAMIC;
dev->platform_data = pdata;
diff --git a/arch/arm/mach-mxs/include/mach/devices.h b/arch/arm/mach-mxs/include/mach/devices.h
index 5680d61c9..b212aa783 100644
--- a/arch/arm/mach-mxs/include/mach/devices.h
+++ b/arch/arm/mach-mxs/include/mach/devices.h
@@ -26,7 +26,7 @@ static inline struct device_d *mxs_add_nand(unsigned long gpmi_base, unsigned lo
dev->resource = xzalloc(sizeof(struct resource) * ARRAY_SIZE(res));
memcpy(dev->resource, res, sizeof(struct resource) * ARRAY_SIZE(res));
dev->num_resources = ARRAY_SIZE(res);
- strcpy(dev->name, "mxs_nand");
+ dev_set_name(dev, "mxs_nand");
dev->id = DEVICE_ID_DYNAMIC;
platform_device_register(dev);
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
index b41fde991..01db73116 100644
--- a/arch/arm/mach-mxs/ocotp.c
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -197,7 +197,7 @@ static int mxs_ocotp_probe(struct device_d *dev)
priv->cdev.size = cpu_is_mx23() ? 128 : 160;
priv->cdev.name = DRIVERNAME;
- strcpy(priv->dev.name, "ocotp");
+ dev_set_name(&priv->dev, "ocotp");
priv->dev.parent = dev;
err = register_device(&priv->dev);
if (err)
diff --git a/arch/sandbox/board/console.c b/arch/sandbox/board/console.c
index cf1781d15..006bbd1a6 100644
--- a/arch/sandbox/board/console.c
+++ b/arch/sandbox/board/console.c
@@ -32,7 +32,7 @@ int barebox_register_console(int stdinfd, int stdoutfd)
data = (struct linux_console_data *)(dev + 1);
dev->platform_data = data;
- strcpy(dev->name, "console");
+ dev_set_name(dev, "console");
dev->id = DEVICE_ID_DYNAMIC;
data->stdoutfd = stdoutfd;
diff --git a/common/console.c b/common/console.c
index 40c26b66d..47ccf2e54 100644
--- a/common/console.c
+++ b/common/console.c
@@ -314,10 +314,10 @@ int console_register(struct console_device *newcdev)
if (newcdev->devname) {
dev->id = newcdev->devid;
- strcpy(dev->name, newcdev->devname);
+ dev_set_name(dev, newcdev->devname);
} else {
dev->id = DEVICE_ID_DYNAMIC;
- strcpy(dev->name, "cs");
+ dev_set_name(dev, "cs");
}
if (newcdev->dev)
diff --git a/common/state/state.c b/common/state/state.c
index 25d950211..55804a521 100644
--- a/common/state/state.c
+++ b/common/state/state.c
@@ -179,7 +179,7 @@ static struct state *state_new(const char *name)
int ret;
state = xzalloc(sizeof(*state));
- safe_strncpy(state->dev.name, name, MAX_DRIVER_NAME);
+ dev_set_name(&state->dev, name);
state->name = state->dev.name;
state->dev.id = DEVICE_ID_SINGLE;
INIT_LIST_HEAD(&state->variables);
diff --git a/drivers/aiodev/core.c b/drivers/aiodev/core.c
index 79f935d71..cb53cfb7d 100644
--- a/drivers/aiodev/core.c
+++ b/drivers/aiodev/core.c
@@ -115,7 +115,7 @@ int aiodevice_register(struct aiodevice *aiodev)
aiodev->dev.id = DEVICE_ID_DYNAMIC;
}
- strcpy(aiodev->dev.name, aiodev->name);
+ dev_set_name(&aiodev->dev, aiodev->name);
aiodev->dev.parent = aiodev->hwdev;
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index ae5df13c9..a8cd16835 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -200,7 +200,7 @@ struct amba_device *amba_device_alloc(const char *name, int id, resource_size_t
dev = xzalloc(sizeof(*dev));
- strcpy(dev->dev.name, name);
+ dev_set_name(&dev->dev, name);
dev->dev.id = id;
dev->res.start = base;
dev->res.end = base + size - 1;
diff --git a/drivers/ata/disk_ata_drive.c b/drivers/ata/disk_ata_drive.c
index 5ebddbdec..11f7151e5 100644
--- a/drivers/ata/disk_ata_drive.c
+++ b/drivers/ata/disk_ata_drive.c
@@ -325,10 +325,10 @@ int ata_port_register(struct ata_port *port)
int ret;
if (port->devname) {
- strcpy(port->class_dev.name, port->devname);
+ dev_set_name(&port->class_dev, port->devname);
port->class_dev.id = DEVICE_ID_SINGLE;
} else {
- strcpy(port->class_dev.name, "ata");
+ dev_set_name(&port->class_dev, "ata");
port->class_dev.id = DEVICE_ID_DYNAMIC;
}
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index b889a4866..1038d20a1 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -32,7 +32,7 @@ int bus_register(struct bus_type *bus)
return -EEXIST;
bus->dev = xzalloc(sizeof(*bus->dev));
- strcpy(bus->dev->name, bus->name);
+ dev_set_name(bus->dev, bus->name);
bus->dev->id = DEVICE_ID_SINGLE;
ret = register_device(bus->dev);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index c43a4bde2..c25498bf4 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -468,16 +468,57 @@ EXPORT_SYMBOL(dummy_probe);
const char *dev_id(const struct device_d *dev)
{
- static char buf[MAX_DRIVER_NAME + 16];
+ static char *buf;
+ int err;
+
+ if (buf)
+ free(buf);
if (dev->id != DEVICE_ID_SINGLE)
- snprintf(buf, sizeof(buf), FORMAT_DRIVER_NAME_ID, dev->name, dev->id);
+ err = asprintf(&buf, FORMAT_DRIVER_NAME_ID,
+ dev->name, dev->id);
else
- snprintf(buf, sizeof(buf), "%s", dev->name);
+ err = asprintf(&buf, "%s", dev->name);
+
+ BUG_ON(err < 0);
return buf;
}
+/**
+ * dev_set_name - set a device name
+ * @dev: device
+ * @fmt: format string for the device's name
+ *
+ * NOTE: This function expects dev->name to be free()-able, so extra
+ * precautions needs to be taken when mixing its usage with manual
+ * assignement of device_d.name.
+ */
+int dev_set_name(struct device_d *dev, const char *fmt, ...)
+{
+ va_list vargs;
+ int err;
+ /*
+ * Save old pointer in case we are overriding already set name
+ */
+ char *oldname = dev->name;
+
+ va_start(vargs, fmt);
+ err = vasprintf(&dev->name, fmt, vargs);
+ va_end(vargs);
+
+ /*
+ * Free old pointer, we do this after vasprintf call in case
+ * old device name was in one of vargs
+ */
+ free(oldname);
+
+ WARN_ON(err < 0);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(dev_set_name);
+
static void devices_shutdown(void)
{
struct device_d *dev;
diff --git a/drivers/base/resource.c b/drivers/base/resource.c
index 6c2d7fed4..cb7105bf8 100644
--- a/drivers/base/resource.c
+++ b/drivers/base/resource.c
@@ -27,7 +27,7 @@ struct device_d *device_alloc(const char *devname, int id)
struct device_d *dev;
dev = xzalloc(sizeof(*dev));
- strcpy(dev->name, devname);
+ dev_set_name(dev, devname);
dev->id = id;
return dev;
diff --git a/drivers/efi/efi-device.c b/drivers/efi/efi-device.c
index 3a27323a0..b7dea7c82 100644
--- a/drivers/efi/efi-device.c
+++ b/drivers/efi/efi-device.c
@@ -185,7 +185,7 @@ static struct efi_device *efi_add_device(efi_handle_t *handle, efi_guid_t **guid
efidev->dev.info = efi_devinfo;
efidev->devpath = devpath;
- sprintf(efidev->dev.name, "handle-%p", handle);
+ dev_set_name(&efidev->dev, "handle-%p", handle);
efidev->parent_handle = efi_find_parent(efidev->handle);
diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index c1eae98ac..6d11da32a 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -438,7 +438,7 @@ static int fpgamgr_probe(struct device_d *dev)
dev_dbg(dev, "Registering FPGA firmware programmer\n");
mgr->dev.id = DEVICE_ID_SINGLE;
- strcpy(mgr->dev.name, "fpga");
+ dev_set_name(&mgr->dev, "fpga");
mgr->dev.parent = dev;
ret = register_device(&mgr->dev);
if (ret)
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 608f8289b..25e0fe7ad 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -389,7 +389,7 @@ static struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
int status;
client = xzalloc(sizeof *client);
- strcpy(client->dev.name, chip->type);
+ dev_set_name(&client->dev, chip->type);
client->dev.type_data = client;
client->dev.platform_data = chip->platform_data;
client->dev.id = DEVICE_ID_DYNAMIC;
@@ -588,7 +588,7 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
}
adapter->dev.id = adapter->nr;
- strcpy(adapter->dev.name, "i2c");
+ dev_set_name(&adapter->dev, "i2c");
ret = register_device(&adapter->dev);
if (ret)
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index c6b4e02cb..c8d1d5e16 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1802,10 +1802,10 @@ int mci_register(struct mci_host *host)
mci->host = host;
if (host->devname) {
- strcpy(mci->dev.name, host->devname);
+ dev_set_name(&mci->dev, host->devname);
mci->dev.id = DEVICE_ID_SINGLE;
} else {
- strcpy(mci->dev.name, "mci");
+ dev_set_name(&mci->dev, "mci");
mci->dev.id = DEVICE_ID_DYNAMIC;
}
diff --git a/drivers/mfd/rave-sp.c b/drivers/mfd/rave-sp.c
index c61443218..40fce077c 100644
--- a/drivers/mfd/rave-sp.c
+++ b/drivers/mfd/rave-sp.c
@@ -789,7 +789,7 @@ static int rave_sp_add_params(struct rave_sp *sp)
int ret;
dev->parent = sp->serdev->dev;
- strcpy(dev->name, "sp");
+ dev_set_name(dev, "sp");
dev->id = DEVICE_ID_SINGLE;
ret = register_device(dev);
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 15fe9ce79..56e85b3d8 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -607,7 +607,7 @@ int add_mtd_device(struct mtd_info *mtd, const char *devname, int device_id)
if (!devname)
devname = "mtd";
- strcpy(mtd->class_dev.name, devname);
+ dev_set_name(&mtd->class_dev, devname);
mtd->class_dev.id = device_id;
if (mtd->parent)
mtd->class_dev.parent = mtd->parent;
diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
index 626966818..ed5377bd4 100644
--- a/drivers/mtd/spi-nor/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/cadence-quadspi.c
@@ -1051,7 +1051,7 @@ static int cqspi_setup_flash(struct device_d *dev,
if (np) {
nor->dev = xzalloc(sizeof(*nor->dev));
- strcpy(nor->dev->name, np->name);
+ dev_set_name(nor->dev, np->name);
nor->dev->device_node = np;
nor->dev->id = DEVICE_ID_SINGLE;
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 536077ebf..493c778c3 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -157,7 +157,7 @@ static int uif_init(struct ubi_device *ubi, int *ref)
*ref = 0;
sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
- sprintf(ubi->dev.name, "%s.ubi", ubi->mtd->cdev.name);
+ dev_set_name(&ubi->dev, "%s.ubi", ubi->mtd->cdev.name);
ubi->dev.id = DEVICE_ID_SINGLE;
ubi->dev.parent = &ubi->mtd->class_dev;
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 617704821..99da79171 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -145,7 +145,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
vol->last_eb_bytes = vol->usable_leb_size;
}
- sprintf(vol->dev.name, "%s.%s", dev_name(&ubi->dev), vol->name);
+ dev_set_name(&vol->dev, "%s.%s", dev_name(&ubi->dev), vol->name);
vol->dev.id = DEVICE_ID_SINGLE;
vol->dev.parent = &ubi->dev;
err = register_device(&vol->dev);
@@ -443,7 +443,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
dbg_gen("add volume");
- sprintf(vol->dev.name, "%s.%s", dev_name(&ubi->dev), vol->name);
+ dev_set_name(&vol->dev, "%s.%s", dev_name(&ubi->dev), vol->name);
vol->dev.id = DEVICE_ID_SINGLE;
vol->dev.parent = &ubi->dev;
err = register_device(&vol->dev);
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 3d3939cfa..c6fc21dc5 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -916,7 +916,7 @@ static int cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
if (ret)
goto err_out;
- sprintf(dev->name, "cpsw-slave");
+ dev_set_name(dev, "cpsw-slave");
dev->id = slave->slave_num;
dev->parent = priv->dev;
ret = register_device(dev);
diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c
index dda022e05..180b32ede 100644
--- a/drivers/net/e1000/eeprom.c
+++ b/drivers/net/e1000/eeprom.c
@@ -1529,7 +1529,7 @@ int e1000_register_invm(struct e1000_hw *hw)
if (ret < 0)
return ret;
- strcpy(hw->invm.dev.name, "invm");
+ dev_set_name(&hw->invm.dev, "invm");
hw->invm.dev.id = hw->dev->id;
hw->invm.dev.parent = hw->dev;
ret = register_device(&hw->invm.dev);
diff --git a/drivers/net/orion-gbe.c b/drivers/net/orion-gbe.c
index e6bd75768..431ec5c31 100644
--- a/drivers/net/orion-gbe.c
+++ b/drivers/net/orion-gbe.c
@@ -462,7 +462,7 @@ static int port_probe(struct device_d *parent, struct port_priv *port)
reg |= RGMII_ENABLE;
writel(reg, port->regs + PORT_SC1);
- snprintf(dev->name, MAX_DRIVER_NAME, "%08x.ethernet-port", (u32)gbe->regs);
+ dev_set_name(dev, "%08x.ethernet-port", (u32)gbe->regs);
dev->id = port->portno;
dev->parent = parent;
dev->device_node = port->np;
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 7d53bcc3d..177d54863 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -222,7 +222,7 @@ int mdiobus_register(struct mii_bus *bus)
bus->dev.priv = bus;
bus->dev.id = DEVICE_ID_DYNAMIC;
- strcpy(bus->dev.name, "miibus");
+ dev_set_name(&bus->dev, "miibus");
bus->dev.parent = bus->parent;
bus->dev.detect = mdiobus_detect;
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 42dcad906..19d458e07 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -176,12 +176,12 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id)
phydev->dev.bus = &mdio_bus_type;
if (bus) {
- sprintf(phydev->dev.name, "mdio%d-phy%02x",
- phydev->bus->dev.id,
- phydev->addr);
+ dev_set_name(&phydev->dev, "mdio%d-phy%02x",
+ phydev->bus->dev.id,
+ phydev->addr);
phydev->dev.id = DEVICE_ID_SINGLE;
} else {
- sprintf(phydev->dev.name, "fixed-phy");
+ dev_set_name(&phydev->dev, "fixed-phy");
phydev->dev.id = DEVICE_ID_DYNAMIC;
}
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index c0f61f453..63c0f997b 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -199,7 +199,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
nvmem->read_only = of_property_read_bool(np, "read-only") |
config->read_only;
- safe_strncpy(nvmem->dev.name, config->name, MAX_DRIVER_NAME);
+ dev_set_name(&nvmem->dev, config->name);
nvmem->dev.id = DEVICE_ID_DYNAMIC;
dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
diff --git a/drivers/nvmem/ocotp.c b/drivers/nvmem/ocotp.c
index c2d2982ee..0d07da280 100644
--- a/drivers/nvmem/ocotp.c
+++ b/drivers/nvmem/ocotp.c
@@ -531,7 +531,7 @@ static int imx_ocotp_probe(struct device_d *dev)
if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk);
- strcpy(priv->dev.name, "ocotp");
+ dev_set_name(&priv->dev, "ocotp");
priv->dev.parent = dev;
register_device(&priv->dev);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index c9157cdd7..4fd3ce2b7 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -68,12 +68,12 @@ static void of_device_make_bus_id(struct device_d *dev)
reg = of_get_property(np, "dcr-reg", NULL);
if (reg) {
#ifdef CONFIG_PPC_DCR_NATIVE
- snprintf(dev->name, MAX_DRIVER_NAME, "d%x.%s", *reg, name);
+ dev_set_name(dev, "d%x.%s", *reg, name);
#else /* CONFIG_PPC_DCR_NATIVE */
u64 addr = of_translate_dcr_address(np, *reg, NULL);
if (addr != OF_BAD_ADDR) {
- snprintf(dev->name, MAX_DRIVER_NAME, "D%llx.%s",
- (unsigned long long)addr, name);
+ dev_set_name(dev, "D%llx.%s",
+ (unsigned long long)addr, name);
free(name);
return;
}
@@ -96,8 +96,8 @@ static void of_device_make_bus_id(struct device_d *dev)
addr = OF_BAD_ADDR;
}
if (addr != OF_BAD_ADDR) {
- snprintf(dev->name, MAX_DRIVER_NAME, "%llx.%s",
- (unsigned long long)addr, name);
+ dev_set_name(dev, "%llx.%s",
+ (unsigned long long)addr, name);
free(name);
return;
}
@@ -106,7 +106,7 @@ static void of_device_make_bus_id(struct device_d *dev)
/*
* No BusID, use the node name and add a globally incremented counter
*/
- snprintf(dev->name, MAX_DRIVER_NAME, "%s.%d", name, bus_no_reg_magic++);
+ dev_set_name(dev, "%s.%d", name, bus_no_reg_magic++);
free(name);
}
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 201675b48..ac1562330 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -87,8 +87,7 @@ int pci_register_device(struct pci_dev *pdev)
struct device_d *dev = &pdev->dev;
int ret;
- snprintf(dev->name, MAX_DRIVER_NAME, "pci-%04x:%04x.",
- pdev->vendor, pdev->device);
+ dev_set_name(dev, "pci-%04x:%04x.", pdev->vendor, pdev->device);
dev->bus = &pci_bus;
dev->id = DEVICE_ID_DYNAMIC;
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 1b6a9f7b1..9d6288fc0 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -46,7 +46,7 @@ struct phy *phy_create(struct device_d *dev, struct device_node *node,
id = phy_ida++;
- snprintf(phy->dev.name, MAX_DRIVER_NAME, "phy");
+ dev_set_name(&phy->dev, "phy");
phy->dev.id = id;
phy->dev.parent = dev;
phy->dev.device_node = node ?: dev->device_node;
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 80fade061..c8016999f 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -89,7 +89,7 @@ int pwmchip_add(struct pwm_chip *chip, struct device_d *dev)
pwm->chip = chip;
pwm->hwdev = dev;
- strcpy(pwm->dev.name, chip->devname);
+ dev_set_name(&pwm->dev, chip->devname);
pwm->dev.id = DEVICE_ID_SINGLE;
pwm->dev.parent = dev;
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 8b047a638..5b58271c0 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -67,7 +67,7 @@ int rtc_register(struct rtc_device *rtcdev)
return -EINVAL;
dev->id = DEVICE_ID_DYNAMIC;
- strcpy(dev->name, "rtc");
+ dev_set_name(dev, "rtc");
if (rtcdev->dev)
dev->parent = rtcdev->dev;
platform_device_register(dev);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 5650098a0..25bb98879 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -76,7 +76,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
proxy->bits_per_word = chip->bits_per_word ? chip->bits_per_word : 8;
proxy->dev.platform_data = chip->platform_data;
proxy->dev.bus = &spi_bus;
- strcpy(proxy->dev.name, chip->name);
+ dev_set_name(&proxy->dev, chip->name);
/* allocate a free id for this chip */
proxy->dev.id = DEVICE_ID_DYNAMIC;
proxy->dev.type_data = proxy;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 70ded6ded..0ee8808a6 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -431,9 +431,10 @@ int usb_new_device(struct usb_device *dev)
dev->serial, sizeof(dev->serial));
if (parent) {
- sprintf(dev->dev.name, "%s-%d", parent->dev.name, dev->portnr - 1);
+ dev_set_name(&dev->dev, "%s-%d", parent->dev.name,
+ dev->portnr - 1);
} else {
- sprintf(dev->dev.name, "usb%d", dev->host->busnum);
+ dev_set_name(&dev->dev, "usb%d", dev->host->busnum);
}
dev->dev.id = DEVICE_ID_SINGLE;
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index ed99b53df..e35745609 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -179,7 +179,7 @@ int usb_add_gadget_udc_release(struct device_d *parent, struct usb_gadget *gadge
if (!udc)
goto err1;
- strcpy(gadget->dev.name, "usbgadget");
+ dev_set_name(&gadget->dev, "usbgadget");
gadget->dev.id = DEVICE_ID_SINGLE;
gadget->dev.parent = parent;
@@ -198,7 +198,7 @@ int usb_add_gadget_udc_release(struct device_d *parent, struct usb_gadget *gadge
dev_add_param_string(&gadget->dev, "productname", NULL, NULL,
&gadget->productname, NULL);
- strcpy(udc->dev.name, "udc");
+ dev_set_name(&udc->dev, "udc");
udc->dev.id = DEVICE_ID_DYNAMIC;
udc->gadget = gadget;
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 431b97ea9..5fe3bcb7c 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -333,7 +333,7 @@ static int dsps_register_otg_device(struct dsps_glue *glue)
{
int ret;
- strcpy(glue->otg_dev.name, "otg");
+ dev_set_name(&glue->otg_dev, "otg");
glue->otg_dev.id = DEVICE_ID_DYNAMIC,
glue->otg_dev.parent = glue->dev;
diff --git a/drivers/video/backlight.c b/drivers/video/backlight.c
index 30d52fcb6..3913d1c4c 100644
--- a/drivers/video/backlight.c
+++ b/drivers/video/backlight.c
@@ -71,7 +71,7 @@ int backlight_register(struct backlight_device *bl)
{
int ret;
- sprintf(bl->dev.name, "backlight");
+ dev_set_name(&bl->dev, "backlight");
bl->dev.id = DEVICE_ID_DYNAMIC;
ret = register_device(&bl->dev);
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index c9d184d50..72f33a6db 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -309,7 +309,7 @@ int register_framebuffer(struct fb_info *info)
dev->id = id;
dev->info = fb_info;
- sprintf(dev->name, "fb");
+ dev_set_name(dev, "fb");
ret = register_device(&info->dev);
if (ret)
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index ff573860e..694ffa853 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -423,7 +423,7 @@ static int w1_device_register(struct w1_bus *bus, struct w1_device *dev)
char str[18];
int ret;
- sprintf(dev->dev.name, "w1-%x-", dev->fid);
+ dev_set_name(&dev->dev, "w1-%x-", dev->fid);
dev->dev.id = DEVICE_ID_DYNAMIC;
dev->dev.bus = &w1_bustype;
dev->bus = bus;
@@ -619,7 +619,7 @@ int w1_bus_register(struct w1_bus *bus)
list_add_tail(&bus->list, &w1_buses);
- strcpy(bus->dev.name, "w1_bus");
+ dev_set_name(&bus->dev, "w1_bus");
bus->dev.id = DEVICE_ID_DYNAMIC;
bus->dev.parent = bus->parent;
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 56e8626cb..e6e5ddecd 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -104,7 +104,7 @@ static int watchdog_register_dev(struct watchdog *wd, const char *name, int id)
{
wd->dev.parent = wd->hwdev;
wd->dev.id = id;
- strncpy(wd->dev.name, name, MAX_DRIVER_NAME);
+ dev_set_name(&wd->dev, name);
return register_device(&wd->dev);
}
diff --git a/fs/fs.c b/fs/fs.c
index d76d82914..57eaaf585 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -2757,7 +2757,7 @@ int mount(const char *device, const char *fsname, const char *pathname,
fsdev = xzalloc(sizeof(struct fs_device_d));
fsdev->backingstore = xstrdup(device);
- safe_strncpy(fsdev->dev.name, fsname, MAX_DRIVER_NAME);
+ dev_set_name(&fsdev->dev, fsname);
fsdev->dev.id = get_free_deviceid(fsdev->dev.name);
fsdev->dev.bus = &fs_bus;
fsdev->options = xstrdup(fsoptions);
diff --git a/include/driver.h b/include/driver.h
index 1b61f2066..5a67757a2 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -23,7 +23,6 @@
#include <linux/ioport.h>
#include <of.h>
-#define MAX_DRIVER_NAME 32
#define FORMAT_DRIVER_NAME_ID "%s%d"
#include <param.h>
@@ -40,8 +39,12 @@ struct platform_device_id {
struct device_d {
/*! This member (and 'type' described below) is used to match with a
* driver. This is a descriptive name and could be MPC5XXX_ether or
- * imx_serial. */
- char name[MAX_DRIVER_NAME];
+ * imx_serial.
+ *
+ * NOTE: dev_set_name() can be used to assign device name using
+ * printf-like format strings
+ */
+ char *name;
/*! The id is used to uniquely identify a device in the system. The id
* will show up under /dev/ as the device's name. Usually this is
* something like eth0 or nor0. */
@@ -177,6 +180,8 @@ static inline const char *dev_name(const struct device_d *dev)
return dev_id(dev);
}
+int dev_set_name(struct device_d *dev, const char *fmt, ...);
+
/*
* get resource 'num' for a device
*/
diff --git a/net/eth.c b/net/eth.c
index 9dc441195..36260478d 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -363,7 +363,7 @@ int eth_register(struct eth_device *edev)
return -1;
}
- strcpy(edev->dev.name, "eth");
+ dev_set_name(&edev->dev, "eth");
if (edev->parent)
edev->dev.parent = edev->parent;
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 08/17] linux: string: Port kbasename()
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (6 preceding siblings ...)
2018-10-09 17:37 ` [PATCH v2 07/17] drivers: Introduce dev_set_name() Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-11 8:31 ` Sascha Hauer
2018-10-09 17:37 ` [PATCH v2 09/17] of: Port latest of_device_make_bus_id() implementation Andrey Smirnov
` (8 subsequent siblings)
16 siblings, 1 reply; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
include/linux/string.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/linux/string.h b/include/linux/string.h
index 3418b4fbe..c9823dab8 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -111,6 +111,18 @@ extern char *strim(char *);
void *memchr_inv(const void *start, int c, size_t bytes);
+/**
+ * kbasename - return the last part of a pathname.
+ *
+ * @path: path to extract the filename from.
+ */
+static inline const char *kbasename(const char *path)
+{
+ const char *tail = strrchr(path, '/');
+ return tail ? tail + 1 : path;
+}
+
+
#ifdef __cplusplus
}
#endif
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 09/17] of: Port latest of_device_make_bus_id() implementation
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (7 preceding siblings ...)
2018-10-09 17:37 ` [PATCH v2 08/17] linux: string: Port kbasename() Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-10 16:51 ` Lucas Stach
2018-10-09 17:37 ` [PATCH v2 10/17] mdio_bus: Fix documentation for mdio_bus_match() Andrey Smirnov
` (7 subsequent siblings)
16 siblings, 1 reply; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Code implementing of_device_make_bus_id() in Barebox uses rather old
implementation from Linux kernel and has a very significan limitation
in that it will produce identical names for different DT nodes that
happen to have the same node name as well as "reg" property.
One such example, that tirggered this change, is "switch@0" nodes that
can be found in dts/src/arm/vf610-zii-dev-rev-c.dts
This commit replaces original code with the current Linux kernel
implementation that traverses DT hierarchy from leaf node to its root
concatenating node names in the process.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/of/platform.c | 80 ++++++++++++-------------------------------
1 file changed, 22 insertions(+), 58 deletions(-)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 4fd3ce2b7..17052f419 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -43,71 +43,35 @@ EXPORT_SYMBOL(of_find_device_by_node);
* of_device_make_bus_id - Use the device node data to assign a unique name
* @dev: pointer to device structure that is linked to a device tree node
*
- * This routine will first try using either the dcr-reg or the reg property
- * value to derive a unique name. As a last resort it will use the node
- * name followed by a unique number.
+ * This routine will first try using the translated bus address to
+ * derive a unique name. If it cannot, then it will prepend names from
+ * parent nodes until a unique name can be derived.
*/
static void of_device_make_bus_id(struct device_d *dev)
{
- static int bus_no_reg_magic;
- struct device_node *np = dev->device_node;
- const __be32 *reg, *addrp;
+ struct device_node *node = dev->device_node;
+ const __be32 *reg;
u64 addr;
- char *name, *at;
-
- name = xstrdup(np->name);
- at = strchr(name, '@');
- if (at)
- *at = '\0';
-
-#ifdef CONFIG_PPC_DCR
- /*
- * If it's a DCR based device, use 'd' for native DCRs
- * and 'D' for MMIO DCRs.
- */
- reg = of_get_property(np, "dcr-reg", NULL);
- if (reg) {
-#ifdef CONFIG_PPC_DCR_NATIVE
- dev_set_name(dev, "d%x.%s", *reg, name);
-#else /* CONFIG_PPC_DCR_NATIVE */
- u64 addr = of_translate_dcr_address(np, *reg, NULL);
- if (addr != OF_BAD_ADDR) {
- dev_set_name(dev, "D%llx.%s",
- (unsigned long long)addr, name);
- free(name);
- return;
- }
-#endif /* !CONFIG_PPC_DCR_NATIVE */
- }
-#endif /* CONFIG_PPC_DCR */
-
- /*
- * For MMIO, get the physical address
- */
- reg = of_get_property(np, "reg", NULL);
- if (reg) {
- if (of_can_translate_address(np)) {
- addr = of_translate_address(np, reg);
- } else {
- addrp = of_get_address(np, 0, NULL, NULL);
- if (addrp)
- addr = of_read_number(addrp, 1);
- else
- addr = OF_BAD_ADDR;
- }
- if (addr != OF_BAD_ADDR) {
- dev_set_name(dev, "%llx.%s",
- (unsigned long long)addr, name);
- free(name);
+
+ /* Construct the name, using parent nodes if necessary to ensure uniqueness */
+ while (node->parent) {
+ /*
+ * If the address can be translated, then that is as much
+ * uniqueness as we need. Make it the first component and return
+ */
+ reg = of_get_property(node, "reg", NULL);
+ if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) {
+ dev_set_name(dev, dev->name ? "%llx.%s:%s" : "%llx.%s",
+ (unsigned long long)addr, node->name,
+ dev->name);
return;
}
- }
- /*
- * No BusID, use the node name and add a globally incremented counter
- */
- dev_set_name(dev, "%s.%d", name, bus_no_reg_magic++);
- free(name);
+ /* format arguments only used if dev_name() resolves to NULL */
+ dev_set_name(dev, dev->name ? "%s:%s" : "%s",
+ kbasename(node->full_name), dev->name);
+ node = node->parent;
+ }
}
/**
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 10/17] mdio_bus: Fix documentation for mdio_bus_match()
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (8 preceding siblings ...)
2018-10-09 17:37 ` [PATCH v2 09/17] of: Port latest of_device_make_bus_id() implementation Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 11/17] include: linux: phy: Add missing PHY_INTERFACE_* constants Andrey Smirnov
` (6 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Fix documentation for mdio_bus_match(), while at it re-arrange the
code to be easier to follow. Seeing != used as a result of a matching
function is extremely confusing.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/net/phy/mdio_bus.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 177d54863..d7d6d8940 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -335,16 +335,19 @@ EXPORT_SYMBOL(of_mdio_find_bus);
* @dev: target PHY device
* @drv: given PHY driver
*
- * Description: Given a PHY device, and a PHY driver, return 1 if
- * the driver supports the device. Otherwise, return 0.
+ * Description: Given a PHY device, and a PHY driver, return 0 if
+ * the driver supports the device. Otherwise, return 1.
*/
static int mdio_bus_match(struct device_d *dev, struct driver_d *drv)
{
struct phy_device *phydev = to_phy_device(dev);
struct phy_driver *phydrv = to_phy_driver(drv);
- return ((phydrv->phy_id & phydrv->phy_id_mask) !=
- (phydev->phy_id & phydrv->phy_id_mask));
+ if ((phydrv->phy_id & phydrv->phy_id_mask) ==
+ (phydev->phy_id & phydrv->phy_id_mask))
+ return 0;
+
+ return 1;
}
static ssize_t phydev_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 11/17] include: linux: phy: Add missing PHY_INTERFACE_* constants
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (9 preceding siblings ...)
2018-10-09 17:37 ` [PATCH v2 10/17] mdio_bus: Fix documentation for mdio_bus_match() Andrey Smirnov
@ 2018-10-09 17:37 ` Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 12/17] include: linux: ethtool: Add missing *_UNKNOWN constants Andrey Smirnov
` (5 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:37 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
include/linux/phy.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index ac750f5c3..5b2c63ff6 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -54,7 +54,16 @@ typedef enum {
PHY_INTERFACE_MODE_RGMII_TXID,
PHY_INTERFACE_MODE_RTBI,
PHY_INTERFACE_MODE_SMII,
+ PHY_INTERFACE_MODE_XGMII,
PHY_INTERFACE_MODE_QSGMII,
+ PHY_INTERFACE_MODE_TRGMII,
+ PHY_INTERFACE_MODE_1000BASEX,
+ PHY_INTERFACE_MODE_2500BASEX,
+ PHY_INTERFACE_MODE_RXAUI,
+ PHY_INTERFACE_MODE_XAUI,
+ /* 10GBASE-KR, XFI, SFI - single lane 10G Serdes */
+ PHY_INTERFACE_MODE_10GKR,
+ PHY_INTERFACE_MODE_MAX,
} phy_interface_t;
#define PHY_INIT_TIMEOUT 100000
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 12/17] include: linux: ethtool: Add missing *_UNKNOWN constants
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (10 preceding siblings ...)
2018-10-09 17:37 ` [PATCH v2 11/17] include: linux: phy: Add missing PHY_INTERFACE_* constants Andrey Smirnov
@ 2018-10-09 17:38 ` Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 13/17] net: phy: Check phy_mask in get_phy_device() Andrey Smirnov
` (4 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:38 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
include/linux/ethtool.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 4d83fe019..324e40cde 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -72,9 +72,12 @@
#define SPEED_2500 2500
#define SPEED_10000 10000
+#define SPEED_UNKNOWN -1
+
/* Duplex, half or full. */
#define DUPLEX_HALF 0x00
#define DUPLEX_FULL 0x01
+#define DUPLEX_UNKNOWN 0xff
/* Which connector port. */
#define PORT_TP 0x00
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 13/17] net: phy: Check phy_mask in get_phy_device()
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (11 preceding siblings ...)
2018-10-09 17:38 ` [PATCH v2 12/17] include: linux: ethtool: Add missing *_UNKNOWN constants Andrey Smirnov
@ 2018-10-09 17:38 ` Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 14/17] mdio_bus: Allow for non PHY-devices on MDIO buses Andrey Smirnov
` (3 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:38 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Do not try to probe PHY devices if they are masked via phy_mask of the
corresponding bus. This way we won't try adding devices that are
unlikely to be proper PHYs by default. With this change it is still
remain to be possible to add such a device to the bus explicitly
either using "miitool" or calling phy_device_create() explicilty.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/net/phy/phy.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 19d458e07..b985b7567 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -234,6 +234,10 @@ struct phy_device *get_phy_device(struct mii_bus *bus, int addr)
u32 phy_id = 0;
int r;
+ /* skip masked out PHY addresses */
+ if (bus->phy_mask & BIT(addr))
+ return ERR_PTR(-ENODEV);
+
r = get_phy_id(bus, addr, &phy_id);
if (r)
return ERR_PTR(r);
@@ -440,9 +444,6 @@ int phy_device_connect(struct eth_device *edev, struct mii_bus *bus, int addr,
}
for (i = 0; i < PHY_MAX_ADDR && !edev->phydev; i++) {
- /* skip masked out PHY addresses */
- if (bus->phy_mask & (1 << i))
- continue;
phy = mdiobus_scan(bus, i);
if (IS_ERR(phy))
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 14/17] mdio_bus: Allow for non PHY-devices on MDIO buses
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (12 preceding siblings ...)
2018-10-09 17:38 ` [PATCH v2 13/17] net: phy: Check phy_mask in get_phy_device() Andrey Smirnov
@ 2018-10-09 17:38 ` Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 15/17] net: phy: Add basic driver for MV88E6XXX switches from Marvell Andrey Smirnov
` (2 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:38 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Instead of just creating a simple PHY device for every child of MDIO
bus node, add code to check if any of them have "compatible" property
set as well as code to create a proper platform device for such cases.
This change is useful for when MDIO bus and some of Ethernet ports are
connected to a switch or some other MDIO device that doesn't behave
like a generic PHY and can't be probed via its PHY ID.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/net/phy/mdio_bus.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index d7d6d8940..cda05afae 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -26,6 +26,7 @@
#include <errno.h>
#include <linux/phy.h>
#include <linux/err.h>
+#include <of_device.h>
#define DEFAULT_GPIO_RESET_ASSERT 1000 /* us */
#define DEFAULT_GPIO_RESET_DEASSERT 1000 /* us */
@@ -179,8 +180,19 @@ static int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
/* Loop over the child nodes and register a phy_device for each one */
for_each_available_child_of_node(np, child) {
- if (!of_mdiobus_child_is_phy(child))
+ if (!of_mdiobus_child_is_phy(child)) {
+ if (of_get_property(child, "compatible", NULL)) {
+ if (!of_platform_device_create(child,
+ &mdio->dev)) {
+ dev_err(&mdio->dev,
+ "Failed to create device "
+ "for %s\n",
+ child->full_name);
+ }
+ }
+
continue;
+ }
ret = of_property_read_u32(child, "reg", &addr);
if (ret) {
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 15/17] net: phy: Add basic driver for MV88E6XXX switches from Marvell
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (13 preceding siblings ...)
2018-10-09 17:38 ` [PATCH v2 14/17] mdio_bus: Allow for non PHY-devices on MDIO buses Andrey Smirnov
@ 2018-10-09 17:38 ` Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 16/17] net: phy: mv88e6xxx: Port EEPROM support code Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 17/17] net: phy: mv88e6xxx: Add support for MAC ports Andrey Smirnov
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:38 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port a very abridged version of MV88E6XXX DSA driver from Linux
kernel. Currently only internal MDIO bus connected to switch PHYs is
exposed.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
net: phy: mv88e6xxx: Expose internal MDIO bus
---
drivers/net/phy/Kconfig | 6 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/mv88e6xxx/Makefile | 5 +
drivers/net/phy/mv88e6xxx/chip.c | 724 ++++++++++++++++++++++++++++
drivers/net/phy/mv88e6xxx/chip.h | 61 +++
drivers/net/phy/mv88e6xxx/global2.c | 124 +++++
drivers/net/phy/mv88e6xxx/global2.h | 41 ++
drivers/net/phy/mv88e6xxx/port.c | 20 +
drivers/net/phy/mv88e6xxx/port.h | 89 ++++
9 files changed, 1071 insertions(+)
create mode 100644 drivers/net/phy/mv88e6xxx/Makefile
create mode 100644 drivers/net/phy/mv88e6xxx/chip.c
create mode 100644 drivers/net/phy/mv88e6xxx/chip.h
create mode 100644 drivers/net/phy/mv88e6xxx/global2.c
create mode 100644 drivers/net/phy/mv88e6xxx/global2.h
create mode 100644 drivers/net/phy/mv88e6xxx/port.c
create mode 100644 drivers/net/phy/mv88e6xxx/port.h
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 79fb917ee..3b1a6ea7e 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -48,6 +48,12 @@ config SMSC_PHY
---help---
Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs
+config NET_DSA_MV88E6XXX
+ tristate "Marvell 88E6xxx Ethernet switch fabric support"
+ help
+ This driver adds support for most of the Marvell 88E6xxx models of
+ Ethernet switch chips, except 88E6060.
+
comment "MII bus device drivers"
config MDIO_MVEBU
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 4424054d9..e4d9ec65a 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o
obj-$(CONFIG_MICREL_PHY) += micrel.o
obj-$(CONFIG_NATIONAL_PHY) += national.o
obj-$(CONFIG_SMSC_PHY) += smsc.o
+obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx/
obj-$(CONFIG_MDIO_MVEBU) += mdio-mvebu.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
diff --git a/drivers/net/phy/mv88e6xxx/Makefile b/drivers/net/phy/mv88e6xxx/Makefile
new file mode 100644
index 000000000..8c8ba78cd
--- /dev/null
+++ b/drivers/net/phy/mv88e6xxx/Makefile
@@ -0,0 +1,5 @@
+obj-y += mv88e6xxx.o
+
+mv88e6xxx-objs := chip.o
+mv88e6xxx-objs += global2.o
+mv88e6xxx-objs += port.o
\ No newline at end of file
diff --git a/drivers/net/phy/mv88e6xxx/chip.c b/drivers/net/phy/mv88e6xxx/chip.c
new file mode 100644
index 000000000..cde60f43c
--- /dev/null
+++ b/drivers/net/phy/mv88e6xxx/chip.c
@@ -0,0 +1,724 @@
+#include <common.h>
+#include <init.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+#include <linux/bitfield.h>
+
+#include <gpio.h>
+#include <of_device.h>
+#include <of_gpio.h>
+
+#include "chip.h"
+#include "global2.h"
+#include "port.h"
+
+/* #define MV88E6XXX_SWITCH_GLOBAL_REGS_3 0x1d */
+
+/* List of supported models */
+enum mv88e6xxx_model {
+ MV88E6085,
+ MV88E6095,
+ MV88E6097,
+ MV88E6123,
+ MV88E6131,
+ MV88E6141,
+ MV88E6161,
+ MV88E6165,
+ MV88E6171,
+ MV88E6172,
+ MV88E6175,
+ MV88E6176,
+ MV88E6185,
+ MV88E6190,
+ MV88E6190X,
+ MV88E6191,
+ MV88E6240,
+ MV88E6290,
+ MV88E6320,
+ MV88E6321,
+ MV88E6341,
+ MV88E6350,
+ MV88E6351,
+ MV88E6352,
+ MV88E6390,
+ MV88E6390X,
+};
+
+static const struct mv88e6xxx_ops mv88e6085_ops = {
+ /* MV88E6XXX_FAMILY_6097 */
+ /* FIXME: Was not ported due to lack of HW */
+ .phy_read = NULL,
+ .phy_write = NULL,
+};
+
+static const struct mv88e6xxx_ops mv88e6095_ops = {
+ /* MV88E6XXX_FAMILY_6095 */
+ /* FIXME: Was not ported due to lack of HW */
+ .phy_read = NULL,
+ .phy_write = NULL,
+};
+
+static const struct mv88e6xxx_ops mv88e6097_ops = {
+ /* MV88E6XXX_FAMILY_6097 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6123_ops = {
+ /* MV88E6XXX_FAMILY_6165 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6131_ops = {
+ /* MV88E6XXX_FAMILY_6185 */
+ /* FIXME: Was not ported due to lack of HW */
+ .phy_read = NULL,
+ .phy_write = NULL,
+};
+
+static const struct mv88e6xxx_ops mv88e6141_ops = {
+ /* MV88E6XXX_FAMILY_6341 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6161_ops = {
+ /* MV88E6XXX_FAMILY_6165 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6165_ops = {
+ /* MV88E6XXX_FAMILY_6165 */
+ /* FIXME: Was not ported due to lack of HW */
+ .phy_read = NULL,
+ .phy_write = NULL,
+};
+
+static const struct mv88e6xxx_ops mv88e6171_ops = {
+ /* MV88E6XXX_FAMILY_6351 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6172_ops = {
+ /* MV88E6XXX_FAMILY_6352 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6175_ops = {
+ /* MV88E6XXX_FAMILY_6351 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6176_ops = {
+ /* MV88E6XXX_FAMILY_6352 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6185_ops = {
+ /* MV88E6XXX_FAMILY_6185 */
+ /* FIXME: Was not ported due to lack of HW */
+ .phy_read = NULL,
+ .phy_write = NULL,
+};
+
+static const struct mv88e6xxx_ops mv88e6190_ops = {
+ /* MV88E6XXX_FAMILY_6390 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6190x_ops = {
+ /* MV88E6XXX_FAMILY_6390 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6191_ops = {
+ /* MV88E6XXX_FAMILY_6390 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6240_ops = {
+ /* MV88E6XXX_FAMILY_6352 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6290_ops = {
+ /* MV88E6XXX_FAMILY_6390 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6320_ops = {
+ /* MV88E6XXX_FAMILY_6320 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6321_ops = {
+ /* MV88E6XXX_FAMILY_6320 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6341_ops = {
+ /* MV88E6XXX_FAMILY_6341 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6350_ops = {
+ /* MV88E6XXX_FAMILY_6351 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6351_ops = {
+ /* MV88E6XXX_FAMILY_6351 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6352_ops = {
+ /* MV88E6XXX_FAMILY_6352 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6390_ops = {
+ /* MV88E6XXX_FAMILY_6390 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_ops mv88e6390x_ops = {
+ /* MV88E6XXX_FAMILY_6390 */
+ .phy_read = mv88e6xxx_g2_smi_phy_read,
+ .phy_write = mv88e6xxx_g2_smi_phy_write,
+};
+
+static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+ [MV88E6085] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
+ .family = MV88E6XXX_FAMILY_6097,
+ .name = "Marvell 88E6085",
+ .num_ports = 10,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6085_ops,
+ },
+
+ [MV88E6095] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6095,
+ .family = MV88E6XXX_FAMILY_6095,
+ .name = "Marvell 88E6095/88E6095F",
+ .num_ports = 11,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6095_ops,
+ },
+
+ [MV88E6097] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6097,
+ .family = MV88E6XXX_FAMILY_6097,
+ .name = "Marvell 88E6097/88E6097F",
+ .num_ports = 11,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6097_ops,
+ },
+
+ [MV88E6123] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6123,
+ .family = MV88E6XXX_FAMILY_6165,
+ .name = "Marvell 88E6123",
+ .num_ports = 3,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6123_ops,
+ },
+
+ [MV88E6131] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6131,
+ .family = MV88E6XXX_FAMILY_6185,
+ .name = "Marvell 88E6131",
+ .num_ports = 8,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6131_ops,
+ },
+
+ [MV88E6141] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
+ .family = MV88E6XXX_FAMILY_6341,
+ .name = "Marvell 88E6341",
+ .num_ports = 6,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6141_ops,
+ },
+
+ [MV88E6161] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6161,
+ .family = MV88E6XXX_FAMILY_6165,
+ .name = "Marvell 88E6161",
+ .num_ports = 6,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6161_ops,
+ },
+
+ [MV88E6165] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6165,
+ .family = MV88E6XXX_FAMILY_6165,
+ .name = "Marvell 88E6165",
+ .num_ports = 6,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6165_ops,
+ },
+
+ [MV88E6171] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6171,
+ .family = MV88E6XXX_FAMILY_6351,
+ .name = "Marvell 88E6171",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6171_ops,
+ },
+
+ [MV88E6172] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6172,
+ .family = MV88E6XXX_FAMILY_6352,
+ .name = "Marvell 88E6172",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6172_ops,
+ },
+
+ [MV88E6175] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6175,
+ .family = MV88E6XXX_FAMILY_6351,
+ .name = "Marvell 88E6175",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6175_ops,
+ },
+
+ [MV88E6176] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6176,
+ .family = MV88E6XXX_FAMILY_6352,
+ .name = "Marvell 88E6176",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6176_ops,
+ },
+
+ [MV88E6185] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6185,
+ .family = MV88E6XXX_FAMILY_6185,
+ .name = "Marvell 88E6185",
+ .num_ports = 10,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6185_ops,
+ },
+
+ [MV88E6190] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190,
+ .family = MV88E6XXX_FAMILY_6390,
+ .name = "Marvell 88E6190",
+ .num_ports = 11, /* 10 + Z80 */
+ .port_base_addr = 0x0,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6190_ops,
+ },
+
+ [MV88E6190X] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190X,
+ .family = MV88E6XXX_FAMILY_6390,
+ .name = "Marvell 88E6190X",
+ .num_ports = 11, /* 10 + Z80 */
+ .port_base_addr = 0x0,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6190x_ops,
+ },
+
+ [MV88E6191] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191,
+ .family = MV88E6XXX_FAMILY_6390,
+ .name = "Marvell 88E6191",
+ .num_ports = 11, /* 10 + Z80 */
+ .port_base_addr = 0x0,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6191_ops,
+ },
+
+ [MV88E6240] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
+ .family = MV88E6XXX_FAMILY_6352,
+ .name = "Marvell 88E6240",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6240_ops,
+ },
+
+ [MV88E6290] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290,
+ .family = MV88E6XXX_FAMILY_6390,
+ .name = "Marvell 88E6290",
+ .num_ports = 11, /* 10 + Z80 */
+ .port_base_addr = 0x0,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6290_ops,
+ },
+
+ [MV88E6320] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6320,
+ .family = MV88E6XXX_FAMILY_6320,
+ .name = "Marvell 88E6320",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6320_ops,
+ },
+
+ [MV88E6321] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6321,
+ .family = MV88E6XXX_FAMILY_6320,
+ .name = "Marvell 88E6321",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6321_ops,
+ },
+
+ [MV88E6341] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
+ .family = MV88E6XXX_FAMILY_6341,
+ .name = "Marvell 88E6341",
+ .num_ports = 6,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6341_ops,
+ },
+
+ [MV88E6350] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6350,
+ .family = MV88E6XXX_FAMILY_6351,
+ .name = "Marvell 88E6350",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6350_ops,
+ },
+
+ [MV88E6351] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6351,
+ .family = MV88E6XXX_FAMILY_6351,
+ .name = "Marvell 88E6351",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6351_ops,
+ },
+
+ [MV88E6352] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6352,
+ .family = MV88E6XXX_FAMILY_6352,
+ .name = "Marvell 88E6352",
+ .num_ports = 7,
+ .port_base_addr = 0x10,
+ .ops = &mv88e6352_ops,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6352_ops,
+ },
+
+ [MV88E6390] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
+ .family = MV88E6XXX_FAMILY_6390,
+ .name = "Marvell 88E6390",
+ .num_ports = 11, /* 10 + Z80 */
+ .port_base_addr = 0x0,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6390_ops,
+ },
+
+ [MV88E6390X] = {
+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390X,
+ .family = MV88E6XXX_FAMILY_6390,
+ .name = "Marvell 88E6390X",
+ .num_ports = 11, /* 10 + Z80 */
+ .port_base_addr = 0x0,
+ .global2_addr = 0x1c,
+ .ops = &mv88e6390x_ops,
+ },
+};
+
+int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
+{
+ int ret;
+ ret = mdiobus_write(chip->parent_miibus, addr, reg, val);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
+ addr, reg, val);
+
+ return 0;
+}
+
+int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
+{
+ int ret;
+
+ ret = mdiobus_read(chip->parent_miibus, addr, reg);
+ if (ret < 0)
+ return ret;
+
+ *val = ret & 0xffff;
+
+ dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
+ addr, reg, *val);
+
+ return 0;
+}
+
+int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
+{
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ u16 val;
+ int err;
+
+ err = mv88e6xxx_read(chip, addr, reg, &val);
+ if (err)
+ return err;
+
+ if (!(val & mask))
+ return 0;
+
+ udelay(2000);
+ }
+
+ dev_err(chip->dev, "Timeout while waiting for switch\n");
+ return -ETIMEDOUT;
+}
+
+static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
+{
+ struct mv88e6xxx_chip *chip = bus->priv;
+ u16 val;
+ int err;
+
+ if (!chip->info->ops->phy_read)
+ return -EOPNOTSUPP;
+
+ err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
+
+ if (reg == MII_PHYSID2) {
+ /* Some internal PHYS don't have a model number. Use
+ * the mv88e6390 family model number instead.
+ */
+ if (!(val & 0x3f0))
+ val |= MV88E6XXX_PORT_SWITCH_ID_PROD_6390 >> 4;
+ }
+
+ return err ?: val;
+}
+
+static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+ struct mv88e6xxx_chip *chip = bus->priv;
+ int err;
+
+ if (!chip->info->ops->phy_write)
+ return -EOPNOTSUPP;
+
+ err = chip->info->ops->phy_write(chip, bus, phy, reg, val);
+
+ return err;
+}
+
+static const struct mv88e6xxx_info *
+mv88e6xxx_lookup_info(unsigned int prod_num)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
+ if (mv88e6xxx_table[i].prod_num == prod_num)
+ return &mv88e6xxx_table[i];
+
+ return NULL;
+}
+
+static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
+{
+ const struct mv88e6xxx_info *info;
+ unsigned int prod_num, rev;
+ u16 id;
+ int err;
+
+ err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id);
+ if (err)
+ return err;
+
+ prod_num = id & MV88E6XXX_PORT_SWITCH_ID_PROD_MASK;
+ rev = id & MV88E6XXX_PORT_SWITCH_ID_REV_MASK;
+
+ info = mv88e6xxx_lookup_info(prod_num);
+ if (!info)
+ return -ENODEV;
+
+ /* Update the compatible info with the probed one */
+ chip->info = info;
+
+ dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
+ chip->info->prod_num, chip->info->name, rev);
+
+ return 0;
+}
+
+/*
+ * Linux driver has this delay at 20ms, but it doesn't seem to be
+ * enough in Barebox and trying to access switch registers immediately
+ * after this function will return all F's on some platforms
+ * tested. Increasing this to 50ms seem to resolve the issue.
+ */
+static void mv88e6xxx_hardware_reset_delay(void)
+{
+ udelay(50000);
+}
+
+static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
+{
+ /* If there is a GPIO connected to the reset pin, toggle it */
+ if (gpio_is_valid(chip->reset)) {
+ gpio_set_active(chip->reset, 1);
+ mv88e6xxx_hardware_reset_delay();
+ gpio_set_active(chip->reset, 0);
+ mv88e6xxx_hardware_reset_delay();
+ }
+}
+
+static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
+{
+ mv88e6xxx_hardware_reset(chip);
+ return 0;
+}
+
+static int mv88e6xxx_probe(struct device_d *dev)
+{
+ struct device_node *np = dev->device_node;
+ struct device_node *mdio_node;
+ struct mv88e6xxx_chip *chip;
+ enum of_gpio_flags of_flags;
+ int err;
+ u32 reg;
+
+ err = of_property_read_u32(np, "reg", ®);
+ if (err) {
+ dev_err(dev, "Couldn't determine switch MIDO address\n");
+ return err;
+ }
+
+ if (reg) {
+ dev_err(dev, "Only single-chip address mode is supported\n");
+ return -ENOTSUPP;
+ }
+
+ chip = xzalloc(sizeof(struct mv88e6xxx_chip));
+ chip->dev = dev;
+ chip->info = of_device_get_match_data(dev);
+
+ chip->parent_miibus = of_mdio_find_bus(np->parent);
+ if (!chip->parent_miibus)
+ return -EPROBE_DEFER;
+
+ chip->reset = of_get_named_gpio_flags(np, "reset-gpios", 0, &of_flags);
+ if (gpio_is_valid(chip->reset)) {
+ unsigned long flags = GPIOF_OUT_INIT_INACTIVE;
+ char *name;
+
+ if (of_flags & OF_GPIO_ACTIVE_LOW)
+ flags |= GPIOF_ACTIVE_LOW;
+
+ name = basprintf("%s reset", dev_name(dev));
+ err = gpio_request_one(chip->reset, flags, name);
+ if (err < 0)
+ return err;
+ /*
+ * We assume that reset line was previously held low
+ * and give the switch time to initialize before
+ * trying to read its registers
+ */
+ mv88e6xxx_hardware_reset_delay();
+ }
+
+ err = mv88e6xxx_detect(chip);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_switch_reset(chip);
+ if (err)
+ return err;
+ /*
+ * In single-chip address mode addresses 0x10 - 0x1f are
+ * reserved to access various switch registers and do not
+ * correspond to any PHYs, so we mask them to pervent from
+ * being exposed as phy devices
+ */
+ chip->parent_miibus->phy_mask |= GENMASK(0x1f, 0x10);
+ /*
+ * Address 0x0f on internal bus is dedicated to SERDES
+ * registers and won't be very useful against standard PHY
+ * driver
+ */
+ chip->miibus.phy_mask |= GENMASK(0x1f, 0x0f);
+
+ chip->miibus.read = mv88e6xxx_mdio_read;
+ chip->miibus.write = mv88e6xxx_mdio_write;
+
+ chip->miibus.priv = chip;
+ chip->miibus.parent = dev;
+
+ mdio_node = of_get_child_by_name(np, "mdio");
+ if (mdio_node)
+ chip->miibus.dev.device_node = mdio_node;
+
+ return mdiobus_register(&chip->miibus);
+}
+
+static const struct of_device_id mv88e6xxx_of_match[] = {
+ {
+ .compatible = "marvell,mv88e6085",
+ .data = &mv88e6xxx_table[MV88E6085],
+ },
+ {
+ .compatible = "marvell,mv88e6190",
+ .data = &mv88e6xxx_table[MV88E6190],
+ },
+ {},
+};
+
+static struct driver_d mv88e6xxx_driver = {
+ .name = "mv88e6085",
+ .probe = mv88e6xxx_probe,
+ .of_compatible = mv88e6xxx_of_match,
+};
+device_platform_driver(mv88e6xxx_driver);
diff --git a/drivers/net/phy/mv88e6xxx/chip.h b/drivers/net/phy/mv88e6xxx/chip.h
new file mode 100644
index 000000000..4df18a241
--- /dev/null
+++ b/drivers/net/phy/mv88e6xxx/chip.h
@@ -0,0 +1,61 @@
+#ifndef _MV88E6XXX_CHIP_H
+#define _MV88E6XXX_CHIP_H
+
+#include <common.h>
+#include <init.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+/* sub-devices MDIO addresses */
+#define MV88E6XXX_SWITCH_GLOBAL_REGS_1 0x1b
+#define MV88E6XXX_SWITCH_GLOBAL_REGS_2 0x1c
+
+enum mv88e6xxx_family {
+ MV88E6XXX_FAMILY_NONE,
+ MV88E6XXX_FAMILY_6065, /* 6031 6035 6061 6065 */
+ MV88E6XXX_FAMILY_6095, /* 6092 6095 */
+ MV88E6XXX_FAMILY_6097, /* 6046 6085 6096 6097 */
+ MV88E6XXX_FAMILY_6165, /* 6123 6161 6165 */
+ MV88E6XXX_FAMILY_6185, /* 6108 6121 6122 6131 6152 6155 6182 6185 */
+ MV88E6XXX_FAMILY_6320, /* 6320 6321 */
+ MV88E6XXX_FAMILY_6341, /* 6141 6341 */
+ MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */
+ MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */
+ MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */
+};
+
+struct mv88e6xxx_ops;
+
+struct mv88e6xxx_info {
+ enum mv88e6xxx_family family;
+ u16 prod_num;
+ const char *name;
+ unsigned int num_ports;
+ unsigned int port_base_addr;
+ unsigned int global2_addr;
+
+ const struct mv88e6xxx_ops *ops;
+};
+
+struct mv88e6xxx_chip {
+ const struct mv88e6xxx_info *info;
+ struct mii_bus *parent_miibus;
+ struct mii_bus miibus;
+ struct device_d *dev;
+ int reset;
+};
+
+struct mv88e6xxx_ops {
+ int (*phy_read)(struct mv88e6xxx_chip *chip,
+ struct mii_bus *bus,
+ int addr, int reg, u16 *val);
+ int (*phy_write)(struct mv88e6xxx_chip *chip,
+ struct mii_bus *bus,
+ int addr, int reg, u16 val);
+};
+
+int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
+int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
+int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask);
+
+#endif /* _MV88E6XXX_CHIP_H */
\ No newline at end of file
diff --git a/drivers/net/phy/mv88e6xxx/global2.c b/drivers/net/phy/mv88e6xxx/global2.c
new file mode 100644
index 000000000..fc78049aa
--- /dev/null
+++ b/drivers/net/phy/mv88e6xxx/global2.c
@@ -0,0 +1,124 @@
+#include <linux/ethtool.h>
+#include <linux/bitfield.h>
+
+#include "global2.h"
+
+int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
+{
+ return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val);
+}
+
+int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
+{
+ return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
+}
+
+int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
+{
+ return mv88e6xxx_wait(chip, chip->info->global2_addr, reg, mask);
+}
+
+static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
+{
+ return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_SMI_PHY_CMD,
+ MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
+}
+
+static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
+{
+ int err;
+
+ err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_CMD,
+ MV88E6XXX_G2_SMI_PHY_CMD_BUSY | cmd);
+ if (err)
+ return err;
+
+ return mv88e6xxx_g2_smi_phy_wait(chip);
+}
+
+static int mv88e6xxx_g2_smi_phy_access(struct mv88e6xxx_chip *chip,
+ bool external, bool c45, u16 op, int dev,
+ int reg)
+{
+ u16 cmd = op;
+
+ if (external)
+ cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL;
+ else
+ cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL; /* empty mask */
+
+ if (c45)
+ cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45; /* empty mask */
+ else
+ cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_22;
+
+ dev <<= __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK);
+ cmd |= dev & MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK;
+ cmd |= reg & MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK;
+
+ return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
+}
+
+static int mv88e6xxx_g2_smi_phy_access_c22(struct mv88e6xxx_chip *chip,
+ bool external, u16 op, int dev,
+ int reg)
+{
+ return mv88e6xxx_g2_smi_phy_access(chip, external, false, op, dev, reg);
+}
+
+/* IEEE 802.3 Clause 22 Read Data Register */
+static int mv88e6xxx_g2_smi_phy_read_data_c22(struct mv88e6xxx_chip *chip,
+ bool external, int dev, int reg,
+ u16 *data)
+{
+ u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA;
+ int err;
+
+ err = mv88e6xxx_g2_smi_phy_wait(chip);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
+ if (err)
+ return err;
+
+ return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
+}
+
+/* IEEE 802.3 Clause 22 Write Data Register */
+static int mv88e6xxx_g2_smi_phy_write_data_c22(struct mv88e6xxx_chip *chip,
+ bool external, int dev, int reg,
+ u16 data)
+{
+ u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA;
+ int err;
+
+ err = mv88e6xxx_g2_smi_phy_wait(chip);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
+ if (err)
+ return err;
+
+ return mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
+}
+
+
+int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
+ int addr, int reg, u16 *val)
+{
+ bool external = false;
+
+ return mv88e6xxx_g2_smi_phy_read_data_c22(chip, external, addr, reg,
+ val);
+}
+
+int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
+ int addr, int reg, u16 val)
+{
+ bool external = false;
+
+ return mv88e6xxx_g2_smi_phy_write_data_c22(chip, external, addr, reg,
+ val);
+}
diff --git a/drivers/net/phy/mv88e6xxx/global2.h b/drivers/net/phy/mv88e6xxx/global2.h
new file mode 100644
index 000000000..28bbd8c43
--- /dev/null
+++ b/drivers/net/phy/mv88e6xxx/global2.h
@@ -0,0 +1,41 @@
+#ifndef _MV88E6XXX_GLOBAL2_H
+#define _MV88E6XXX_GLOBAL2_H
+
+#include "chip.h"
+
+/* Offset 0x18: SMI PHY Command Register */
+#define MV88E6XXX_G2_SMI_PHY_CMD 0x18
+#define MV88E6XXX_G2_SMI_PHY_CMD_BUSY 0x8000
+#define MV88E6390_G2_SMI_PHY_CMD_FUNC_MASK 0x6000
+#define MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL 0x0000
+#define MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL 0x2000
+#define MV88E6390_G2_SMI_PHY_CMD_FUNC_SETUP 0x4000
+#define MV88E6XXX_G2_SMI_PHY_CMD_MODE_MASK 0x1000
+#define MV88E6XXX_G2_SMI_PHY_CMD_MODE_45 0x0000
+#define MV88E6XXX_G2_SMI_PHY_CMD_MODE_22 0x1000
+#define MV88E6XXX_G2_SMI_PHY_CMD_OP_MASK 0x0c00
+#define MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA 0x0400
+#define MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA 0x0800
+#define MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_ADDR 0x0000
+#define MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_DATA 0x0400
+#define MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA_INC 0x0800
+#define MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA 0x0c00
+#define MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK 0x03e0
+#define MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK 0x001f
+#define MV88E6XXX_G2_SMI_PHY_CMD_SETUP_PTR_MASK 0x03ff
+
+/* Offset 0x19: SMI PHY Data Register */
+#define MV88E6XXX_G2_SMI_PHY_DATA 0x19
+
+int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val);
+int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val);
+int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask);
+
+int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip,
+ struct mii_bus *bus,
+ int addr, int reg, u16 *val);
+int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip,
+ struct mii_bus *bus,
+ int addr, int reg, u16 val);
+
+#endif /* _MV88E6XXX_GLOBAL2_H */
\ No newline at end of file
diff --git a/drivers/net/phy/mv88e6xxx/port.c b/drivers/net/phy/mv88e6xxx/port.c
new file mode 100644
index 000000000..59afdbd97
--- /dev/null
+++ b/drivers/net/phy/mv88e6xxx/port.c
@@ -0,0 +1,20 @@
+#include <common.h>
+#include <init.h>
+
+#include "port.h"
+
+int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
+ u16 *val)
+{
+ int addr = chip->info->port_base_addr + port;
+
+ return mv88e6xxx_read(chip, addr, reg, val);
+}
+
+int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
+ u16 val)
+{
+ int addr = chip->info->port_base_addr + port;
+
+ return mv88e6xxx_write(chip, addr, reg, val);
+}
diff --git a/drivers/net/phy/mv88e6xxx/port.h b/drivers/net/phy/mv88e6xxx/port.h
new file mode 100644
index 000000000..84c76c42c
--- /dev/null
+++ b/drivers/net/phy/mv88e6xxx/port.h
@@ -0,0 +1,89 @@
+#ifndef _MV88E6XXX_PORT_H
+#define _MV88E6XXX_PORT_H
+
+#include "chip.h"
+
+/* Offset 0x00: Port Status Register */
+#define MV88E6XXX_PORT_STS 0x00
+#define MV88E6XXX_PORT_STS_PAUSE_EN 0x8000
+#define MV88E6XXX_PORT_STS_MY_PAUSE 0x4000
+#define MV88E6XXX_PORT_STS_HD_FLOW 0x2000
+#define MV88E6XXX_PORT_STS_PHY_DETECT 0x1000
+#define MV88E6XXX_PORT_STS_LINK 0x0800
+#define MV88E6XXX_PORT_STS_DUPLEX 0x0400
+#define MV88E6XXX_PORT_STS_SPEED_MASK 0x0300
+#define MV88E6XXX_PORT_STS_SPEED_10 0x0000
+#define MV88E6XXX_PORT_STS_SPEED_100 0x0100
+#define MV88E6XXX_PORT_STS_SPEED_1000 0x0200
+#define MV88E6352_PORT_STS_EEE 0x0040
+#define MV88E6165_PORT_STS_AM_DIS 0x0040
+#define MV88E6185_PORT_STS_MGMII 0x0040
+#define MV88E6XXX_PORT_STS_TX_PAUSED 0x0020
+#define MV88E6XXX_PORT_STS_FLOW_CTL 0x0010
+#define MV88E6XXX_PORT_STS_CMODE_MASK 0x000f
+#define MV88E6XXX_PORT_STS_CMODE_100BASE_X 0x0008
+#define MV88E6XXX_PORT_STS_CMODE_1000BASE_X 0x0009
+#define MV88E6XXX_PORT_STS_CMODE_SGMII 0x000a
+#define MV88E6XXX_PORT_STS_CMODE_2500BASEX 0x000b
+#define MV88E6XXX_PORT_STS_CMODE_XAUI 0x000c
+#define MV88E6XXX_PORT_STS_CMODE_RXAUI 0x000d
+
+/* Offset 0x01: MAC (or PCS or Physical) Control Register */
+#define MV88E6XXX_PORT_MAC_CTL 0x01
+#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK 0x8000
+#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK 0x4000
+#define MV88E6390_PORT_MAC_CTL_FORCE_SPEED 0x2000
+#define MV88E6390_PORT_MAC_CTL_ALTSPEED 0x1000
+#define MV88E6352_PORT_MAC_CTL_200BASE 0x1000
+#define MV88E6XXX_PORT_MAC_CTL_FC 0x0080
+#define MV88E6XXX_PORT_MAC_CTL_FORCE_FC 0x0040
+#define MV88E6XXX_PORT_MAC_CTL_LINK_UP 0x0020
+#define MV88E6XXX_PORT_MAC_CTL_FORCE_LINK 0x0010
+#define MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL 0x0008
+#define MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX 0x0004
+#define MV88E6XXX_PORT_MAC_CTL_SPEED_MASK 0x0003
+#define MV88E6XXX_PORT_MAC_CTL_SPEED_10 0x0000
+#define MV88E6XXX_PORT_MAC_CTL_SPEED_100 0x0001
+#define MV88E6065_PORT_MAC_CTL_SPEED_200 0x0002
+#define MV88E6XXX_PORT_MAC_CTL_SPEED_1000 0x0002
+#define MV88E6390_PORT_MAC_CTL_SPEED_10000 0x0003
+#define MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED 0x0003
+
+/* Offset 0x03: Switch Identifier Register */
+#define MV88E6XXX_PORT_SWITCH_ID 0x03
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_MASK 0xfff0
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6085 0x04a0
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6095 0x0950
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6097 0x0990
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6190X 0x0a00
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6390X 0x0a10
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6131 0x1060
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6320 0x1150
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6123 0x1210
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6161 0x1610
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6165 0x1650
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6171 0x1710
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6172 0x1720
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6175 0x1750
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6176 0x1760
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6190 0x1900
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6191 0x1910
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6185 0x1a70
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6290 0x2900
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6321 0x3100
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6141 0x3400
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6341 0x3410
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6352 0x3520
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6350 0x3710
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6351 0x3750
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6390 0x3900
+#define MV88E6XXX_PORT_SWITCH_ID_REV_MASK 0x000f
+
+int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
+ u16 *val);
+int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
+ u16 val);
+
+
+#endif /* _MV88E6XXX_PORT_H */
\ No newline at end of file
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 16/17] net: phy: mv88e6xxx: Port EEPROM support code
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (14 preceding siblings ...)
2018-10-09 17:38 ` [PATCH v2 15/17] net: phy: Add basic driver for MV88E6XXX switches from Marvell Andrey Smirnov
@ 2018-10-09 17:38 ` Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 17/17] net: phy: mv88e6xxx: Add support for MAC ports Andrey Smirnov
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:38 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/net/phy/mv88e6xxx/chip.c | 85 ++++++++-
drivers/net/phy/mv88e6xxx/chip.h | 10 ++
drivers/net/phy/mv88e6xxx/global2.c | 265 ++++++++++++++++++++++++++++
drivers/net/phy/mv88e6xxx/global2.h | 29 +++
4 files changed, 388 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/mv88e6xxx/chip.c b/drivers/net/phy/mv88e6xxx/chip.c
index cde60f43c..162acf1cc 100644
--- a/drivers/net/phy/mv88e6xxx/chip.c
+++ b/drivers/net/phy/mv88e6xxx/chip.c
@@ -4,6 +4,7 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/bitfield.h>
+#include <linux/nvmem-provider.h>
#include <gpio.h>
#include <of_device.h>
@@ -80,6 +81,8 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
static const struct mv88e6xxx_ops mv88e6141_ops = {
/* MV88E6XXX_FAMILY_6341 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
@@ -105,6 +108,8 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
static const struct mv88e6xxx_ops mv88e6172_ops = {
/* MV88E6XXX_FAMILY_6352 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom16,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
@@ -117,6 +122,8 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
static const struct mv88e6xxx_ops mv88e6176_ops = {
/* MV88E6XXX_FAMILY_6352 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom16,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
@@ -130,48 +137,64 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
static const struct mv88e6xxx_ops mv88e6190_ops = {
/* MV88E6XXX_FAMILY_6390 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
static const struct mv88e6xxx_ops mv88e6190x_ops = {
/* MV88E6XXX_FAMILY_6390 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
static const struct mv88e6xxx_ops mv88e6191_ops = {
/* MV88E6XXX_FAMILY_6390 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
static const struct mv88e6xxx_ops mv88e6240_ops = {
/* MV88E6XXX_FAMILY_6352 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom16,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
static const struct mv88e6xxx_ops mv88e6290_ops = {
/* MV88E6XXX_FAMILY_6390 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
static const struct mv88e6xxx_ops mv88e6320_ops = {
/* MV88E6XXX_FAMILY_6320 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom16,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
static const struct mv88e6xxx_ops mv88e6321_ops = {
/* MV88E6XXX_FAMILY_6320 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom16,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
static const struct mv88e6xxx_ops mv88e6341_ops = {
/* MV88E6XXX_FAMILY_6341 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
@@ -192,16 +215,22 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
/* MV88E6XXX_FAMILY_6352 */
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .get_eeprom = mv88e6xxx_g2_get_eeprom16,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom16,
};
static const struct mv88e6xxx_ops mv88e6390_ops = {
/* MV88E6XXX_FAMILY_6390 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
static const struct mv88e6xxx_ops mv88e6390x_ops = {
/* MV88E6XXX_FAMILY_6390 */
+ .get_eeprom = mv88e6xxx_g2_get_eeprom8,
+ .set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
};
@@ -622,6 +651,41 @@ static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
return 0;
}
+static int mv88e6xxx_eeprom_read(struct device_d *dev, const int offset,
+ void *val, int bytes)
+{
+ struct mv88e6xxx_chip *chip = dev->parent->priv;
+ struct ethtool_eeprom eeprom = {
+ .offset = offset,
+ .len = bytes,
+ };
+
+ if (!chip->info->ops->get_eeprom)
+ return -ENOTSUPP;
+
+ return chip->info->ops->get_eeprom(chip, &eeprom, val);
+}
+
+static int mv88e6xxx_eeprom_write(struct device_d *dev, const int offset,
+ const void *val, int bytes)
+{
+ struct mv88e6xxx_chip *chip = dev->parent->priv;
+ struct ethtool_eeprom eeprom = {
+ .offset = offset,
+ .len = bytes,
+ };
+
+ if (!chip->info->ops->set_eeprom)
+ return -ENOTSUPP;
+
+ return chip->info->ops->set_eeprom(chip, &eeprom, (void *)val);
+}
+
+static const struct nvmem_bus mv88e6xxx_eeprom_nvmem_bus = {
+ .write = mv88e6xxx_eeprom_write,
+ .read = mv88e6xxx_eeprom_read,
+};
+
static int mv88e6xxx_probe(struct device_d *dev)
{
struct device_node *np = dev->device_node;
@@ -629,7 +693,7 @@ static int mv88e6xxx_probe(struct device_d *dev)
struct mv88e6xxx_chip *chip;
enum of_gpio_flags of_flags;
int err;
- u32 reg;
+ u32 reg, eeprom_len = 0;
err = of_property_read_u32(np, "reg", ®);
if (err) {
@@ -644,8 +708,11 @@ static int mv88e6xxx_probe(struct device_d *dev)
chip = xzalloc(sizeof(struct mv88e6xxx_chip));
chip->dev = dev;
+ dev->priv = chip;
chip->info = of_device_get_match_data(dev);
+ of_property_read_u32(np, "eeprom-length", &eeprom_len);
+
chip->parent_miibus = of_mdio_find_bus(np->parent);
if (!chip->parent_miibus)
return -EPROBE_DEFER;
@@ -677,6 +744,22 @@ static int mv88e6xxx_probe(struct device_d *dev)
err = mv88e6xxx_switch_reset(chip);
if (err)
return err;
+
+ if (eeprom_len) {
+ struct nvmem_config config = {
+ .name = basprintf("%s-eeprom", dev_name(dev)),
+ .dev = dev,
+ .word_size = 1,
+ .stride = 1,
+ .size = eeprom_len,
+ .read_only = false,
+ .bus = &mv88e6xxx_eeprom_nvmem_bus,
+ };
+
+ if (IS_ERR(nvmem_register(&config)))
+ dev_err(dev, "Failed to register EEPROM\n");
+ }
+
/*
* In single-chip address mode addresses 0x10 - 0x1f are
* reserved to access various switch registers and do not
diff --git a/drivers/net/phy/mv88e6xxx/chip.h b/drivers/net/phy/mv88e6xxx/chip.h
index 4df18a241..021df2664 100644
--- a/drivers/net/phy/mv88e6xxx/chip.h
+++ b/drivers/net/phy/mv88e6xxx/chip.h
@@ -45,6 +45,11 @@ struct mv88e6xxx_chip {
int reset;
};
+struct ethtool_eeprom {
+ __u32 offset;
+ __u32 len;
+};
+
struct mv88e6xxx_ops {
int (*phy_read)(struct mv88e6xxx_chip *chip,
struct mii_bus *bus,
@@ -52,6 +57,11 @@ struct mv88e6xxx_ops {
int (*phy_write)(struct mv88e6xxx_chip *chip,
struct mii_bus *bus,
int addr, int reg, u16 val);
+
+ int (*get_eeprom)(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data);
+ int (*set_eeprom)(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data);
};
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
diff --git a/drivers/net/phy/mv88e6xxx/global2.c b/drivers/net/phy/mv88e6xxx/global2.c
index fc78049aa..0e8f2c5ee 100644
--- a/drivers/net/phy/mv88e6xxx/global2.c
+++ b/drivers/net/phy/mv88e6xxx/global2.c
@@ -18,6 +18,271 @@ int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
return mv88e6xxx_wait(chip, chip->info->global2_addr, reg, mask);
}
+/* Offset 0x14: EEPROM Command
+ * Offset 0x15: EEPROM Data (for 16-bit data access)
+ * Offset 0x15: EEPROM Addr (for 8-bit data access)
+ */
+
+static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
+{
+ return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_EEPROM_CMD,
+ MV88E6XXX_G2_EEPROM_CMD_BUSY |
+ MV88E6XXX_G2_EEPROM_CMD_RUNNING);
+}
+
+static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
+{
+ int err;
+
+ err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_EEPROM_CMD,
+ MV88E6XXX_G2_EEPROM_CMD_BUSY | cmd);
+ if (err)
+ return err;
+
+ return mv88e6xxx_g2_eeprom_wait(chip);
+}
+
+static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
+ u16 addr, u8 *data)
+{
+ u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ;
+ int err;
+
+ err = mv88e6xxx_g2_eeprom_wait(chip);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &cmd);
+ if (err)
+ return err;
+
+ *data = cmd & 0xff;
+
+ return 0;
+}
+
+static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
+ u16 addr, u8 data)
+{
+ u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE |
+ MV88E6XXX_G2_EEPROM_CMD_WRITE_EN;
+ int err;
+
+ err = mv88e6xxx_g2_eeprom_wait(chip);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
+ if (err)
+ return err;
+
+ return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
+}
+
+static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
+ u8 addr, u16 *data)
+{
+ u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ | addr;
+ int err;
+
+ err = mv88e6xxx_g2_eeprom_wait(chip);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
+ if (err)
+ return err;
+
+ return mv88e6xxx_g2_read(chip, MV88E6352_G2_EEPROM_DATA, data);
+}
+
+static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
+ u8 addr, u16 data)
+{
+ u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE | addr;
+ int err;
+
+ err = mv88e6xxx_g2_eeprom_wait(chip);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_g2_write(chip, MV88E6352_G2_EEPROM_DATA, data);
+ if (err)
+ return err;
+
+ return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
+}
+
+int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ unsigned int offset = eeprom->offset;
+ unsigned int len = eeprom->len;
+ int err;
+
+ eeprom->len = 0;
+
+ while (len) {
+ err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
+ if (err)
+ return err;
+
+ eeprom->len++;
+ offset++;
+ data++;
+ len--;
+ }
+
+ return 0;
+}
+
+int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ unsigned int offset = eeprom->offset;
+ unsigned int len = eeprom->len;
+ int err;
+
+ eeprom->len = 0;
+
+ while (len) {
+ err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
+ if (err)
+ return err;
+
+ eeprom->len++;
+ offset++;
+ data++;
+ len--;
+ }
+
+ return 0;
+}
+
+int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ unsigned int offset = eeprom->offset;
+ unsigned int len = eeprom->len;
+ u16 val;
+ int err;
+
+ eeprom->len = 0;
+
+ if (offset & 1) {
+ err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
+ if (err)
+ return err;
+
+ *data++ = (val >> 8) & 0xff;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ while (len >= 2) {
+ err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
+ if (err)
+ return err;
+
+ *data++ = val & 0xff;
+ *data++ = (val >> 8) & 0xff;
+
+ offset += 2;
+ len -= 2;
+ eeprom->len += 2;
+ }
+
+ if (len) {
+ err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
+ if (err)
+ return err;
+
+ *data++ = val & 0xff;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ return 0;
+}
+
+int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ unsigned int offset = eeprom->offset;
+ unsigned int len = eeprom->len;
+ u16 val;
+ int err;
+
+ /* Ensure the RO WriteEn bit is set */
+ err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &val);
+ if (err)
+ return err;
+
+ if (!(val & MV88E6XXX_G2_EEPROM_CMD_WRITE_EN))
+ return -EROFS;
+
+ eeprom->len = 0;
+
+ if (offset & 1) {
+ err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
+ if (err)
+ return err;
+
+ val = (*data++ << 8) | (val & 0xff);
+
+ err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
+ if (err)
+ return err;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ while (len >= 2) {
+ val = *data++;
+ val |= *data++ << 8;
+
+ err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
+ if (err)
+ return err;
+
+ offset += 2;
+ len -= 2;
+ eeprom->len += 2;
+ }
+
+ if (len) {
+ err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
+ if (err)
+ return err;
+
+ val = (val & 0xff00) | *data++;
+
+ err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
+ if (err)
+ return err;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ return 0;
+}
+
static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
{
return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_SMI_PHY_CMD,
diff --git a/drivers/net/phy/mv88e6xxx/global2.h b/drivers/net/phy/mv88e6xxx/global2.h
index 28bbd8c43..7c70d4bde 100644
--- a/drivers/net/phy/mv88e6xxx/global2.h
+++ b/drivers/net/phy/mv88e6xxx/global2.h
@@ -27,6 +27,26 @@
/* Offset 0x19: SMI PHY Data Register */
#define MV88E6XXX_G2_SMI_PHY_DATA 0x19
+/* Offset 0x14: EEPROM Command */
+#define MV88E6XXX_G2_EEPROM_CMD 0x14
+#define MV88E6XXX_G2_EEPROM_CMD_BUSY 0x8000
+#define MV88E6XXX_G2_EEPROM_CMD_OP_MASK 0x7000
+#define MV88E6XXX_G2_EEPROM_CMD_OP_WRITE 0x3000
+#define MV88E6XXX_G2_EEPROM_CMD_OP_READ 0x4000
+#define MV88E6XXX_G2_EEPROM_CMD_OP_LOAD 0x6000
+#define MV88E6XXX_G2_EEPROM_CMD_RUNNING 0x0800
+#define MV88E6XXX_G2_EEPROM_CMD_WRITE_EN 0x0400
+#define MV88E6352_G2_EEPROM_CMD_ADDR_MASK 0x00ff
+#define MV88E6390_G2_EEPROM_CMD_DATA_MASK 0x00ff
+
+/* Offset 0x15: EEPROM Data */
+#define MV88E6352_G2_EEPROM_DATA 0x15
+#define MV88E6352_G2_EEPROM_DATA_MASK 0xffff
+
+/* Offset 0x15: EEPROM Addr */
+#define MV88E6390_G2_EEPROM_ADDR 0x15
+#define MV88E6390_G2_EEPROM_ADDR_MASK 0xffff
+
int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val);
int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val);
int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask);
@@ -38,4 +58,13 @@ int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip,
struct mii_bus *bus,
int addr, int reg, u16 val);
+int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data);
+int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data);
+int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data);
+int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
+ struct ethtool_eeprom *eeprom, u8 *data);
+
#endif /* _MV88E6XXX_GLOBAL2_H */
\ No newline at end of file
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 17/17] net: phy: mv88e6xxx: Add support for MAC ports
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
` (15 preceding siblings ...)
2018-10-09 17:38 ` [PATCH v2 16/17] net: phy: mv88e6xxx: Port EEPROM support code Andrey Smirnov
@ 2018-10-09 17:38 ` Andrey Smirnov
16 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-09 17:38 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/net/phy/mv88e6xxx/chip.c | 146 ++++++-
drivers/net/phy/mv88e6xxx/chip.h | 72 ++++
drivers/net/phy/mv88e6xxx/port.c | 646 +++++++++++++++++++++++++++++++
drivers/net/phy/mv88e6xxx/port.h | 38 ++
4 files changed, 898 insertions(+), 4 deletions(-)
diff --git a/drivers/net/phy/mv88e6xxx/chip.c b/drivers/net/phy/mv88e6xxx/chip.c
index 162acf1cc..5a8947f8b 100644
--- a/drivers/net/phy/mv88e6xxx/chip.c
+++ b/drivers/net/phy/mv88e6xxx/chip.c
@@ -64,12 +64,20 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
/* MV88E6XXX_FAMILY_6097 */
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6123_ops = {
/* MV88E6XXX_FAMILY_6165 */
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6131_ops = {
@@ -85,12 +93,20 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6161_ops = {
/* MV88E6XXX_FAMILY_6165 */
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6165_ops = {
@@ -104,6 +120,11 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
/* MV88E6XXX_FAMILY_6351 */
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6172_ops = {
@@ -112,12 +133,22 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
+ .port_set_speed = mv88e6352_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6175_ops = {
/* MV88E6XXX_FAMILY_6351 */
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6176_ops = {
@@ -126,6 +157,11 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
+ .port_set_speed = mv88e6352_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6185_ops = {
@@ -141,6 +177,11 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
+ .port_set_speed = mv88e6390_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6190x_ops = {
@@ -149,6 +190,11 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
+ .port_set_speed = mv88e6390x_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6191_ops = {
@@ -157,6 +203,11 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
+ .port_set_speed = mv88e6390_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6240_ops = {
@@ -165,6 +216,11 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
+ .port_set_speed = mv88e6352_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6290_ops = {
@@ -173,6 +229,11 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
+ .port_set_speed = mv88e6390_port_set_speed,
+ .port_set_cmode = mv88e6390x_port_set_cmode,
};
static const struct mv88e6xxx_ops mv88e6320_ops = {
@@ -181,6 +242,10 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -189,6 +254,10 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom16,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6341_ops = {
@@ -197,18 +266,33 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
+ .port_set_speed = mv88e6390_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6350_ops = {
/* MV88E6XXX_FAMILY_6351 */
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6351_ops = {
/* MV88E6XXX_FAMILY_6351 */
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
+ .port_set_speed = mv88e6185_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6352_ops = {
@@ -217,6 +301,11 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.phy_write = mv88e6xxx_g2_smi_phy_write,
.get_eeprom = mv88e6xxx_g2_get_eeprom16,
.set_eeprom = mv88e6xxx_g2_set_eeprom16,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
+ .port_set_speed = mv88e6352_port_set_speed,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6390_ops = {
@@ -225,6 +314,12 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
+ .port_set_speed = mv88e6390_port_set_speed,
+ .port_set_cmode = mv88e6390x_port_set_cmode,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_ops mv88e6390x_ops = {
@@ -233,6 +328,12 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.set_eeprom = mv88e6xxx_g2_set_eeprom8,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
+ .port_set_link = mv88e6xxx_port_set_link,
+ .port_set_duplex = mv88e6xxx_port_set_duplex,
+ .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
+ .port_set_speed = mv88e6390x_port_set_speed,
+ .port_set_cmode = mv88e6390x_port_set_cmode,
+ .port_link_state = mv88e6352_port_link_state,
};
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
@@ -241,6 +342,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6097,
.name = "Marvell 88E6085",
.num_ports = 10,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6085_ops,
@@ -251,6 +353,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6095,
.name = "Marvell 88E6095/88E6095F",
.num_ports = 11,
+ .num_internal_phys = 0,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6095_ops,
@@ -261,6 +364,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6097,
.name = "Marvell 88E6097/88E6097F",
.num_ports = 11,
+ .num_internal_phys = 8,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6097_ops,
@@ -271,6 +375,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6123",
.num_ports = 3,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6123_ops,
@@ -281,6 +386,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6131",
.num_ports = 8,
+ .num_internal_phys = 0,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6131_ops,
@@ -291,6 +397,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6341,
.name = "Marvell 88E6341",
.num_ports = 6,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6141_ops,
@@ -301,6 +408,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6161",
.num_ports = 6,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6161_ops,
@@ -311,6 +419,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6165",
.num_ports = 6,
+ .num_internal_phys = 0,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6165_ops,
@@ -321,6 +430,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6171",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6171_ops,
@@ -331,6 +441,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6172",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6172_ops,
@@ -341,6 +452,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6175",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6175_ops,
@@ -351,6 +463,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6176",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6176_ops,
@@ -361,6 +474,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6185",
.num_ports = 10,
+ .num_internal_phys = 0,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6185_ops,
@@ -371,6 +485,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6190",
.num_ports = 11, /* 10 + Z80 */
+ .num_internal_phys = 11,
.port_base_addr = 0x0,
.global2_addr = 0x1c,
.ops = &mv88e6190_ops,
@@ -381,6 +496,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6190X",
.num_ports = 11, /* 10 + Z80 */
+ .num_internal_phys = 11,
.port_base_addr = 0x0,
.global2_addr = 0x1c,
.ops = &mv88e6190x_ops,
@@ -391,6 +507,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6191",
.num_ports = 11, /* 10 + Z80 */
+ .num_internal_phys = 11,
.port_base_addr = 0x0,
.global2_addr = 0x1c,
.ops = &mv88e6191_ops,
@@ -401,6 +518,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6240",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6240_ops,
@@ -411,6 +529,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6290",
.num_ports = 11, /* 10 + Z80 */
+ .num_internal_phys = 11,
.port_base_addr = 0x0,
.global2_addr = 0x1c,
.ops = &mv88e6290_ops,
@@ -421,6 +540,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6320",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6320_ops,
@@ -431,6 +551,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6321",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6321_ops,
@@ -441,6 +562,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6341,
.name = "Marvell 88E6341",
.num_ports = 6,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6341_ops,
@@ -451,6 +573,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6350",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6350_ops,
@@ -461,6 +584,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6351",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.global2_addr = 0x1c,
.ops = &mv88e6351_ops,
@@ -471,6 +595,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6352",
.num_ports = 7,
+ .num_internal_phys = 5,
.port_base_addr = 0x10,
.ops = &mv88e6352_ops,
.global2_addr = 0x1c,
@@ -482,6 +607,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6390",
.num_ports = 11, /* 10 + Z80 */
+ .num_internal_phys = 11,
.port_base_addr = 0x0,
.global2_addr = 0x1c,
.ops = &mv88e6390_ops,
@@ -492,6 +618,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6390X",
.num_ports = 11, /* 10 + Z80 */
+ .num_internal_phys = 11,
.port_base_addr = 0x0,
.global2_addr = 0x1c,
.ops = &mv88e6390x_ops,
@@ -692,8 +819,8 @@ static int mv88e6xxx_probe(struct device_d *dev)
struct device_node *mdio_node;
struct mv88e6xxx_chip *chip;
enum of_gpio_flags of_flags;
- int err;
u32 reg, eeprom_len = 0;
+ int err;
err = of_property_read_u32(np, "reg", ®);
if (err) {
@@ -766,13 +893,16 @@ static int mv88e6xxx_probe(struct device_d *dev)
* correspond to any PHYs, so we mask them to pervent from
* being exposed as phy devices
*/
- chip->parent_miibus->phy_mask |= GENMASK(0x1f, 0x10);
+ /* FIXME: This should probably use port_base_addr */
+
+ chip->parent_miibus->phy_mask |= GENMASK(0x1f,
+ chip->info->port_base_addr);
/*
* Address 0x0f on internal bus is dedicated to SERDES
* registers and won't be very useful against standard PHY
* driver
*/
- chip->miibus.phy_mask |= GENMASK(0x1f, 0x0f);
+ chip->miibus.phy_mask |= GENMASK(0x1f, chip->info->num_ports);
chip->miibus.read = mv88e6xxx_mdio_read;
chip->miibus.write = mv88e6xxx_mdio_write;
@@ -784,7 +914,15 @@ static int mv88e6xxx_probe(struct device_d *dev)
if (mdio_node)
chip->miibus.dev.device_node = mdio_node;
- return mdiobus_register(&chip->miibus);
+ err = m88e6xxx_port_probe(chip);
+ if (err)
+ return err;
+
+ err = mdiobus_register(&chip->miibus);
+ if (err)
+ return err;
+
+ return 0;
}
static const struct of_device_id mv88e6xxx_of_match[] = {
diff --git a/drivers/net/phy/mv88e6xxx/chip.h b/drivers/net/phy/mv88e6xxx/chip.h
index 021df2664..bc527efeb 100644
--- a/drivers/net/phy/mv88e6xxx/chip.h
+++ b/drivers/net/phy/mv88e6xxx/chip.h
@@ -26,23 +26,33 @@ enum mv88e6xxx_family {
struct mv88e6xxx_ops;
+#define DSA_MAX_PORTS 12
+
struct mv88e6xxx_info {
enum mv88e6xxx_family family;
u16 prod_num;
const char *name;
unsigned int num_ports;
+ unsigned int num_internal_phys;
unsigned int port_base_addr;
unsigned int global2_addr;
const struct mv88e6xxx_ops *ops;
};
+struct mv88e6xxx_port {
+ u8 cmode;
+};
+
struct mv88e6xxx_chip {
const struct mv88e6xxx_info *info;
struct mii_bus *parent_miibus;
struct mii_bus miibus;
struct device_d *dev;
int reset;
+
+ /* Array of port structures. */
+ struct mv88e6xxx_port ports[DSA_MAX_PORTS];
};
struct ethtool_eeprom {
@@ -50,6 +60,16 @@ struct ethtool_eeprom {
__u32 len;
};
+struct phylink_link_state {
+ phy_interface_t interface;
+ int speed;
+ int duplex;
+ int pause;
+ unsigned int link:1;
+ unsigned int an_enabled:1;
+ unsigned int an_complete:1;
+};
+
struct mv88e6xxx_ops {
int (*phy_read)(struct mv88e6xxx_chip *chip,
struct mii_bus *bus,
@@ -62,6 +82,58 @@ struct mv88e6xxx_ops {
struct ethtool_eeprom *eeprom, u8 *data);
int (*set_eeprom)(struct mv88e6xxx_chip *chip,
struct ethtool_eeprom *eeprom, u8 *data);
+
+ /* RGMII Receive/Transmit Timing Control
+ * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise.
+ */
+ int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port,
+ phy_interface_t mode);
+
+#define LINK_FORCED_DOWN 0
+#define LINK_FORCED_UP 1
+#define LINK_UNFORCED -2
+
+ /* Port's MAC link state
+ * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down,
+ * or LINK_UNFORCED for normal link detection.
+ */
+ int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
+
+#define DUPLEX_UNFORCED -2
+
+ /* Port's MAC duplex mode
+ *
+ * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex,
+ * or DUPLEX_UNFORCED for normal duplex detection.
+ */
+ int (*port_set_duplex)(struct mv88e6xxx_chip *chip, int port, int dup);
+
+#define PAUSE_ON 1
+#define PAUSE_OFF 0
+
+ /* Enable/disable sending Pause */
+ int (*port_set_pause)(struct mv88e6xxx_chip *chip, int port,
+ int pause);
+
+#define SPEED_MAX INT_MAX
+#define SPEED_UNFORCED -2
+
+ /* Port's MAC speed (in Mbps)
+ *
+ * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid.
+ * Use SPEED_UNFORCED for normal detection, SPEED_MAX for max value.
+ */
+ int (*port_set_speed)(struct mv88e6xxx_chip *chip, int port, int speed);
+
+ /* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc.
+ * Some chips allow this to be configured on specific ports.
+ */
+ int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port,
+ phy_interface_t mode);
+
+ /* Return the port link state, as required by phylink */
+ int (*port_link_state)(struct mv88e6xxx_chip *chip, int port,
+ struct phylink_link_state *state);
};
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
diff --git a/drivers/net/phy/mv88e6xxx/port.c b/drivers/net/phy/mv88e6xxx/port.c
index 59afdbd97..c15b25cc2 100644
--- a/drivers/net/phy/mv88e6xxx/port.c
+++ b/drivers/net/phy/mv88e6xxx/port.c
@@ -1,6 +1,8 @@
#include <common.h>
#include <init.h>
+#include <linux/marvell_phy.h>
+
#include "port.h"
int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
@@ -18,3 +20,647 @@ int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
return mv88e6xxx_write(chip, addr, reg, val);
}
+
+/* Offset 0x00: MAC (or PCS or Physical) Status Register
+ *
+ * For most devices, this is read only. However the 6185 has the MyPause
+ * bit read/write.
+ */
+int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
+ int pause)
+{
+ u16 reg;
+ int err;
+
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
+ if (err)
+ return err;
+
+ if (pause)
+ reg |= MV88E6XXX_PORT_STS_MY_PAUSE;
+ else
+ reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE;
+
+ return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
+}
+
+/* Offset 0x01: MAC (or PCS or Physical) Control Register
+ *
+ * Link, Duplex and Flow Control have one force bit, one value bit.
+ *
+ * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
+ * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
+ * Newer chips need a ForcedSpd bit 13 set to consider the value.
+ */
+
+static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
+ phy_interface_t mode)
+{
+ u16 reg;
+ int err;
+
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
+ if (err)
+ return err;
+
+ reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
+ MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
+
+ switch (mode) {
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
+ MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ break;
+ default:
+ return 0;
+ }
+
+ err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
+ if (err)
+ return err;
+
+ dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
+ reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
+ reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
+
+ return 0;
+}
+
+int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
+ phy_interface_t mode)
+{
+ if (port < 5)
+ return -EOPNOTSUPP;
+
+ return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
+}
+
+int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
+ phy_interface_t mode)
+{
+ if (port != 0)
+ return -EOPNOTSUPP;
+
+ return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
+}
+
+int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
+{
+ u16 reg;
+ int err;
+
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
+ if (err)
+ return err;
+
+ reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
+ MV88E6XXX_PORT_MAC_CTL_LINK_UP);
+
+ switch (link) {
+ case LINK_FORCED_DOWN:
+ reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
+ break;
+ case LINK_FORCED_UP:
+ reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
+ MV88E6XXX_PORT_MAC_CTL_LINK_UP;
+ break;
+ case LINK_UNFORCED:
+ /* normal link detection */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
+ if (err)
+ return err;
+
+ dev_dbg(chip->dev, "p%d: %s link %s\n", port,
+ reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
+ reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down");
+
+ return 0;
+}
+
+int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup)
+{
+ u16 reg;
+ int err;
+
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
+ if (err)
+ return err;
+
+ reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
+ MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
+
+ switch (dup) {
+ case DUPLEX_HALF:
+ reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
+ break;
+ case DUPLEX_FULL:
+ reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
+ MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
+ break;
+ case DUPLEX_UNFORCED:
+ /* normal duplex detection */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
+ if (err)
+ return err;
+
+ dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
+ reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
+ reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
+
+ return 0;
+}
+
+static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port,
+ int speed, bool alt_bit, bool force_bit)
+{
+ u16 reg, ctrl;
+ int err;
+
+ switch (speed) {
+ case 10:
+ ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
+ break;
+ case 100:
+ ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
+ break;
+ case 200:
+ if (alt_bit)
+ ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
+ MV88E6390_PORT_MAC_CTL_ALTSPEED;
+ else
+ ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
+ break;
+ case 1000:
+ ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
+ break;
+ case 2500:
+ ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
+ MV88E6390_PORT_MAC_CTL_ALTSPEED;
+ break;
+ case 10000:
+ /* all bits set, fall through... */
+ case SPEED_UNFORCED:
+ ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
+ if (err)
+ return err;
+
+ reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK;
+ if (alt_bit)
+ reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
+ if (force_bit) {
+ reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
+ if (speed != SPEED_UNFORCED)
+ ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
+ }
+ reg |= ctrl;
+
+ err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
+ if (err)
+ return err;
+
+ if (speed)
+ dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
+ else
+ dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
+
+ return 0;
+}
+
+/* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
+int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
+{
+ if (speed == SPEED_MAX)
+ speed = 200;
+
+ if (speed > 200)
+ return -EOPNOTSUPP;
+
+ /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
+ return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
+}
+
+/* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
+int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
+{
+ if (speed == SPEED_MAX)
+ speed = 1000;
+
+ if (speed == 200 || speed > 1000)
+ return -EOPNOTSUPP;
+
+ return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
+}
+
+/* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
+int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
+{
+ if (speed == SPEED_MAX)
+ speed = 1000;
+
+ if (speed > 1000)
+ return -EOPNOTSUPP;
+
+ if (speed == 200 && port < 5)
+ return -EOPNOTSUPP;
+
+ return mv88e6xxx_port_set_speed(chip, port, speed, true, false);
+}
+
+/* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
+int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
+{
+ if (speed == SPEED_MAX)
+ speed = port < 9 ? 1000 : 2500;
+
+ if (speed > 2500)
+ return -EOPNOTSUPP;
+
+ if (speed == 200 && port != 0)
+ return -EOPNOTSUPP;
+
+ if (speed == 2500 && port < 9)
+ return -EOPNOTSUPP;
+
+ return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
+}
+
+/* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
+int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
+{
+ if (speed == SPEED_MAX)
+ speed = port < 9 ? 1000 : 10000;
+
+ if (speed == 200 && port != 0)
+ return -EOPNOTSUPP;
+
+ if (speed >= 2500 && port < 9)
+ return -EOPNOTSUPP;
+
+ return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
+}
+
+int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
+ phy_interface_t mode)
+{
+ /* int lane; */
+ u16 cmode;
+ /* u16 reg; */
+ /* int err; */
+
+ if (mode == PHY_INTERFACE_MODE_NA)
+ return 0;
+
+ if (port != 9 && port != 10)
+ return -EOPNOTSUPP;
+
+ switch (mode) {
+ case PHY_INTERFACE_MODE_1000BASEX:
+ cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X;
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
+ break;
+ case PHY_INTERFACE_MODE_2500BASEX:
+ cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
+ break;
+ case PHY_INTERFACE_MODE_XGMII:
+ case PHY_INTERFACE_MODE_XAUI:
+ cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
+ break;
+ case PHY_INTERFACE_MODE_RXAUI:
+ cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
+ break;
+ default:
+ cmode = 0;
+ }
+#if 0
+ lane = mv88e6390x_serdes_get_lane(chip, port);
+ if (lane < 0)
+ return lane;
+
+ if (chip->ports[port].serdes_irq) {
+ err = mv88e6390_serdes_irq_disable(chip, port, lane);
+ if (err)
+ return err;
+ }
+
+ err = mv88e6390_serdes_power(chip, port, false);
+ if (err)
+ return err;
+
+ if (cmode) {
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
+ if (err)
+ return err;
+
+ reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
+ reg |= cmode;
+
+ err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
+ if (err)
+ return err;
+
+ err = mv88e6390_serdes_power(chip, port, true);
+ if (err)
+ return err;
+
+ if (chip->ports[port].serdes_irq) {
+ err = mv88e6390_serdes_irq_enable(chip, port, lane);
+ if (err)
+ return err;
+ }
+ }
+#endif
+ chip->ports[port].cmode = cmode;
+
+ return 0;
+}
+
+int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
+ struct phylink_link_state *state)
+{
+ int err;
+ u16 reg;
+
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
+ if (err)
+ return err;
+
+ switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) {
+ case MV88E6XXX_PORT_STS_SPEED_10:
+ state->speed = SPEED_10;
+ break;
+ case MV88E6XXX_PORT_STS_SPEED_100:
+ state->speed = SPEED_100;
+ break;
+ case MV88E6XXX_PORT_STS_SPEED_1000:
+ state->speed = SPEED_1000;
+ break;
+ case MV88E6XXX_PORT_STS_SPEED_10000:
+ if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) ==
+ MV88E6XXX_PORT_STS_CMODE_2500BASEX)
+ state->speed = SPEED_2500;
+ else
+ state->speed = SPEED_10000;
+ break;
+ }
+
+ state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ?
+ DUPLEX_FULL : DUPLEX_HALF;
+ state->link = !!(reg & MV88E6XXX_PORT_STS_LINK);
+ state->an_enabled = 1;
+ state->an_complete = state->link;
+
+ return 0;
+}
+
+int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
+ struct phylink_link_state *state)
+{
+ if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
+ u8 cmode = chip->ports[port].cmode;
+
+ /* When a port is in "Cross-chip serdes" mode, it uses
+ * 1000Base-X full duplex mode, but there is no automatic
+ * link detection. Use the sync OK status for link (as it
+ * would do for 1000Base-X mode.)
+ */
+ if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) {
+ u16 mac;
+ int err;
+
+ err = mv88e6xxx_port_read(chip, port,
+ MV88E6XXX_PORT_MAC_CTL, &mac);
+ if (err)
+ return err;
+
+ state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK);
+ state->an_enabled = 1;
+ state->an_complete =
+ !!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE);
+ state->duplex =
+ state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
+ state->speed =
+ state->link ? SPEED_1000 : SPEED_UNKNOWN;
+
+ return 0;
+ }
+ }
+
+ return mv88e6352_port_link_state(chip, port, state);
+}
+
+
+static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
+ int link, int speed, int duplex, int pause,
+ phy_interface_t mode)
+{
+ int err;
+
+ if (!chip->info->ops->port_set_link)
+ return 0;
+
+ /* Port's MAC control must not be changed unless the link is down */
+ err = chip->info->ops->port_set_link(chip, port, 0);
+ if (err)
+ return err;
+
+ if (chip->info->ops->port_set_speed) {
+ err = chip->info->ops->port_set_speed(chip, port, speed);
+ if (err && err != -EOPNOTSUPP)
+ goto restore_link;
+ }
+
+ if (chip->info->ops->port_set_pause) {
+ err = chip->info->ops->port_set_pause(chip, port, pause);
+ if (err)
+ goto restore_link;
+
+ }
+
+ if (chip->info->ops->port_set_duplex) {
+ err = chip->info->ops->port_set_duplex(chip, port, duplex);
+ if (err && err != -EOPNOTSUPP)
+ goto restore_link;
+ }
+
+ if (chip->info->ops->port_set_rgmii_delay) {
+ err = chip->info->ops->port_set_rgmii_delay(chip, port, mode);
+ if (err && err != -EOPNOTSUPP)
+ goto restore_link;
+ }
+
+ if (chip->info->ops->port_set_cmode) {
+ err = chip->info->ops->port_set_cmode(chip, port, mode);
+ if (err && err != -EOPNOTSUPP)
+ goto restore_link;
+ }
+
+ err = 0;
+restore_link:
+ if (chip->info->ops->port_set_link(chip, port, link))
+ dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port);
+
+ return err;
+}
+
+static int mv88e6xxx_port_config_init(struct phy_device *phydev)
+{
+ struct mv88e6xxx_chip *chip = phydev->dev.priv;
+ int port = phydev->addr - chip->info->port_base_addr;
+ int err;
+
+ err = mv88e6xxx_port_setup_mac(chip, port, phydev->link, phydev->speed,
+ phydev->duplex, phydev->pause,
+ phydev->interface);
+
+ if (err && err != -EOPNOTSUPP)
+ dev_err(&phydev->dev, "p%d: failed to configure MAC\n", port);
+
+ return err;
+}
+
+static int mv88e6xxx_port_config_aneg(struct phy_device *phydev)
+{
+ return 0;
+}
+
+static int mv88e6xxx_port_read_status(struct phy_device *phydev)
+{
+ struct mv88e6xxx_chip *chip = phydev->dev.priv;
+ int port = phydev->addr - chip->info->port_base_addr;
+ struct phylink_link_state state;
+ int err;
+
+ err = mv88e6352_port_link_state(chip, port, &state);
+ if (err)
+ return err;
+
+ phydev->link = state.link;
+ phydev->duplex = state.duplex;
+ phydev->speed = state.speed;
+
+ phydev->pause = phydev->asym_pause = 0;
+
+ return 0;
+}
+
+/*
+ * Fake switch PHY_ID used to match this driver against, devices
+ * create in m88e6xxx_port_probe.
+ */
+#define MV88E6XXX_SWITCH_PORT_PHY_ID (0x01410000 | \
+ MV88E6XXX_PORT_SWITCH_ID_PROD_6085)
+
+static struct phy_driver mv88e6xxx_port_driver = {
+ .phy_id = MV88E6XXX_SWITCH_PORT_PHY_ID,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .drv.name = "Marvel 88E6xxx Port",
+ .features = PHY_GBIT_FEATURES & ~SUPPORTED_Autoneg,
+ .config_init = mv88e6xxx_port_config_init,
+ .config_aneg = mv88e6xxx_port_config_aneg,
+ .read_status = mv88e6xxx_port_read_status,
+};
+
+static int __init mv88e6xxx_port_driver_register(void)
+{
+ return phy_driver_register(&mv88e6xxx_port_driver);
+}
+fs_initcall(mv88e6xxx_port_driver_register);
+
+int m88e6xxx_port_probe(struct mv88e6xxx_chip *chip)
+{
+ struct device_d *dev = chip->dev;
+ struct device_node *np = dev->device_node;
+ struct device_node *port_node, *switch_node;
+ struct device_node *port_nodes[DSA_MAX_PORTS] = { NULL };
+ int err, i;
+
+ switch_node = of_find_node_by_name(np, "ports");
+ if (!switch_node)
+ return -EINVAL;
+
+ for_each_available_child_of_node(switch_node, port_node) {
+ u32 nr;
+
+ err = of_property_read_u32(port_node, "reg", &nr);
+ if (err) {
+ dev_err(dev,
+ "Error: Failed to find reg for child %s\n",
+ port_node->full_name);
+ continue;
+ }
+
+ port_nodes[nr] = port_node;
+ }
+
+ /*
+ * Walk through all of the ports and unmask those that are
+ * connected to a PHY via child MDIO bus, so the can be picked
+ * up via regular PHY discover.
+ *
+ * While at it, also create PHY objects for ports that are
+ * not, so they can be correctly configured
+ */
+ for (i = 0; i < chip->info->num_ports; i++) {
+ struct phy_device *phydev;
+ u16 status;
+
+ err = mv88e6xxx_port_read(chip, i, MV88E6XXX_PORT_STS,
+ &status);
+ if (err)
+ return err;
+
+ if (status & MV88E6XXX_PORT_STS_PHY_DETECT) {
+ /*
+ * True PHYs will be automaticall handled by
+ * generic PHY driver, so we ignore those.
+ */
+ /* chip->parent_miibus->phy_mask &= ~BIT(i); */
+ continue;
+ }
+
+ /*
+ * In order to expose MAC-only ports on the switch, so
+ * they can be properly configured to match other
+ * end's settings, we create pseudo PHY devices that
+ * will match against our special PHY driver
+ */
+ phydev = phy_device_create(chip->parent_miibus,
+ chip->info->port_base_addr + i,
+ MV88E6XXX_SWITCH_PORT_PHY_ID);
+ phydev->dev.device_node = port_nodes[i];
+ phydev->dev.priv = chip;
+ phydev->duplex = DUPLEX_UNFORCED;
+
+ err = phy_register_device(phydev);
+ if (err)
+ dev_err(dev, "Error: Failed to register a PHY\n");
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/drivers/net/phy/mv88e6xxx/port.h b/drivers/net/phy/mv88e6xxx/port.h
index 84c76c42c..35fdc908d 100644
--- a/drivers/net/phy/mv88e6xxx/port.h
+++ b/drivers/net/phy/mv88e6xxx/port.h
@@ -15,6 +15,7 @@
#define MV88E6XXX_PORT_STS_SPEED_10 0x0000
#define MV88E6XXX_PORT_STS_SPEED_100 0x0100
#define MV88E6XXX_PORT_STS_SPEED_1000 0x0200
+#define MV88E6XXX_PORT_STS_SPEED_10000 0x0300
#define MV88E6352_PORT_STS_EEE 0x0040
#define MV88E6165_PORT_STS_AM_DIS 0x0040
#define MV88E6185_PORT_STS_MGMII 0x0040
@@ -27,14 +28,28 @@
#define MV88E6XXX_PORT_STS_CMODE_2500BASEX 0x000b
#define MV88E6XXX_PORT_STS_CMODE_XAUI 0x000c
#define MV88E6XXX_PORT_STS_CMODE_RXAUI 0x000d
+#define MV88E6185_PORT_STS_CDUPLEX 0x0008
+#define MV88E6185_PORT_STS_CMODE_MASK 0x0007
+#define MV88E6185_PORT_STS_CMODE_GMII_FD 0x0000
+#define MV88E6185_PORT_STS_CMODE_MII_100_FD_PS 0x0001
+#define MV88E6185_PORT_STS_CMODE_MII_100 0x0002
+#define MV88E6185_PORT_STS_CMODE_MII_10 0x0003
+#define MV88E6185_PORT_STS_CMODE_SERDES 0x0004
+#define MV88E6185_PORT_STS_CMODE_1000BASE_X 0x0005
+#define MV88E6185_PORT_STS_CMODE_PHY 0x0006
+#define MV88E6185_PORT_STS_CMODE_DISABLED 0x0007
/* Offset 0x01: MAC (or PCS or Physical) Control Register */
#define MV88E6XXX_PORT_MAC_CTL 0x01
#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK 0x8000
#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK 0x4000
+#define MV88E6185_PORT_MAC_CTL_SYNC_OK 0x4000
#define MV88E6390_PORT_MAC_CTL_FORCE_SPEED 0x2000
#define MV88E6390_PORT_MAC_CTL_ALTSPEED 0x1000
#define MV88E6352_PORT_MAC_CTL_200BASE 0x1000
+#define MV88E6185_PORT_MAC_CTL_AN_EN 0x0400
+#define MV88E6185_PORT_MAC_CTL_AN_RESTART 0x0200
+#define MV88E6185_PORT_MAC_CTL_AN_DONE 0x0100
#define MV88E6XXX_PORT_MAC_CTL_FC 0x0080
#define MV88E6XXX_PORT_MAC_CTL_FORCE_FC 0x0040
#define MV88E6XXX_PORT_MAC_CTL_LINK_UP 0x0020
@@ -85,5 +100,28 @@ int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
u16 val);
+int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
+ int pause);
+int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
+ phy_interface_t mode);
+int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
+ phy_interface_t mode);
+int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link);
+int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup);
+int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
+int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
+int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
+int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
+int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
+int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
+ phy_interface_t mode);
+int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
+ struct phylink_link_state *state);
+int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
+ struct phylink_link_state *state);
+
+/* Barebox specific */
+int m88e6xxx_port_probe(struct mv88e6xxx_chip *chip);
+
#endif /* _MV88E6XXX_PORT_H */
\ No newline at end of file
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 07/17] drivers: Introduce dev_set_name()
2018-10-09 17:37 ` [PATCH v2 07/17] drivers: Introduce dev_set_name() Andrey Smirnov
@ 2018-10-10 2:57 ` Andrey Smirnov
2018-10-11 8:56 ` Sascha Hauer
2018-10-10 9:41 ` Lucas Stach
1 sibling, 1 reply; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-10 2:57 UTC (permalink / raw)
To: Barebox List
On Tue, Oct 9, 2018 at 10:38 AM Andrey Smirnov <andrew.smirnov@gmail.com> wrote:
>
> In order to allow device names that are longer than MAX_DRIVER_NAME,
> port Linux kernel function of the same name, and convert all of the
> code to use it.
>
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> ---
> arch/arm/mach-imx/iim.c | 2 +-
> .../arm/mach-imx/include/mach/devices-imx51.h | 2 +-
> .../arm/mach-imx/include/mach/devices-imx53.h | 2 +-
> arch/arm/mach-mxs/include/mach/devices.h | 2 +-
> arch/arm/mach-mxs/ocotp.c | 2 +-
> arch/sandbox/board/console.c | 2 +-
> common/console.c | 4 +-
> common/state/state.c | 2 +-
> drivers/aiodev/core.c | 2 +-
> drivers/amba/bus.c | 2 +-
> drivers/ata/disk_ata_drive.c | 4 +-
> drivers/base/bus.c | 2 +-
> drivers/base/driver.c | 47 +++++++++++++++++--
> drivers/base/resource.c | 2 +-
> drivers/efi/efi-device.c | 2 +-
> drivers/firmware/socfpga.c | 2 +-
> drivers/i2c/i2c.c | 4 +-
> drivers/mci/mci-core.c | 4 +-
> drivers/mfd/rave-sp.c | 2 +-
> drivers/mtd/core.c | 2 +-
> drivers/mtd/spi-nor/cadence-quadspi.c | 2 +-
> drivers/mtd/ubi/build.c | 2 +-
> drivers/mtd/ubi/vmt.c | 4 +-
> drivers/net/cpsw.c | 2 +-
> drivers/net/e1000/eeprom.c | 2 +-
> drivers/net/orion-gbe.c | 2 +-
> drivers/net/phy/mdio_bus.c | 2 +-
> drivers/net/phy/phy.c | 8 ++--
> drivers/nvmem/core.c | 2 +-
> drivers/nvmem/ocotp.c | 2 +-
> drivers/of/platform.c | 12 ++---
> drivers/pci/bus.c | 3 +-
> drivers/phy/phy-core.c | 2 +-
> drivers/pwm/core.c | 2 +-
> drivers/rtc/class.c | 2 +-
> drivers/spi/spi.c | 2 +-
> drivers/usb/core/usb.c | 5 +-
> drivers/usb/gadget/udc-core.c | 4 +-
> drivers/usb/musb/musb_dsps.c | 2 +-
> drivers/video/backlight.c | 2 +-
> drivers/video/fb.c | 2 +-
> drivers/w1/w1.c | 4 +-
> drivers/watchdog/wd_core.c | 2 +-
> fs/fs.c | 2 +-
> include/driver.h | 11 +++--
> net/eth.c | 2 +-
> 46 files changed, 113 insertions(+), 67 deletions(-)
>
> diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c
> index d4794cbac..207e1879c 100644
> --- a/arch/arm/mach-imx/iim.c
> +++ b/arch/arm/mach-imx/iim.c
> @@ -474,7 +474,7 @@ static int imx_iim_probe(struct device_d *dev)
>
> imx_iim = iim;
>
> - strcpy(iim->dev.name, "iim");
> + dev_set_name(&iim->dev, "iim");
> iim->dev.parent = dev;
> iim->dev.id = DEVICE_ID_SINGLE;
> ret = register_device(&iim->dev);
> diff --git a/arch/arm/mach-imx/include/mach/devices-imx51.h b/arch/arm/mach-imx/include/mach/devices-imx51.h
> index cccd8f461..66fe643f8 100644
> --- a/arch/arm/mach-imx/include/mach/devices-imx51.h
> +++ b/arch/arm/mach-imx/include/mach/devices-imx51.h
> @@ -81,7 +81,7 @@ static inline struct device_d *imx51_add_nand(struct imx_nand_platform_data *pda
> dev->resource = xzalloc(sizeof(struct resource) * ARRAY_SIZE(res));
> memcpy(dev->resource, res, sizeof(struct resource) * ARRAY_SIZE(res));
> dev->num_resources = ARRAY_SIZE(res);
> - strcpy(dev->name, "imx_nand");
> + dev_set_name(dev, "imx_nand");
> dev->id = DEVICE_ID_DYNAMIC;
> dev->platform_data = pdata;
>
> diff --git a/arch/arm/mach-imx/include/mach/devices-imx53.h b/arch/arm/mach-imx/include/mach/devices-imx53.h
> index 10caae8c9..27200a26d 100644
> --- a/arch/arm/mach-imx/include/mach/devices-imx53.h
> +++ b/arch/arm/mach-imx/include/mach/devices-imx53.h
> @@ -95,7 +95,7 @@ static inline struct device_d *imx53_add_nand(struct imx_nand_platform_data *pda
> dev->resource = xzalloc(sizeof(struct resource) * ARRAY_SIZE(res));
> memcpy(dev->resource, res, sizeof(struct resource) * ARRAY_SIZE(res));
> dev->num_resources = ARRAY_SIZE(res);
> - strcpy(dev->name, "imx_nand");
> + dev_set_name(dev, "imx_nand");
> dev->id = DEVICE_ID_DYNAMIC;
> dev->platform_data = pdata;
>
> diff --git a/arch/arm/mach-mxs/include/mach/devices.h b/arch/arm/mach-mxs/include/mach/devices.h
> index 5680d61c9..b212aa783 100644
> --- a/arch/arm/mach-mxs/include/mach/devices.h
> +++ b/arch/arm/mach-mxs/include/mach/devices.h
> @@ -26,7 +26,7 @@ static inline struct device_d *mxs_add_nand(unsigned long gpmi_base, unsigned lo
> dev->resource = xzalloc(sizeof(struct resource) * ARRAY_SIZE(res));
> memcpy(dev->resource, res, sizeof(struct resource) * ARRAY_SIZE(res));
> dev->num_resources = ARRAY_SIZE(res);
> - strcpy(dev->name, "mxs_nand");
> + dev_set_name(dev, "mxs_nand");
> dev->id = DEVICE_ID_DYNAMIC;
>
> platform_device_register(dev);
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> index b41fde991..01db73116 100644
> --- a/arch/arm/mach-mxs/ocotp.c
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -197,7 +197,7 @@ static int mxs_ocotp_probe(struct device_d *dev)
> priv->cdev.size = cpu_is_mx23() ? 128 : 160;
> priv->cdev.name = DRIVERNAME;
>
> - strcpy(priv->dev.name, "ocotp");
> + dev_set_name(&priv->dev, "ocotp");
> priv->dev.parent = dev;
> err = register_device(&priv->dev);
> if (err)
> diff --git a/arch/sandbox/board/console.c b/arch/sandbox/board/console.c
> index cf1781d15..006bbd1a6 100644
> --- a/arch/sandbox/board/console.c
> +++ b/arch/sandbox/board/console.c
> @@ -32,7 +32,7 @@ int barebox_register_console(int stdinfd, int stdoutfd)
> data = (struct linux_console_data *)(dev + 1);
>
> dev->platform_data = data;
> - strcpy(dev->name, "console");
> + dev_set_name(dev, "console");
> dev->id = DEVICE_ID_DYNAMIC;
>
> data->stdoutfd = stdoutfd;
> diff --git a/common/console.c b/common/console.c
> index 40c26b66d..47ccf2e54 100644
> --- a/common/console.c
> +++ b/common/console.c
> @@ -314,10 +314,10 @@ int console_register(struct console_device *newcdev)
>
> if (newcdev->devname) {
> dev->id = newcdev->devid;
> - strcpy(dev->name, newcdev->devname);
> + dev_set_name(dev, newcdev->devname);
> } else {
> dev->id = DEVICE_ID_DYNAMIC;
> - strcpy(dev->name, "cs");
> + dev_set_name(dev, "cs");
> }
>
> if (newcdev->dev)
> diff --git a/common/state/state.c b/common/state/state.c
> index 25d950211..55804a521 100644
> --- a/common/state/state.c
> +++ b/common/state/state.c
> @@ -179,7 +179,7 @@ static struct state *state_new(const char *name)
> int ret;
>
> state = xzalloc(sizeof(*state));
> - safe_strncpy(state->dev.name, name, MAX_DRIVER_NAME);
> + dev_set_name(&state->dev, name);
> state->name = state->dev.name;
> state->dev.id = DEVICE_ID_SINGLE;
> INIT_LIST_HEAD(&state->variables);
> diff --git a/drivers/aiodev/core.c b/drivers/aiodev/core.c
> index 79f935d71..cb53cfb7d 100644
> --- a/drivers/aiodev/core.c
> +++ b/drivers/aiodev/core.c
> @@ -115,7 +115,7 @@ int aiodevice_register(struct aiodevice *aiodev)
> aiodev->dev.id = DEVICE_ID_DYNAMIC;
> }
>
> - strcpy(aiodev->dev.name, aiodev->name);
> + dev_set_name(&aiodev->dev, aiodev->name);
>
> aiodev->dev.parent = aiodev->hwdev;
>
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index ae5df13c9..a8cd16835 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -200,7 +200,7 @@ struct amba_device *amba_device_alloc(const char *name, int id, resource_size_t
>
> dev = xzalloc(sizeof(*dev));
>
> - strcpy(dev->dev.name, name);
> + dev_set_name(&dev->dev, name);
> dev->dev.id = id;
> dev->res.start = base;
> dev->res.end = base + size - 1;
> diff --git a/drivers/ata/disk_ata_drive.c b/drivers/ata/disk_ata_drive.c
> index 5ebddbdec..11f7151e5 100644
> --- a/drivers/ata/disk_ata_drive.c
> +++ b/drivers/ata/disk_ata_drive.c
> @@ -325,10 +325,10 @@ int ata_port_register(struct ata_port *port)
> int ret;
>
> if (port->devname) {
> - strcpy(port->class_dev.name, port->devname);
> + dev_set_name(&port->class_dev, port->devname);
> port->class_dev.id = DEVICE_ID_SINGLE;
> } else {
> - strcpy(port->class_dev.name, "ata");
> + dev_set_name(&port->class_dev, "ata");
> port->class_dev.id = DEVICE_ID_DYNAMIC;
> }
>
> diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> index b889a4866..1038d20a1 100644
> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -32,7 +32,7 @@ int bus_register(struct bus_type *bus)
> return -EEXIST;
>
> bus->dev = xzalloc(sizeof(*bus->dev));
> - strcpy(bus->dev->name, bus->name);
> + dev_set_name(bus->dev, bus->name);
> bus->dev->id = DEVICE_ID_SINGLE;
>
> ret = register_device(bus->dev);
> diff --git a/drivers/base/driver.c b/drivers/base/driver.c
> index c43a4bde2..c25498bf4 100644
> --- a/drivers/base/driver.c
> +++ b/drivers/base/driver.c
> @@ -468,16 +468,57 @@ EXPORT_SYMBOL(dummy_probe);
>
> const char *dev_id(const struct device_d *dev)
> {
> - static char buf[MAX_DRIVER_NAME + 16];
> + static char *buf;
> + int err;
> +
> + if (buf)
> + free(buf);
Ugh, I just realized that original implementation of this function
didn't work right for constructs like
https://git.pengutronix.de/cgit/barebox/tree/drivers/mci/mci-core.c#n1826
because the result of calling dev_name() for one of the arguments
would get clobbered by the call to dev_name() inside of dev_info().
Switching to heap allocated memory only makes things worse.
Sascha, one solution for this that I can see is to just return
dev->name for the case of dev->id == DEVICE_ID_SINGLE and add a
"_name" field to struct device_d that can be lazily filled with device
name + ID string for dev->id != DEVICE_ID_SINGLE and returned as
result.
Thoughts?
Thanks,
Andrey Smirnov
>
> if (dev->id != DEVICE_ID_SINGLE)
> - snprintf(buf, sizeof(buf), FORMAT_DRIVER_NAME_ID, dev->name, dev->id);
> + err = asprintf(&buf, FORMAT_DRIVER_NAME_ID,
> + dev->name, dev->id);
> else
> - snprintf(buf, sizeof(buf), "%s", dev->name);
> + err = asprintf(&buf, "%s", dev->name);
> +
> + BUG_ON(err < 0);
>
> return buf;
> }
>
> +/**
> + * dev_set_name - set a device name
> + * @dev: device
> + * @fmt: format string for the device's name
> + *
> + * NOTE: This function expects dev->name to be free()-able, so extra
> + * precautions needs to be taken when mixing its usage with manual
> + * assignement of device_d.name.
> + */
> +int dev_set_name(struct device_d *dev, const char *fmt, ...)
> +{
> + va_list vargs;
> + int err;
> + /*
> + * Save old pointer in case we are overriding already set name
> + */
> + char *oldname = dev->name;
> +
> + va_start(vargs, fmt);
> + err = vasprintf(&dev->name, fmt, vargs);
> + va_end(vargs);
> +
> + /*
> + * Free old pointer, we do this after vasprintf call in case
> + * old device name was in one of vargs
> + */
> + free(oldname);
> +
> + WARN_ON(err < 0);
> +
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(dev_set_name);
> +
> static void devices_shutdown(void)
> {
> struct device_d *dev;
> diff --git a/drivers/base/resource.c b/drivers/base/resource.c
> index 6c2d7fed4..cb7105bf8 100644
> --- a/drivers/base/resource.c
> +++ b/drivers/base/resource.c
> @@ -27,7 +27,7 @@ struct device_d *device_alloc(const char *devname, int id)
> struct device_d *dev;
>
> dev = xzalloc(sizeof(*dev));
> - strcpy(dev->name, devname);
> + dev_set_name(dev, devname);
> dev->id = id;
>
> return dev;
> diff --git a/drivers/efi/efi-device.c b/drivers/efi/efi-device.c
> index 3a27323a0..b7dea7c82 100644
> --- a/drivers/efi/efi-device.c
> +++ b/drivers/efi/efi-device.c
> @@ -185,7 +185,7 @@ static struct efi_device *efi_add_device(efi_handle_t *handle, efi_guid_t **guid
> efidev->dev.info = efi_devinfo;
> efidev->devpath = devpath;
>
> - sprintf(efidev->dev.name, "handle-%p", handle);
> + dev_set_name(&efidev->dev, "handle-%p", handle);
>
> efidev->parent_handle = efi_find_parent(efidev->handle);
>
> diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
> index c1eae98ac..6d11da32a 100644
> --- a/drivers/firmware/socfpga.c
> +++ b/drivers/firmware/socfpga.c
> @@ -438,7 +438,7 @@ static int fpgamgr_probe(struct device_d *dev)
> dev_dbg(dev, "Registering FPGA firmware programmer\n");
>
> mgr->dev.id = DEVICE_ID_SINGLE;
> - strcpy(mgr->dev.name, "fpga");
> + dev_set_name(&mgr->dev, "fpga");
> mgr->dev.parent = dev;
> ret = register_device(&mgr->dev);
> if (ret)
> diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
> index 608f8289b..25e0fe7ad 100644
> --- a/drivers/i2c/i2c.c
> +++ b/drivers/i2c/i2c.c
> @@ -389,7 +389,7 @@ static struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
> int status;
>
> client = xzalloc(sizeof *client);
> - strcpy(client->dev.name, chip->type);
> + dev_set_name(&client->dev, chip->type);
> client->dev.type_data = client;
> client->dev.platform_data = chip->platform_data;
> client->dev.id = DEVICE_ID_DYNAMIC;
> @@ -588,7 +588,7 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
> }
>
> adapter->dev.id = adapter->nr;
> - strcpy(adapter->dev.name, "i2c");
> + dev_set_name(&adapter->dev, "i2c");
>
> ret = register_device(&adapter->dev);
> if (ret)
> diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
> index c6b4e02cb..c8d1d5e16 100644
> --- a/drivers/mci/mci-core.c
> +++ b/drivers/mci/mci-core.c
> @@ -1802,10 +1802,10 @@ int mci_register(struct mci_host *host)
> mci->host = host;
>
> if (host->devname) {
> - strcpy(mci->dev.name, host->devname);
> + dev_set_name(&mci->dev, host->devname);
> mci->dev.id = DEVICE_ID_SINGLE;
> } else {
> - strcpy(mci->dev.name, "mci");
> + dev_set_name(&mci->dev, "mci");
> mci->dev.id = DEVICE_ID_DYNAMIC;
> }
>
> diff --git a/drivers/mfd/rave-sp.c b/drivers/mfd/rave-sp.c
> index c61443218..40fce077c 100644
> --- a/drivers/mfd/rave-sp.c
> +++ b/drivers/mfd/rave-sp.c
> @@ -789,7 +789,7 @@ static int rave_sp_add_params(struct rave_sp *sp)
> int ret;
>
> dev->parent = sp->serdev->dev;
> - strcpy(dev->name, "sp");
> + dev_set_name(dev, "sp");
> dev->id = DEVICE_ID_SINGLE;
>
> ret = register_device(dev);
> diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
> index 15fe9ce79..56e85b3d8 100644
> --- a/drivers/mtd/core.c
> +++ b/drivers/mtd/core.c
> @@ -607,7 +607,7 @@ int add_mtd_device(struct mtd_info *mtd, const char *devname, int device_id)
>
> if (!devname)
> devname = "mtd";
> - strcpy(mtd->class_dev.name, devname);
> + dev_set_name(&mtd->class_dev, devname);
> mtd->class_dev.id = device_id;
> if (mtd->parent)
> mtd->class_dev.parent = mtd->parent;
> diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
> index 626966818..ed5377bd4 100644
> --- a/drivers/mtd/spi-nor/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/cadence-quadspi.c
> @@ -1051,7 +1051,7 @@ static int cqspi_setup_flash(struct device_d *dev,
> if (np) {
> nor->dev = xzalloc(sizeof(*nor->dev));
>
> - strcpy(nor->dev->name, np->name);
> + dev_set_name(nor->dev, np->name);
>
> nor->dev->device_node = np;
> nor->dev->id = DEVICE_ID_SINGLE;
> diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
> index 536077ebf..493c778c3 100644
> --- a/drivers/mtd/ubi/build.c
> +++ b/drivers/mtd/ubi/build.c
> @@ -157,7 +157,7 @@ static int uif_init(struct ubi_device *ubi, int *ref)
> *ref = 0;
> sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
>
> - sprintf(ubi->dev.name, "%s.ubi", ubi->mtd->cdev.name);
> + dev_set_name(&ubi->dev, "%s.ubi", ubi->mtd->cdev.name);
> ubi->dev.id = DEVICE_ID_SINGLE;
> ubi->dev.parent = &ubi->mtd->class_dev;
>
> diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
> index 617704821..99da79171 100644
> --- a/drivers/mtd/ubi/vmt.c
> +++ b/drivers/mtd/ubi/vmt.c
> @@ -145,7 +145,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
> vol->last_eb_bytes = vol->usable_leb_size;
> }
>
> - sprintf(vol->dev.name, "%s.%s", dev_name(&ubi->dev), vol->name);
> + dev_set_name(&vol->dev, "%s.%s", dev_name(&ubi->dev), vol->name);
> vol->dev.id = DEVICE_ID_SINGLE;
> vol->dev.parent = &ubi->dev;
> err = register_device(&vol->dev);
> @@ -443,7 +443,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
>
> dbg_gen("add volume");
>
> - sprintf(vol->dev.name, "%s.%s", dev_name(&ubi->dev), vol->name);
> + dev_set_name(&vol->dev, "%s.%s", dev_name(&ubi->dev), vol->name);
> vol->dev.id = DEVICE_ID_SINGLE;
> vol->dev.parent = &ubi->dev;
> err = register_device(&vol->dev);
> diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
> index 3d3939cfa..c6fc21dc5 100644
> --- a/drivers/net/cpsw.c
> +++ b/drivers/net/cpsw.c
> @@ -916,7 +916,7 @@ static int cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
> if (ret)
> goto err_out;
>
> - sprintf(dev->name, "cpsw-slave");
> + dev_set_name(dev, "cpsw-slave");
> dev->id = slave->slave_num;
> dev->parent = priv->dev;
> ret = register_device(dev);
> diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c
> index dda022e05..180b32ede 100644
> --- a/drivers/net/e1000/eeprom.c
> +++ b/drivers/net/e1000/eeprom.c
> @@ -1529,7 +1529,7 @@ int e1000_register_invm(struct e1000_hw *hw)
> if (ret < 0)
> return ret;
>
> - strcpy(hw->invm.dev.name, "invm");
> + dev_set_name(&hw->invm.dev, "invm");
> hw->invm.dev.id = hw->dev->id;
> hw->invm.dev.parent = hw->dev;
> ret = register_device(&hw->invm.dev);
> diff --git a/drivers/net/orion-gbe.c b/drivers/net/orion-gbe.c
> index e6bd75768..431ec5c31 100644
> --- a/drivers/net/orion-gbe.c
> +++ b/drivers/net/orion-gbe.c
> @@ -462,7 +462,7 @@ static int port_probe(struct device_d *parent, struct port_priv *port)
> reg |= RGMII_ENABLE;
> writel(reg, port->regs + PORT_SC1);
>
> - snprintf(dev->name, MAX_DRIVER_NAME, "%08x.ethernet-port", (u32)gbe->regs);
> + dev_set_name(dev, "%08x.ethernet-port", (u32)gbe->regs);
> dev->id = port->portno;
> dev->parent = parent;
> dev->device_node = port->np;
> diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
> index 7d53bcc3d..177d54863 100644
> --- a/drivers/net/phy/mdio_bus.c
> +++ b/drivers/net/phy/mdio_bus.c
> @@ -222,7 +222,7 @@ int mdiobus_register(struct mii_bus *bus)
>
> bus->dev.priv = bus;
> bus->dev.id = DEVICE_ID_DYNAMIC;
> - strcpy(bus->dev.name, "miibus");
> + dev_set_name(&bus->dev, "miibus");
> bus->dev.parent = bus->parent;
> bus->dev.detect = mdiobus_detect;
>
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index 42dcad906..19d458e07 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -176,12 +176,12 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id)
> phydev->dev.bus = &mdio_bus_type;
>
> if (bus) {
> - sprintf(phydev->dev.name, "mdio%d-phy%02x",
> - phydev->bus->dev.id,
> - phydev->addr);
> + dev_set_name(&phydev->dev, "mdio%d-phy%02x",
> + phydev->bus->dev.id,
> + phydev->addr);
> phydev->dev.id = DEVICE_ID_SINGLE;
> } else {
> - sprintf(phydev->dev.name, "fixed-phy");
> + dev_set_name(&phydev->dev, "fixed-phy");
> phydev->dev.id = DEVICE_ID_DYNAMIC;
> }
>
> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
> index c0f61f453..63c0f997b 100644
> --- a/drivers/nvmem/core.c
> +++ b/drivers/nvmem/core.c
> @@ -199,7 +199,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
> nvmem->read_only = of_property_read_bool(np, "read-only") |
> config->read_only;
>
> - safe_strncpy(nvmem->dev.name, config->name, MAX_DRIVER_NAME);
> + dev_set_name(&nvmem->dev, config->name);
> nvmem->dev.id = DEVICE_ID_DYNAMIC;
>
> dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
> diff --git a/drivers/nvmem/ocotp.c b/drivers/nvmem/ocotp.c
> index c2d2982ee..0d07da280 100644
> --- a/drivers/nvmem/ocotp.c
> +++ b/drivers/nvmem/ocotp.c
> @@ -531,7 +531,7 @@ static int imx_ocotp_probe(struct device_d *dev)
> if (IS_ERR(priv->clk))
> return PTR_ERR(priv->clk);
>
> - strcpy(priv->dev.name, "ocotp");
> + dev_set_name(&priv->dev, "ocotp");
> priv->dev.parent = dev;
> register_device(&priv->dev);
>
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index c9157cdd7..4fd3ce2b7 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -68,12 +68,12 @@ static void of_device_make_bus_id(struct device_d *dev)
> reg = of_get_property(np, "dcr-reg", NULL);
> if (reg) {
> #ifdef CONFIG_PPC_DCR_NATIVE
> - snprintf(dev->name, MAX_DRIVER_NAME, "d%x.%s", *reg, name);
> + dev_set_name(dev, "d%x.%s", *reg, name);
> #else /* CONFIG_PPC_DCR_NATIVE */
> u64 addr = of_translate_dcr_address(np, *reg, NULL);
> if (addr != OF_BAD_ADDR) {
> - snprintf(dev->name, MAX_DRIVER_NAME, "D%llx.%s",
> - (unsigned long long)addr, name);
> + dev_set_name(dev, "D%llx.%s",
> + (unsigned long long)addr, name);
> free(name);
> return;
> }
> @@ -96,8 +96,8 @@ static void of_device_make_bus_id(struct device_d *dev)
> addr = OF_BAD_ADDR;
> }
> if (addr != OF_BAD_ADDR) {
> - snprintf(dev->name, MAX_DRIVER_NAME, "%llx.%s",
> - (unsigned long long)addr, name);
> + dev_set_name(dev, "%llx.%s",
> + (unsigned long long)addr, name);
> free(name);
> return;
> }
> @@ -106,7 +106,7 @@ static void of_device_make_bus_id(struct device_d *dev)
> /*
> * No BusID, use the node name and add a globally incremented counter
> */
> - snprintf(dev->name, MAX_DRIVER_NAME, "%s.%d", name, bus_no_reg_magic++);
> + dev_set_name(dev, "%s.%d", name, bus_no_reg_magic++);
> free(name);
> }
>
> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
> index 201675b48..ac1562330 100644
> --- a/drivers/pci/bus.c
> +++ b/drivers/pci/bus.c
> @@ -87,8 +87,7 @@ int pci_register_device(struct pci_dev *pdev)
> struct device_d *dev = &pdev->dev;
> int ret;
>
> - snprintf(dev->name, MAX_DRIVER_NAME, "pci-%04x:%04x.",
> - pdev->vendor, pdev->device);
> + dev_set_name(dev, "pci-%04x:%04x.", pdev->vendor, pdev->device);
> dev->bus = &pci_bus;
> dev->id = DEVICE_ID_DYNAMIC;
>
> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
> index 1b6a9f7b1..9d6288fc0 100644
> --- a/drivers/phy/phy-core.c
> +++ b/drivers/phy/phy-core.c
> @@ -46,7 +46,7 @@ struct phy *phy_create(struct device_d *dev, struct device_node *node,
>
> id = phy_ida++;
>
> - snprintf(phy->dev.name, MAX_DRIVER_NAME, "phy");
> + dev_set_name(&phy->dev, "phy");
> phy->dev.id = id;
> phy->dev.parent = dev;
> phy->dev.device_node = node ?: dev->device_node;
> diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
> index 80fade061..c8016999f 100644
> --- a/drivers/pwm/core.c
> +++ b/drivers/pwm/core.c
> @@ -89,7 +89,7 @@ int pwmchip_add(struct pwm_chip *chip, struct device_d *dev)
> pwm->chip = chip;
> pwm->hwdev = dev;
>
> - strcpy(pwm->dev.name, chip->devname);
> + dev_set_name(&pwm->dev, chip->devname);
> pwm->dev.id = DEVICE_ID_SINGLE;
> pwm->dev.parent = dev;
>
> diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
> index 8b047a638..5b58271c0 100644
> --- a/drivers/rtc/class.c
> +++ b/drivers/rtc/class.c
> @@ -67,7 +67,7 @@ int rtc_register(struct rtc_device *rtcdev)
> return -EINVAL;
>
> dev->id = DEVICE_ID_DYNAMIC;
> - strcpy(dev->name, "rtc");
> + dev_set_name(dev, "rtc");
> if (rtcdev->dev)
> dev->parent = rtcdev->dev;
> platform_device_register(dev);
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 5650098a0..25bb98879 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -76,7 +76,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
> proxy->bits_per_word = chip->bits_per_word ? chip->bits_per_word : 8;
> proxy->dev.platform_data = chip->platform_data;
> proxy->dev.bus = &spi_bus;
> - strcpy(proxy->dev.name, chip->name);
> + dev_set_name(&proxy->dev, chip->name);
> /* allocate a free id for this chip */
> proxy->dev.id = DEVICE_ID_DYNAMIC;
> proxy->dev.type_data = proxy;
> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> index 70ded6ded..0ee8808a6 100644
> --- a/drivers/usb/core/usb.c
> +++ b/drivers/usb/core/usb.c
> @@ -431,9 +431,10 @@ int usb_new_device(struct usb_device *dev)
> dev->serial, sizeof(dev->serial));
>
> if (parent) {
> - sprintf(dev->dev.name, "%s-%d", parent->dev.name, dev->portnr - 1);
> + dev_set_name(&dev->dev, "%s-%d", parent->dev.name,
> + dev->portnr - 1);
> } else {
> - sprintf(dev->dev.name, "usb%d", dev->host->busnum);
> + dev_set_name(&dev->dev, "usb%d", dev->host->busnum);
> }
>
> dev->dev.id = DEVICE_ID_SINGLE;
> diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
> index ed99b53df..e35745609 100644
> --- a/drivers/usb/gadget/udc-core.c
> +++ b/drivers/usb/gadget/udc-core.c
> @@ -179,7 +179,7 @@ int usb_add_gadget_udc_release(struct device_d *parent, struct usb_gadget *gadge
> if (!udc)
> goto err1;
>
> - strcpy(gadget->dev.name, "usbgadget");
> + dev_set_name(&gadget->dev, "usbgadget");
> gadget->dev.id = DEVICE_ID_SINGLE;
> gadget->dev.parent = parent;
>
> @@ -198,7 +198,7 @@ int usb_add_gadget_udc_release(struct device_d *parent, struct usb_gadget *gadge
> dev_add_param_string(&gadget->dev, "productname", NULL, NULL,
> &gadget->productname, NULL);
>
> - strcpy(udc->dev.name, "udc");
> + dev_set_name(&udc->dev, "udc");
> udc->dev.id = DEVICE_ID_DYNAMIC;
>
> udc->gadget = gadget;
> diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
> index 431b97ea9..5fe3bcb7c 100644
> --- a/drivers/usb/musb/musb_dsps.c
> +++ b/drivers/usb/musb/musb_dsps.c
> @@ -333,7 +333,7 @@ static int dsps_register_otg_device(struct dsps_glue *glue)
> {
> int ret;
>
> - strcpy(glue->otg_dev.name, "otg");
> + dev_set_name(&glue->otg_dev, "otg");
> glue->otg_dev.id = DEVICE_ID_DYNAMIC,
> glue->otg_dev.parent = glue->dev;
>
> diff --git a/drivers/video/backlight.c b/drivers/video/backlight.c
> index 30d52fcb6..3913d1c4c 100644
> --- a/drivers/video/backlight.c
> +++ b/drivers/video/backlight.c
> @@ -71,7 +71,7 @@ int backlight_register(struct backlight_device *bl)
> {
> int ret;
>
> - sprintf(bl->dev.name, "backlight");
> + dev_set_name(&bl->dev, "backlight");
> bl->dev.id = DEVICE_ID_DYNAMIC;
>
> ret = register_device(&bl->dev);
> diff --git a/drivers/video/fb.c b/drivers/video/fb.c
> index c9d184d50..72f33a6db 100644
> --- a/drivers/video/fb.c
> +++ b/drivers/video/fb.c
> @@ -309,7 +309,7 @@ int register_framebuffer(struct fb_info *info)
> dev->id = id;
> dev->info = fb_info;
>
> - sprintf(dev->name, "fb");
> + dev_set_name(dev, "fb");
>
> ret = register_device(&info->dev);
> if (ret)
> diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
> index ff573860e..694ffa853 100644
> --- a/drivers/w1/w1.c
> +++ b/drivers/w1/w1.c
> @@ -423,7 +423,7 @@ static int w1_device_register(struct w1_bus *bus, struct w1_device *dev)
> char str[18];
> int ret;
>
> - sprintf(dev->dev.name, "w1-%x-", dev->fid);
> + dev_set_name(&dev->dev, "w1-%x-", dev->fid);
> dev->dev.id = DEVICE_ID_DYNAMIC;
> dev->dev.bus = &w1_bustype;
> dev->bus = bus;
> @@ -619,7 +619,7 @@ int w1_bus_register(struct w1_bus *bus)
>
> list_add_tail(&bus->list, &w1_buses);
>
> - strcpy(bus->dev.name, "w1_bus");
> + dev_set_name(&bus->dev, "w1_bus");
> bus->dev.id = DEVICE_ID_DYNAMIC;
> bus->dev.parent = bus->parent;
>
> diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
> index 56e8626cb..e6e5ddecd 100644
> --- a/drivers/watchdog/wd_core.c
> +++ b/drivers/watchdog/wd_core.c
> @@ -104,7 +104,7 @@ static int watchdog_register_dev(struct watchdog *wd, const char *name, int id)
> {
> wd->dev.parent = wd->hwdev;
> wd->dev.id = id;
> - strncpy(wd->dev.name, name, MAX_DRIVER_NAME);
> + dev_set_name(&wd->dev, name);
>
> return register_device(&wd->dev);
> }
> diff --git a/fs/fs.c b/fs/fs.c
> index d76d82914..57eaaf585 100644
> --- a/fs/fs.c
> +++ b/fs/fs.c
> @@ -2757,7 +2757,7 @@ int mount(const char *device, const char *fsname, const char *pathname,
>
> fsdev = xzalloc(sizeof(struct fs_device_d));
> fsdev->backingstore = xstrdup(device);
> - safe_strncpy(fsdev->dev.name, fsname, MAX_DRIVER_NAME);
> + dev_set_name(&fsdev->dev, fsname);
> fsdev->dev.id = get_free_deviceid(fsdev->dev.name);
> fsdev->dev.bus = &fs_bus;
> fsdev->options = xstrdup(fsoptions);
> diff --git a/include/driver.h b/include/driver.h
> index 1b61f2066..5a67757a2 100644
> --- a/include/driver.h
> +++ b/include/driver.h
> @@ -23,7 +23,6 @@
> #include <linux/ioport.h>
> #include <of.h>
>
> -#define MAX_DRIVER_NAME 32
> #define FORMAT_DRIVER_NAME_ID "%s%d"
>
> #include <param.h>
> @@ -40,8 +39,12 @@ struct platform_device_id {
> struct device_d {
> /*! This member (and 'type' described below) is used to match with a
> * driver. This is a descriptive name and could be MPC5XXX_ether or
> - * imx_serial. */
> - char name[MAX_DRIVER_NAME];
> + * imx_serial.
> + *
> + * NOTE: dev_set_name() can be used to assign device name using
> + * printf-like format strings
> + */
> + char *name;
> /*! The id is used to uniquely identify a device in the system. The id
> * will show up under /dev/ as the device's name. Usually this is
> * something like eth0 or nor0. */
> @@ -177,6 +180,8 @@ static inline const char *dev_name(const struct device_d *dev)
> return dev_id(dev);
> }
>
> +int dev_set_name(struct device_d *dev, const char *fmt, ...);
> +
> /*
> * get resource 'num' for a device
> */
> diff --git a/net/eth.c b/net/eth.c
> index 9dc441195..36260478d 100644
> --- a/net/eth.c
> +++ b/net/eth.c
> @@ -363,7 +363,7 @@ int eth_register(struct eth_device *edev)
> return -1;
> }
>
> - strcpy(edev->dev.name, "eth");
> + dev_set_name(&edev->dev, "eth");
>
> if (edev->parent)
> edev->dev.parent = edev->parent;
> --
> 2.17.1
>
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 07/17] drivers: Introduce dev_set_name()
2018-10-09 17:37 ` [PATCH v2 07/17] drivers: Introduce dev_set_name() Andrey Smirnov
2018-10-10 2:57 ` Andrey Smirnov
@ 2018-10-10 9:41 ` Lucas Stach
2018-10-10 15:33 ` Andrey Smirnov
1 sibling, 1 reply; 28+ messages in thread
From: Lucas Stach @ 2018-10-10 9:41 UTC (permalink / raw)
To: Andrey Smirnov, barebox
Hi Andrey,
Am Dienstag, den 09.10.2018, 10:37 -0700 schrieb Andrey Smirnov:
> In order to allow device names that are longer than MAX_DRIVER_NAME,
> port Linux kernel function of the same name, and convert all of the
> code to use it.
This patch doesn't apply cleanly on barebox master or next due to the
thing being patched in rave-sp.c not being present in upstream. You
probably generated this patchset with some local changes applied.
The fix is easy by dropping the rave-sp.c chunk of the patch. Maybe
Sascha can just fix this up while applying.
Regards,
Lucas
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 07/17] drivers: Introduce dev_set_name()
2018-10-10 9:41 ` Lucas Stach
@ 2018-10-10 15:33 ` Andrey Smirnov
0 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-10 15:33 UTC (permalink / raw)
To: Lucas Stach; +Cc: Barebox List
On Wed, Oct 10, 2018 at 2:41 AM Lucas Stach <l.stach@pengutronix.de> wrote:
>
> Hi Andrey,
>
> Am Dienstag, den 09.10.2018, 10:37 -0700 schrieb Andrey Smirnov:
> > In order to allow device names that are longer than MAX_DRIVER_NAME,
> > port Linux kernel function of the same name, and convert all of the
> > code to use it.
>
> This patch doesn't apply cleanly on barebox master or next due to the
> thing being patched in rave-sp.c not being present in upstream. You
> probably generated this patchset with some local changes applied.
>
> The fix is easy by dropping the rave-sp.c chunk of the patch. Maybe
> Sascha can just fix this up while applying.
>
Oh, didn't realized that, my bad. I'll have to do a v3 to fix the
dev_id() issue anyway, so I'll make sure to fix this other problem as
well.
Thanks,
Andrey Smirnov
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 09/17] of: Port latest of_device_make_bus_id() implementation
2018-10-09 17:37 ` [PATCH v2 09/17] of: Port latest of_device_make_bus_id() implementation Andrey Smirnov
@ 2018-10-10 16:51 ` Lucas Stach
2018-10-10 16:54 ` Andrey Smirnov
0 siblings, 1 reply; 28+ messages in thread
From: Lucas Stach @ 2018-10-10 16:51 UTC (permalink / raw)
To: Andrey Smirnov, barebox
Hi Andrey,
Am Dienstag, den 09.10.2018, 10:37 -0700 schrieb Andrey Smirnov:
> Code implementing of_device_make_bus_id() in Barebox uses rather old
> implementation from Linux kernel and has a very significan limitation
> in that it will produce identical names for different DT nodes that
> happen to have the same node name as well as "reg" property.
>
> > One such example, that tirggered this change, is "switch@0" nodes that
> can be found in dts/src/arm/vf610-zii-dev-rev-c.dts
>
> This commit replaces original code with the current Linux kernel
> implementation that traverses DT hierarchy from leaf node to its root
> concatenating node names in the process.
I think this change is what is breaking the imx_thermal driver here.
This is a bad interaction between the AIODEV framework using the
hwdev->device_node->name as the device name for the aoidev and the
parent device getting the same name with this change. Before this
change the tempmon platform device (which doesn't has an address by
itself) would get a made up bus_no_reg_magic appended.
Due to both devices having the same name, the device registration for
the aiodev now fails. I've fixed it locally by not using the node name
in the AIODEV framework, but you may prefer to fix this differently.
Something to keep in mind for v3 of this series.
Regards,
Lucas
> > Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> ---
> drivers/of/platform.c | 80 ++++++++++++-------------------------------
> 1 file changed, 22 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 4fd3ce2b7..17052f419 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -43,71 +43,35 @@ EXPORT_SYMBOL(of_find_device_by_node);
> * of_device_make_bus_id - Use the device node data to assign a unique name
> * @dev: pointer to device structure that is linked to a device tree node
> *
> - * This routine will first try using either the dcr-reg or the reg property
> - * value to derive a unique name. As a last resort it will use the node
> - * name followed by a unique number.
> + * This routine will first try using the translated bus address to
> + * derive a unique name. If it cannot, then it will prepend names from
> + * parent nodes until a unique name can be derived.
> */
> static void of_device_make_bus_id(struct device_d *dev)
> {
> > - static int bus_no_reg_magic;
> > - struct device_node *np = dev->device_node;
> > - const __be32 *reg, *addrp;
> > + struct device_node *node = dev->device_node;
> > + const __be32 *reg;
> > u64 addr;
> > - char *name, *at;
> -
> > - name = xstrdup(np->name);
> > - at = strchr(name, '@');
> > - if (at)
> > - *at = '\0';
> -
> -#ifdef CONFIG_PPC_DCR
> > - /*
> > - * If it's a DCR based device, use 'd' for native DCRs
> > - * and 'D' for MMIO DCRs.
> > - */
> > - reg = of_get_property(np, "dcr-reg", NULL);
> > - if (reg) {
> -#ifdef CONFIG_PPC_DCR_NATIVE
> > - dev_set_name(dev, "d%x.%s", *reg, name);
> -#else /* CONFIG_PPC_DCR_NATIVE */
> > - u64 addr = of_translate_dcr_address(np, *reg, NULL);
> > - if (addr != OF_BAD_ADDR) {
> > - dev_set_name(dev, "D%llx.%s",
> > - (unsigned long long)addr, name);
> > - free(name);
> > - return;
> > - }
> -#endif /* !CONFIG_PPC_DCR_NATIVE */
> > - }
> -#endif /* CONFIG_PPC_DCR */
> -
> > - /*
> > - * For MMIO, get the physical address
> > - */
> > - reg = of_get_property(np, "reg", NULL);
> > - if (reg) {
> > - if (of_can_translate_address(np)) {
> > - addr = of_translate_address(np, reg);
> > - } else {
> > - addrp = of_get_address(np, 0, NULL, NULL);
> > - if (addrp)
> > - addr = of_read_number(addrp, 1);
> > - else
> > - addr = OF_BAD_ADDR;
> > - }
> > - if (addr != OF_BAD_ADDR) {
> > - dev_set_name(dev, "%llx.%s",
> > - (unsigned long long)addr, name);
> > - free(name);
> +
> > + /* Construct the name, using parent nodes if necessary to ensure uniqueness */
> > + while (node->parent) {
> > + /*
> > + * If the address can be translated, then that is as much
> > + * uniqueness as we need. Make it the first component and return
> > + */
> > + reg = of_get_property(node, "reg", NULL);
> > + if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) {
> > + dev_set_name(dev, dev->name ? "%llx.%s:%s" : "%llx.%s",
> > + (unsigned long long)addr, node->name,
> > + dev->name);
> > return;
> > }
> > - }
>
> > - /*
> > - * No BusID, use the node name and add a globally incremented counter
> > - */
> > - dev_set_name(dev, "%s.%d", name, bus_no_reg_magic++);
> > - free(name);
> > + /* format arguments only used if dev_name() resolves to NULL */
> > + dev_set_name(dev, dev->name ? "%s:%s" : "%s",
> > + kbasename(node->full_name), dev->name);
> > + node = node->parent;
> > + }
> }
>
> /**
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 09/17] of: Port latest of_device_make_bus_id() implementation
2018-10-10 16:51 ` Lucas Stach
@ 2018-10-10 16:54 ` Andrey Smirnov
0 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-10 16:54 UTC (permalink / raw)
To: Lucas Stach; +Cc: Barebox List
On Wed, Oct 10, 2018 at 9:52 AM Lucas Stach <l.stach@pengutronix.de> wrote:
>
> Hi Andrey,
>
> Am Dienstag, den 09.10.2018, 10:37 -0700 schrieb Andrey Smirnov:
> > Code implementing of_device_make_bus_id() in Barebox uses rather old
> > implementation from Linux kernel and has a very significan limitation
> > in that it will produce identical names for different DT nodes that
> > happen to have the same node name as well as "reg" property.
> >
> > > One such example, that tirggered this change, is "switch@0" nodes that
> > can be found in dts/src/arm/vf610-zii-dev-rev-c.dts
> >
> > This commit replaces original code with the current Linux kernel
> > implementation that traverses DT hierarchy from leaf node to its root
> > concatenating node names in the process.
>
> I think this change is what is breaking the imx_thermal driver here.
>
> This is a bad interaction between the AIODEV framework using the
> hwdev->device_node->name as the device name for the aoidev and the
> parent device getting the same name with this change. Before this
> change the tempmon platform device (which doesn't has an address by
> itself) would get a made up bus_no_reg_magic appended.
>
> Due to both devices having the same name, the device registration for
> the aiodev now fails. I've fixed it locally by not using the node name
> in the AIODEV framework, but you may prefer to fix this differently.
> Something to keep in mind for v3 of this series.
>
Thanks for finding this out! Added on my things to fix in v3 list.
Thanks,
Andrey Smirnov
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 02/17] clocksource: Add ARM global timer support
2018-10-09 17:37 ` [PATCH v2 02/17] clocksource: Add ARM global timer support Andrey Smirnov
@ 2018-10-11 8:28 ` Sascha Hauer
0 siblings, 0 replies; 28+ messages in thread
From: Sascha Hauer @ 2018-10-11 8:28 UTC (permalink / raw)
To: Andrey Smirnov; +Cc: barebox
On Tue, Oct 09, 2018 at 10:37:50AM -0700, Andrey Smirnov wrote:
> Port corresponding Linux kernel driver. Currently VFxxx SoC is the
> intended consumer because it doesn't include common i.MX GPT block
> used as clocksource by other i.MX SoCs.
>
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> ---
> drivers/clocksource/Kconfig | 4 +
> drivers/clocksource/Makefile | 1 +
> drivers/clocksource/arm_global_timer.c | 113 +++++++++++++++++++++++++
> 3 files changed, 118 insertions(+)
> create mode 100644 drivers/clocksource/arm_global_timer.c
>
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 3d63f7ff1..6a6c9362a 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -70,3 +70,7 @@ config CLOCKSOURCE_ARMV8_TIMER
> bool
> default y
> depends on ARM && CPU_64v8
> +
> +config CLOCKSOURCE_ARM_GLOBAL_TIMER
> + bool
Whitespaces instead of tab here.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 08/17] linux: string: Port kbasename()
2018-10-09 17:37 ` [PATCH v2 08/17] linux: string: Port kbasename() Andrey Smirnov
@ 2018-10-11 8:31 ` Sascha Hauer
2018-10-13 20:47 ` Andrey Smirnov
0 siblings, 1 reply; 28+ messages in thread
From: Sascha Hauer @ 2018-10-11 8:31 UTC (permalink / raw)
To: Andrey Smirnov; +Cc: barebox
On Tue, Oct 09, 2018 at 10:37:56AM -0700, Andrey Smirnov wrote:
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> ---
> include/linux/string.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/include/linux/string.h b/include/linux/string.h
> index 3418b4fbe..c9823dab8 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -111,6 +111,18 @@ extern char *strim(char *);
>
> void *memchr_inv(const void *start, int c, size_t bytes);
>
> +/**
> + * kbasename - return the last part of a pathname.
> + *
> + * @path: path to extract the filename from.
> + */
> +static inline const char *kbasename(const char *path)
> +{
> + const char *tail = strrchr(path, '/');
> + return tail ? tail + 1 : path;
> +}
We already have basename() and posix_basename(). How does this one
differ or could this be an alias for one of them?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 07/17] drivers: Introduce dev_set_name()
2018-10-10 2:57 ` Andrey Smirnov
@ 2018-10-11 8:56 ` Sascha Hauer
2018-10-12 2:01 ` Andrey Smirnov
0 siblings, 1 reply; 28+ messages in thread
From: Sascha Hauer @ 2018-10-11 8:56 UTC (permalink / raw)
To: Andrey Smirnov; +Cc: Barebox List
On Tue, Oct 09, 2018 at 07:57:27PM -0700, Andrey Smirnov wrote:
> On Tue, Oct 9, 2018 at 10:38 AM Andrey Smirnov <andrew.smirnov@gmail.com> wrote:
> > diff --git a/drivers/base/driver.c b/drivers/base/driver.c
> > index c43a4bde2..c25498bf4 100644
> > --- a/drivers/base/driver.c
> > +++ b/drivers/base/driver.c
> > @@ -468,16 +468,57 @@ EXPORT_SYMBOL(dummy_probe);
> >
> > const char *dev_id(const struct device_d *dev)
> > {
> > - static char buf[MAX_DRIVER_NAME + 16];
> > + static char *buf;
> > + int err;
> > +
> > + if (buf)
> > + free(buf);
>
> Ugh, I just realized that original implementation of this function
> didn't work right for constructs like
>
> https://git.pengutronix.de/cgit/barebox/tree/drivers/mci/mci-core.c#n1826
>
> because the result of calling dev_name() for one of the arguments
> would get clobbered by the call to dev_name() inside of dev_info().
> Switching to heap allocated memory only makes things worse.
>
> Sascha, one solution for this that I can see is to just return
> dev->name for the case of dev->id == DEVICE_ID_SINGLE and add a
> "_name" field to struct device_d that can be lazily filled with device
> name + ID string for dev->id != DEVICE_ID_SINGLE and returned as
> result.
Not sure if "name" and "_name" are good names, but generally I think we
can do it that way.
Could you split this patch up into two and in the first one just add a
dev_set_name function which sprintf() into the string array and converts
the users and only in the second patch do the conversion to an allocated
dev->name?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 07/17] drivers: Introduce dev_set_name()
2018-10-11 8:56 ` Sascha Hauer
@ 2018-10-12 2:01 ` Andrey Smirnov
0 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-12 2:01 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Barebox List
On Thu, Oct 11, 2018 at 1:56 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
>
> On Tue, Oct 09, 2018 at 07:57:27PM -0700, Andrey Smirnov wrote:
> > On Tue, Oct 9, 2018 at 10:38 AM Andrey Smirnov <andrew.smirnov@gmail.com> wrote:
> > > diff --git a/drivers/base/driver.c b/drivers/base/driver.c
> > > index c43a4bde2..c25498bf4 100644
> > > --- a/drivers/base/driver.c
> > > +++ b/drivers/base/driver.c
> > > @@ -468,16 +468,57 @@ EXPORT_SYMBOL(dummy_probe);
> > >
> > > const char *dev_id(const struct device_d *dev)
> > > {
> > > - static char buf[MAX_DRIVER_NAME + 16];
> > > + static char *buf;
> > > + int err;
> > > +
> > > + if (buf)
> > > + free(buf);
> >
> > Ugh, I just realized that original implementation of this function
> > didn't work right for constructs like
> >
> > https://git.pengutronix.de/cgit/barebox/tree/drivers/mci/mci-core.c#n1826
> >
> > because the result of calling dev_name() for one of the arguments
> > would get clobbered by the call to dev_name() inside of dev_info().
> > Switching to heap allocated memory only makes things worse.
> >
> > Sascha, one solution for this that I can see is to just return
> > dev->name for the case of dev->id == DEVICE_ID_SINGLE and add a
> > "_name" field to struct device_d that can be lazily filled with device
> > name + ID string for dev->id != DEVICE_ID_SINGLE and returned as
> > result.
>
> Not sure if "name" and "_name" are good names, but generally I think we
> can do it that way.
OK, I'll call them "name" and "unique_name" correspondingly them and
let you fix it up when applying if you have something better in mind.
> Could you split this patch up into two and in the first one just add a
> dev_set_name function which sprintf() into the string array and converts
> the users and only in the second patch do the conversion to an allocated
> dev->name?
>
Sure, sounds good. Will do in v3.
Thanks,
Andrey Smirnov
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 08/17] linux: string: Port kbasename()
2018-10-11 8:31 ` Sascha Hauer
@ 2018-10-13 20:47 ` Andrey Smirnov
0 siblings, 0 replies; 28+ messages in thread
From: Andrey Smirnov @ 2018-10-13 20:47 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Barebox List
On Thu, Oct 11, 2018 at 1:31 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
>
> On Tue, Oct 09, 2018 at 10:37:56AM -0700, Andrey Smirnov wrote:
> > Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> > ---
> > include/linux/string.h | 12 ++++++++++++
> > 1 file changed, 12 insertions(+)
> >
> > diff --git a/include/linux/string.h b/include/linux/string.h
> > index 3418b4fbe..c9823dab8 100644
> > --- a/include/linux/string.h
> > +++ b/include/linux/string.h
> > @@ -111,6 +111,18 @@ extern char *strim(char *);
> >
> > void *memchr_inv(const void *start, int c, size_t bytes);
> >
> > +/**
> > + * kbasename - return the last part of a pathname.
> > + *
> > + * @path: path to extract the filename from.
> > + */
> > +static inline const char *kbasename(const char *path)
> > +{
> > + const char *tail = strrchr(path, '/');
> > + return tail ? tail + 1 : path;
> > +}
>
> We already have basename() and posix_basename().
Sorry, forgot to check if something like that existed.
> How does this one differ or could this be an alias for one of them?
>
AFAICT, kbasename() implements the same algorithm as basename() we
already have, except it relies on strrchr() to do all of the work
instead of explicitly coding reverse string traversal. Aliasing would
be difficult since kbasename() operates on and returns "const char *"
and basename doesn't, but I'll change the patch to convert basename()
to use kbasename() internally in v3.
Thanks,
Andrey Smirnov
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2018-10-13 20:48 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-09 17:37 [PATCH v2 00/17] MV88E6xxx switch family support Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 01/17] ARM: Do not expose ARMv8 functions on ARMv7 Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 02/17] clocksource: Add ARM global timer support Andrey Smirnov
2018-10-11 8:28 ` Sascha Hauer
2018-10-09 17:37 ` [PATCH v2 03/17] VFxxx: Select CLOCKSOURCE_ARM_GLOBAL_TIMER Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 04/17] i.MX: Move GPT driver to drivers/clocksource Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 05/17] clocksource: Introduce ARCH_HAS_IMX_GPT Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 06/17] of: Demote "Bad cell count for" to debug Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 07/17] drivers: Introduce dev_set_name() Andrey Smirnov
2018-10-10 2:57 ` Andrey Smirnov
2018-10-11 8:56 ` Sascha Hauer
2018-10-12 2:01 ` Andrey Smirnov
2018-10-10 9:41 ` Lucas Stach
2018-10-10 15:33 ` Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 08/17] linux: string: Port kbasename() Andrey Smirnov
2018-10-11 8:31 ` Sascha Hauer
2018-10-13 20:47 ` Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 09/17] of: Port latest of_device_make_bus_id() implementation Andrey Smirnov
2018-10-10 16:51 ` Lucas Stach
2018-10-10 16:54 ` Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 10/17] mdio_bus: Fix documentation for mdio_bus_match() Andrey Smirnov
2018-10-09 17:37 ` [PATCH v2 11/17] include: linux: phy: Add missing PHY_INTERFACE_* constants Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 12/17] include: linux: ethtool: Add missing *_UNKNOWN constants Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 13/17] net: phy: Check phy_mask in get_phy_device() Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 14/17] mdio_bus: Allow for non PHY-devices on MDIO buses Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 15/17] net: phy: Add basic driver for MV88E6XXX switches from Marvell Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 16/17] net: phy: mv88e6xxx: Port EEPROM support code Andrey Smirnov
2018-10-09 17:38 ` [PATCH v2 17/17] net: phy: mv88e6xxx: Add support for MAC ports Andrey Smirnov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox