netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT
@ 2021-08-01  0:27 Linus Walleij
  2021-08-01  0:27 ` [PATCH net-next 1/6] ixp4xx_eth: make ptp support a platform driver Linus Walleij
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Linus Walleij @ 2021-08-01  0:27 UTC (permalink / raw)
  To: netdev, David S . Miller, Jakub Kicinski
  Cc: Imre Kaloz, Krzysztof Halasa, Linus Walleij

This is a combination of a few cleanups from Arnd and some cleanup
and device tree support work from me, together modernizing the
PTP timer for the IXP46x platforms.

Arnd Bergmann (3):
  ixp4xx_eth: make ptp support a platform driver
  ixp4xx_eth: fix compile-testing
  ixp4xx_eth: enable compile testing

Linus Walleij (3):
  ixp4xx_eth: Stop referring to GPIOs
  ixp4xx_eth: Add devicetree bindings
  ixp4xx_eth: Probe the PTP module from the device tree

 .../bindings/net/intel,ixp46x-ptp-timer.yaml  |  54 ++++++++
 arch/arm/mach-ixp4xx/common.c                 |  14 ++
 drivers/net/ethernet/xscale/Kconfig           |  11 +-
 drivers/net/ethernet/xscale/Makefile          |   6 +-
 drivers/net/ethernet/xscale/ixp46x_ts.h       |  13 +-
 drivers/net/ethernet/xscale/ixp4xx_eth.c      |  35 +++--
 drivers/net/ethernet/xscale/ptp_ixp46x.c      | 122 +++++++++---------
 7 files changed, 175 insertions(+), 80 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml

-- 
2.31.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH net-next 1/6] ixp4xx_eth: make ptp support a platform driver
  2021-08-01  0:27 [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Linus Walleij
@ 2021-08-01  0:27 ` Linus Walleij
  2021-08-01  0:27 ` [PATCH net-next 2/6] ixp4xx_eth: fix compile-testing Linus Walleij
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2021-08-01  0:27 UTC (permalink / raw)
  To: netdev, David S . Miller, Jakub Kicinski
  Cc: Imre Kaloz, Krzysztof Halasa, Arnd Bergmann, Linus Walleij

From: Arnd Bergmann <arnd@arndb.de>

After the recent ixp4xx cleanups, the ptp driver has gained a
build failure in some configurations:

drivers/net/ethernet/xscale/ptp_ixp46x.c: In function 'ptp_ixp_init':
drivers/net/ethernet/xscale/ptp_ixp46x.c:290:51: error: 'IXP4XX_TIMESYNC_BASE_VIRT' undeclared (first use in this function)

Avoid the last bit of hardcoded constants from platform headers
by turning the ptp driver bit into a platform driver and passing
the IRQ and MMIO address as resources.

This is a bit tricky:

- The interface between the two drivers is now the new
  ixp46x_ptp_find() function, replacing the global
  ixp46x_phc_index variable. The call is done as late
  as possible, in hwtstamp_set(), to ensure that the
  ptp device is fully probed.

- As the ptp driver is now called by the network driver, the
  link dependency is reversed, which in turn requires a small
  Makefile hack

- The GPIO number is still left hardcoded. This is clearly not
  great, but it can be addressed later. Note that commit 98ac0cc270b7
  ("ARM: ixp4xx: Convert to MULTI_IRQ_HANDLER") changed the
  IRQ number to something meaningless. Passing the correct IRQ
  in a resource fixes this.

- When the PTP driver is disabled, ethtool .get_ts_info()
  now correctly lists only software timestamping regardless
  of the hardware.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
[Fix a missing include]
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ixp4xx/common.c            | 14 ++++++
 drivers/net/ethernet/xscale/Kconfig      |  4 +-
 drivers/net/ethernet/xscale/Makefile     |  6 ++-
 drivers/net/ethernet/xscale/ixp46x_ts.h  | 13 ++++-
 drivers/net/ethernet/xscale/ixp4xx_eth.c | 28 +++++++----
 drivers/net/ethernet/xscale/ptp_ixp46x.c | 61 ++++++++++++++++--------
 6 files changed, 92 insertions(+), 34 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index b5eadd70d903..cdc720f54daa 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -268,9 +268,23 @@ static struct platform_device ixp46x_i2c_controller = {
 	.resource	= ixp46x_i2c_resources
 };
 
+static struct resource ixp46x_ptp_resources[] = {
+	DEFINE_RES_MEM(IXP4XX_TIMESYNC_BASE_PHYS, SZ_4K),
+	DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO8, "master"),
+	DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO7, "slave"),
+};
+
+static struct platform_device ixp46x_ptp = {
+	.name		= "ptp-ixp46x",
+	.id		= -1,
+	.resource	= ixp46x_ptp_resources,
+	.num_resources	= ARRAY_SIZE(ixp46x_ptp_resources),
+};
+
 static struct platform_device *ixp46x_devices[] __initdata = {
 	&ixp46x_hwrandom_device,
 	&ixp46x_i2c_controller,
+	&ixp46x_ptp,
 };
 
 unsigned long ixp4xx_exp_bus_size;
diff --git a/drivers/net/ethernet/xscale/Kconfig b/drivers/net/ethernet/xscale/Kconfig
index 468ffe3d1707..0e878fa6e322 100644
--- a/drivers/net/ethernet/xscale/Kconfig
+++ b/drivers/net/ethernet/xscale/Kconfig
@@ -29,9 +29,9 @@ config IXP4XX_ETH
 	  on IXP4xx processor.
 
 config PTP_1588_CLOCK_IXP46X
-	tristate "Intel IXP46x as PTP clock"
+	bool "Intel IXP46x as PTP clock"
 	depends on IXP4XX_ETH
-	depends on PTP_1588_CLOCK
+	depends on PTP_1588_CLOCK=y || PTP_1588_CLOCK=IXP4XX_ETH
 	default y
 	help
 	  This driver adds support for using the IXP46X as a PTP
diff --git a/drivers/net/ethernet/xscale/Makefile b/drivers/net/ethernet/xscale/Makefile
index 607f91b1e878..e935f2a2979f 100644
--- a/drivers/net/ethernet/xscale/Makefile
+++ b/drivers/net/ethernet/xscale/Makefile
@@ -3,5 +3,9 @@
 # Makefile for the Intel XScale IXP device drivers.
 #
 
+# Keep this link order to avoid deferred probing
+ifdef CONFIG_PTP_1588_CLOCK_IXP46X
+obj-$(CONFIG_IXP4XX_ETH)		+= ptp_ixp46x.o
+endif
+
 obj-$(CONFIG_IXP4XX_ETH)		+= ixp4xx_eth.o
-obj-$(CONFIG_PTP_1588_CLOCK_IXP46X)	+= ptp_ixp46x.o
diff --git a/drivers/net/ethernet/xscale/ixp46x_ts.h b/drivers/net/ethernet/xscale/ixp46x_ts.h
index d792130e27b0..ee9b93ded20a 100644
--- a/drivers/net/ethernet/xscale/ixp46x_ts.h
+++ b/drivers/net/ethernet/xscale/ixp46x_ts.h
@@ -62,7 +62,16 @@ struct ixp46x_ts_regs {
 #define TX_SNAPSHOT_LOCKED (1<<0)
 #define RX_SNAPSHOT_LOCKED (1<<1)
 
-/* The ptp_ixp46x module will set this variable */
-extern int ixp46x_phc_index;
+#if IS_ENABLED(CONFIG_PTP_1588_CLOCK_IXP46X)
+int ixp46x_ptp_find(struct ixp46x_ts_regs *__iomem *regs, int *phc_index);
+#else
+static inline int ixp46x_ptp_find(struct ixp46x_ts_regs *__iomem *regs, int *phc_index)
+{
+	*regs = NULL;
+	*phc_index = -1;
+
+	return -ENODEV;
+}
+#endif
 
 #endif
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 7ae754eadf22..32dc2c7abb22 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -169,6 +169,8 @@ struct eth_regs {
 
 struct port {
 	struct eth_regs __iomem *regs;
+	struct ixp46x_ts_regs __iomem *timesync_regs;
+	int phc_index;
 	struct npe *npe;
 	struct net_device *netdev;
 	struct napi_struct napi;
@@ -295,7 +297,7 @@ static void ixp_rx_timestamp(struct port *port, struct sk_buff *skb)
 
 	ch = PORT2CHANNEL(port);
 
-	regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT;
+	regs = port->timesync_regs;
 
 	val = __raw_readl(&regs->channel[ch].ch_event);
 
@@ -340,7 +342,7 @@ static void ixp_tx_timestamp(struct port *port, struct sk_buff *skb)
 
 	ch = PORT2CHANNEL(port);
 
-	regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT;
+	regs = port->timesync_regs;
 
 	/*
 	 * This really stinks, but we have to poll for the Tx time stamp.
@@ -375,6 +377,7 @@ static int hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
 	struct hwtstamp_config cfg;
 	struct ixp46x_ts_regs *regs;
 	struct port *port = netdev_priv(netdev);
+	int ret;
 	int ch;
 
 	if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
@@ -383,8 +386,12 @@ static int hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
 	if (cfg.flags) /* reserved for future extensions */
 		return -EINVAL;
 
+	ret = ixp46x_ptp_find(&port->timesync_regs, &port->phc_index);
+	if (ret)
+		return ret;
+
 	ch = PORT2CHANNEL(port);
-	regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT;
+	regs = port->timesync_regs;
 
 	if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON)
 		return -ERANGE;
@@ -988,25 +995,27 @@ static void ixp4xx_get_drvinfo(struct net_device *dev,
 	strlcpy(info->bus_info, "internal", sizeof(info->bus_info));
 }
 
-int ixp46x_phc_index = -1;
-EXPORT_SYMBOL_GPL(ixp46x_phc_index);
-
 static int ixp4xx_get_ts_info(struct net_device *dev,
 			      struct ethtool_ts_info *info)
 {
-	if (!cpu_is_ixp46x()) {
+	struct port *port = netdev_priv(dev);
+
+	if (port->phc_index < 0)
+		ixp46x_ptp_find(&port->timesync_regs, &port->phc_index);
+
+	info->phc_index = port->phc_index;
+
+	if (info->phc_index < 0) {
 		info->so_timestamping =
 			SOF_TIMESTAMPING_TX_SOFTWARE |
 			SOF_TIMESTAMPING_RX_SOFTWARE |
 			SOF_TIMESTAMPING_SOFTWARE;
-		info->phc_index = -1;
 		return 0;
 	}
 	info->so_timestamping =
 		SOF_TIMESTAMPING_TX_HARDWARE |
 		SOF_TIMESTAMPING_RX_HARDWARE |
 		SOF_TIMESTAMPING_RAW_HARDWARE;
-	info->phc_index = ixp46x_phc_index;
 	info->tx_types =
 		(1 << HWTSTAMP_TX_OFF) |
 		(1 << HWTSTAMP_TX_ON);
@@ -1481,6 +1490,7 @@ static int ixp4xx_eth_probe(struct platform_device *pdev)
 	port = netdev_priv(ndev);
 	port->netdev = ndev;
 	port->id = plat->npe;
+	port->phc_index = -1;
 
 	/* Get the port resource and remap */
 	port->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
diff --git a/drivers/net/ethernet/xscale/ptp_ixp46x.c b/drivers/net/ethernet/xscale/ptp_ixp46x.c
index 99d4d9439d05..6232a0e0710e 100644
--- a/drivers/net/ethernet/xscale/ptp_ixp46x.c
+++ b/drivers/net/ethernet/xscale/ptp_ixp46x.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2010 OMICRON electronics GmbH
  */
 #include <linux/device.h>
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
@@ -13,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/ptp_clock_kernel.h>
+#include <linux/platform_device.h>
 #include <linux/soc/ixp4xx/cpu.h>
 
 #include "ixp46x_ts.h"
@@ -20,9 +22,7 @@
 #define DRIVER		"ptp_ixp46x"
 #define N_EXT_TS	2
 #define MASTER_GPIO	8
-#define MASTER_IRQ	25
 #define SLAVE_GPIO	7
-#define SLAVE_IRQ	24
 
 struct ixp_clock {
 	struct ixp46x_ts_regs *regs;
@@ -30,9 +30,11 @@ struct ixp_clock {
 	struct ptp_clock_info caps;
 	int exts0_enabled;
 	int exts1_enabled;
+	int slave_irq;
+	int master_irq;
 };
 
-DEFINE_SPINLOCK(register_lock);
+static DEFINE_SPINLOCK(register_lock);
 
 /*
  * Register access functions
@@ -273,21 +275,36 @@ static int setup_interrupt(int gpio)
 	return irq;
 }
 
-static void __exit ptp_ixp_exit(void)
+int ixp46x_ptp_find(struct ixp46x_ts_regs *__iomem *regs, int *phc_index)
 {
-	free_irq(MASTER_IRQ, &ixp_clock);
-	free_irq(SLAVE_IRQ, &ixp_clock);
-	ixp46x_phc_index = -1;
-	ptp_clock_unregister(ixp_clock.ptp_clock);
+	*regs = ixp_clock.regs;
+	*phc_index = ptp_clock_index(ixp_clock.ptp_clock);
+
+	if (!ixp_clock.ptp_clock)
+		return -EPROBE_DEFER;
+
+	return 0;
 }
+EXPORT_SYMBOL_GPL(ixp46x_ptp_find);
 
-static int __init ptp_ixp_init(void)
+static int ptp_ixp_remove(struct platform_device *pdev)
 {
-	if (!cpu_is_ixp46x())
-		return -ENODEV;
+	free_irq(ixp_clock.master_irq, &ixp_clock);
+	free_irq(ixp_clock.slave_irq, &ixp_clock);
+	ptp_clock_unregister(ixp_clock.ptp_clock);
+	ixp_clock.ptp_clock = NULL;
 
-	ixp_clock.regs =
-		(struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT;
+	return 0;
+}
+
+static int ptp_ixp_probe(struct platform_device *pdev)
+{
+	ixp_clock.regs = devm_platform_ioremap_resource(pdev, 0);
+	ixp_clock.master_irq = platform_get_irq(pdev, 0);
+	ixp_clock.slave_irq = platform_get_irq(pdev, 1);
+	if (IS_ERR(ixp_clock.regs) ||
+	    !ixp_clock.master_irq || !ixp_clock.slave_irq)
+		return -ENXIO;
 
 	ixp_clock.caps = ptp_ixp_caps;
 
@@ -296,32 +313,36 @@ static int __init ptp_ixp_init(void)
 	if (IS_ERR(ixp_clock.ptp_clock))
 		return PTR_ERR(ixp_clock.ptp_clock);
 
-	ixp46x_phc_index = ptp_clock_index(ixp_clock.ptp_clock);
-
 	__raw_writel(DEFAULT_ADDEND, &ixp_clock.regs->addend);
 	__raw_writel(1, &ixp_clock.regs->trgt_lo);
 	__raw_writel(0, &ixp_clock.regs->trgt_hi);
 	__raw_writel(TTIPEND, &ixp_clock.regs->event);
 
-	if (MASTER_IRQ != setup_interrupt(MASTER_GPIO)) {
+	if (ixp_clock.master_irq != setup_interrupt(MASTER_GPIO)) {
 		pr_err("failed to setup gpio %d as irq\n", MASTER_GPIO);
 		goto no_master;
 	}
-	if (SLAVE_IRQ != setup_interrupt(SLAVE_GPIO)) {
+	if (ixp_clock.slave_irq != setup_interrupt(SLAVE_GPIO)) {
 		pr_err("failed to setup gpio %d as irq\n", SLAVE_GPIO);
 		goto no_slave;
 	}
 
 	return 0;
 no_slave:
-	free_irq(MASTER_IRQ, &ixp_clock);
+	free_irq(ixp_clock.master_irq, &ixp_clock);
 no_master:
 	ptp_clock_unregister(ixp_clock.ptp_clock);
+	ixp_clock.ptp_clock = NULL;
 	return -ENODEV;
 }
 
-module_init(ptp_ixp_init);
-module_exit(ptp_ixp_exit);
+static struct platform_driver ptp_ixp_driver = {
+	.driver.name = "ptp-ixp46x",
+	.driver.suppress_bind_attrs = true,
+	.probe = ptp_ixp_probe,
+	.remove = ptp_ixp_remove,
+};
+module_platform_driver(ptp_ixp_driver);
 
 MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
 MODULE_DESCRIPTION("PTP clock using the IXP46X timer");
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 2/6] ixp4xx_eth: fix compile-testing
  2021-08-01  0:27 [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Linus Walleij
  2021-08-01  0:27 ` [PATCH net-next 1/6] ixp4xx_eth: make ptp support a platform driver Linus Walleij
@ 2021-08-01  0:27 ` Linus Walleij
  2021-08-01  0:27 ` [PATCH net-next 3/6] ixp4xx_eth: enable compile testing Linus Walleij
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2021-08-01  0:27 UTC (permalink / raw)
  To: netdev, David S . Miller, Jakub Kicinski
  Cc: Imre Kaloz, Krzysztof Halasa, Arnd Bergmann, Linus Walleij

From: Arnd Bergmann <arnd@arndb.de>

Change the driver to use portable integer types to avoid warnings
during compile testing, including:

drivers/net/ethernet/xscale/ixp4xx_eth.c:721:21: error: cast to 'u32 *' (aka 'unsigned int *') from smaller integer type 'int' [-Werror,-Wint-to-pointer-cast]
        memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4);
                           ^
drivers/net/ethernet/xscale/ixp4xx_eth.c:963:12: error: incompatible pointer types passing 'u32 *' (aka 'unsigned int *') to parameter of type 'dma_addr_t *' (aka 'unsigned long long *') [-Werror,-Wincompatible-pointer-types]
                                              &port->desc_tab_phys)))
                                              ^~~~~~~~~~~~~~~~~~~~
include/linux/dmapool.h:27:20: note: passing argument to parameter 'handle' here
                     dma_addr_t *handle);
                                 ^

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/net/ethernet/xscale/ixp4xx_eth.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 32dc2c7abb22..253ac8f3cb56 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -37,7 +37,6 @@
 #include <linux/module.h>
 #include <linux/soc/ixp4xx/npe.h>
 #include <linux/soc/ixp4xx/qmgr.h>
-#include <mach/hardware.h>
 #include <linux/soc/ixp4xx/cpu.h>
 
 #include "ixp46x_ts.h"
@@ -177,7 +176,7 @@ struct port {
 	struct eth_plat_info *plat;
 	buffer_t *rx_buff_tab[RX_DESCS], *tx_buff_tab[TX_DESCS];
 	struct desc *desc_tab;	/* coherent */
-	u32 desc_tab_phys;
+	dma_addr_t desc_tab_phys;
 	int id;			/* logical port ID */
 	int speed, duplex;
 	u8 firmware[4];
@@ -857,14 +856,14 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
 	bytes = len;
 	mem = skb->data;
 #else
-	offset = (int)skb->data & 3; /* keep 32-bit alignment */
+	offset = (uintptr_t)skb->data & 3; /* keep 32-bit alignment */
 	bytes = ALIGN(offset + len, 4);
 	if (!(mem = kmalloc(bytes, GFP_ATOMIC))) {
 		dev_kfree_skb(skb);
 		dev->stats.tx_dropped++;
 		return NETDEV_TX_OK;
 	}
-	memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4);
+	memcpy_swab32(mem, (u32 *)((uintptr_t)skb->data & ~3), bytes / 4);
 #endif
 
 	phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 3/6] ixp4xx_eth: enable compile testing
  2021-08-01  0:27 [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Linus Walleij
  2021-08-01  0:27 ` [PATCH net-next 1/6] ixp4xx_eth: make ptp support a platform driver Linus Walleij
  2021-08-01  0:27 ` [PATCH net-next 2/6] ixp4xx_eth: fix compile-testing Linus Walleij
@ 2021-08-01  0:27 ` Linus Walleij
  2021-08-01  0:27 ` [PATCH net-next 4/6] ixp4xx_eth: Stop referring to GPIOs Linus Walleij
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2021-08-01  0:27 UTC (permalink / raw)
  To: netdev, David S . Miller, Jakub Kicinski
  Cc: Imre Kaloz, Krzysztof Halasa, Arnd Bergmann, Linus Walleij

From: Arnd Bergmann <arnd@arndb.de>

The driver is now independent of machine specific header
files and should build on all architectures, so enable
building with CONFIG_COMPILE_TEST.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/net/ethernet/xscale/Kconfig | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/xscale/Kconfig b/drivers/net/ethernet/xscale/Kconfig
index 0e878fa6e322..b93e88422a13 100644
--- a/drivers/net/ethernet/xscale/Kconfig
+++ b/drivers/net/ethernet/xscale/Kconfig
@@ -6,8 +6,8 @@
 config NET_VENDOR_XSCALE
 	bool "Intel XScale IXP devices"
 	default y
-	depends on NET_VENDOR_INTEL && (ARM && ARCH_IXP4XX && \
-		   IXP4XX_NPE && IXP4XX_QMGR)
+	depends on NET_VENDOR_INTEL && IXP4XX_NPE && IXP4XX_QMGR
+	depends on ARCH_IXP4XX || COMPILE_TEST
 	help
 	  If you have a network (Ethernet) card belonging to this class, say Y.
 
@@ -20,7 +20,8 @@ if NET_VENDOR_XSCALE
 
 config IXP4XX_ETH
 	tristate "Intel IXP4xx Ethernet support"
-	depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
+	depends on IXP4XX_NPE && IXP4XX_QMGR
+	depends on ARCH_IXP4XX || COMPILE_TEST
 	select PHYLIB
 	select OF_MDIO if OF
 	select NET_PTP_CLASSIFY
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 4/6] ixp4xx_eth: Stop referring to GPIOs
  2021-08-01  0:27 [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Linus Walleij
                   ` (2 preceding siblings ...)
  2021-08-01  0:27 ` [PATCH net-next 3/6] ixp4xx_eth: enable compile testing Linus Walleij
@ 2021-08-01  0:27 ` Linus Walleij
  2021-08-01  0:27 ` [PATCH net-next 5/6] ixp4xx_eth: Add devicetree bindings Linus Walleij
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2021-08-01  0:27 UTC (permalink / raw)
  To: netdev, David S . Miller, Jakub Kicinski
  Cc: Imre Kaloz, Krzysztof Halasa, Linus Walleij, Arnd Bergmann

The driver is being passed interrupts, then looking up the
same interrupts as GPIOs a second time to convert them into
interrupts and set properties on them.

This is pointless: the GPIO and irqchip APIs of a GPIO chip
are orthogonal. Just request the interrupts and be done
with it, drop reliance on any GPIO functions or definitions.

Use devres-managed functions and add a small devress quirk
to unregister the clock as well and we can rely on devres
to handle all the resources and cut down a bunch of
boilerplate in the process.

Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/net/ethernet/xscale/ptp_ixp46x.c | 84 ++++++++----------------
 1 file changed, 28 insertions(+), 56 deletions(-)

diff --git a/drivers/net/ethernet/xscale/ptp_ixp46x.c b/drivers/net/ethernet/xscale/ptp_ixp46x.c
index 6232a0e0710e..3ed40b0d0ad2 100644
--- a/drivers/net/ethernet/xscale/ptp_ixp46x.c
+++ b/drivers/net/ethernet/xscale/ptp_ixp46x.c
@@ -7,7 +7,6 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -21,8 +20,6 @@
 
 #define DRIVER		"ptp_ixp46x"
 #define N_EXT_TS	2
-#define MASTER_GPIO	8
-#define SLAVE_GPIO	7
 
 struct ixp_clock {
 	struct ixp46x_ts_regs *regs;
@@ -243,38 +240,6 @@ static const struct ptp_clock_info ptp_ixp_caps = {
 
 static struct ixp_clock ixp_clock;
 
-static int setup_interrupt(int gpio)
-{
-	int irq;
-	int err;
-
-	err = gpio_request(gpio, "ixp4-ptp");
-	if (err)
-		return err;
-
-	err = gpio_direction_input(gpio);
-	if (err)
-		return err;
-
-	irq = gpio_to_irq(gpio);
-	if (irq < 0)
-		return irq;
-
-	err = irq_set_irq_type(irq, IRQF_TRIGGER_FALLING);
-	if (err) {
-		pr_err("cannot set trigger type for irq %d\n", irq);
-		return err;
-	}
-
-	err = request_irq(irq, isr, 0, DRIVER, &ixp_clock);
-	if (err) {
-		pr_err("request_irq failed for irq %d\n", irq);
-		return err;
-	}
-
-	return irq;
-}
-
 int ixp46x_ptp_find(struct ixp46x_ts_regs *__iomem *regs, int *phc_index)
 {
 	*regs = ixp_clock.regs;
@@ -287,18 +252,20 @@ int ixp46x_ptp_find(struct ixp46x_ts_regs *__iomem *regs, int *phc_index)
 }
 EXPORT_SYMBOL_GPL(ixp46x_ptp_find);
 
-static int ptp_ixp_remove(struct platform_device *pdev)
+/* Called from the registered devm action */
+static void ptp_ixp_unregister_action(void *d)
 {
-	free_irq(ixp_clock.master_irq, &ixp_clock);
-	free_irq(ixp_clock.slave_irq, &ixp_clock);
-	ptp_clock_unregister(ixp_clock.ptp_clock);
-	ixp_clock.ptp_clock = NULL;
+	struct ptp_clock *ptp_clock = d;
 
-	return 0;
+	ptp_clock_unregister(ptp_clock);
+	ixp_clock.ptp_clock = NULL;
 }
 
 static int ptp_ixp_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	int ret;
+
 	ixp_clock.regs = devm_platform_ioremap_resource(pdev, 0);
 	ixp_clock.master_irq = platform_get_irq(pdev, 0);
 	ixp_clock.slave_irq = platform_get_irq(pdev, 1);
@@ -313,34 +280,39 @@ static int ptp_ixp_probe(struct platform_device *pdev)
 	if (IS_ERR(ixp_clock.ptp_clock))
 		return PTR_ERR(ixp_clock.ptp_clock);
 
+	ret = devm_add_action_or_reset(dev, ptp_ixp_unregister_action,
+				       ixp_clock.ptp_clock);
+	if (ret) {
+		dev_err(dev, "failed to install clock removal handler\n");
+		return ret;
+	}
+
 	__raw_writel(DEFAULT_ADDEND, &ixp_clock.regs->addend);
 	__raw_writel(1, &ixp_clock.regs->trgt_lo);
 	__raw_writel(0, &ixp_clock.regs->trgt_hi);
 	__raw_writel(TTIPEND, &ixp_clock.regs->event);
 
-	if (ixp_clock.master_irq != setup_interrupt(MASTER_GPIO)) {
-		pr_err("failed to setup gpio %d as irq\n", MASTER_GPIO);
-		goto no_master;
-	}
-	if (ixp_clock.slave_irq != setup_interrupt(SLAVE_GPIO)) {
-		pr_err("failed to setup gpio %d as irq\n", SLAVE_GPIO);
-		goto no_slave;
-	}
+	ret = devm_request_irq(dev, ixp_clock.master_irq, isr,
+			       0, DRIVER, &ixp_clock);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "request_irq failed for irq %d\n",
+				     ixp_clock.master_irq);
+
+	ret = devm_request_irq(dev, ixp_clock.slave_irq, isr,
+			       0, DRIVER, &ixp_clock);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "request_irq failed for irq %d\n",
+				     ixp_clock.slave_irq);
 
 	return 0;
-no_slave:
-	free_irq(ixp_clock.master_irq, &ixp_clock);
-no_master:
-	ptp_clock_unregister(ixp_clock.ptp_clock);
-	ixp_clock.ptp_clock = NULL;
-	return -ENODEV;
 }
 
 static struct platform_driver ptp_ixp_driver = {
 	.driver.name = "ptp-ixp46x",
 	.driver.suppress_bind_attrs = true,
 	.probe = ptp_ixp_probe,
-	.remove = ptp_ixp_remove,
 };
 module_platform_driver(ptp_ixp_driver);
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 5/6] ixp4xx_eth: Add devicetree bindings
  2021-08-01  0:27 [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Linus Walleij
                   ` (3 preceding siblings ...)
  2021-08-01  0:27 ` [PATCH net-next 4/6] ixp4xx_eth: Stop referring to GPIOs Linus Walleij
@ 2021-08-01  0:27 ` Linus Walleij
  2021-08-03 20:38   ` Rob Herring
  2021-08-01  0:27 ` [PATCH net-next 6/6] ixp4xx_eth: Probe the PTP module from the device tree Linus Walleij
  2021-08-02 16:05 ` [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Jakub Kicinski
  6 siblings, 1 reply; 9+ messages in thread
From: Linus Walleij @ 2021-08-01  0:27 UTC (permalink / raw)
  To: netdev, David S . Miller, Jakub Kicinski
  Cc: Imre Kaloz, Krzysztof Halasa, Linus Walleij, devicetree, Arnd Bergmann

This adds device tree bindings for the IXP46x PTP Timer, a companion
to the IXP4xx ethernet in newer platforms.

Cc: devicetree@vger.kernel.org
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 .../bindings/net/intel,ixp46x-ptp-timer.yaml  | 54 +++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml

diff --git a/Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml b/Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml
new file mode 100644
index 000000000000..8b9b3f915d92
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2018 Linaro Ltd.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/net/intel,ixp46x-ptp-timer.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Intel IXP46x PTP Timer (TSYNC)
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description: |
+  The Intel IXP46x PTP timer is known in the manual as IEEE1588 Hardware
+  Assist and Time Synchronization Hardware Assist TSYNC provides a PTP
+  timer. It exists in the Intel IXP45x and IXP46x XScale SoCs.
+
+properties:
+  compatible:
+    const: intel,ixp46x-ptp-timer
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Interrupt to trigger master mode snapshot from the
+          PRP timer, usually a GPIO interrupt.
+      - description: Interrupt to trigger slave mode snapshot from the
+          PRP timer, usually a GPIO interrupt.
+
+  interrupt-names:
+    items:
+      - const: master
+      - const: slave
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    ptp-timer@c8010000 {
+        compatible = "intel,ixp46x-ptp-timer";
+        reg = <0xc8010000 0x1000>;
+        interrupt-parent = <&gpio0>;
+        interrupts = <8 IRQ_TYPE_EDGE_FALLING>, <7 IRQ_TYPE_EDGE_FALLING>;
+        interrupt-names = "master", "slave";
+    };
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 6/6] ixp4xx_eth: Probe the PTP module from the device tree
  2021-08-01  0:27 [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Linus Walleij
                   ` (4 preceding siblings ...)
  2021-08-01  0:27 ` [PATCH net-next 5/6] ixp4xx_eth: Add devicetree bindings Linus Walleij
@ 2021-08-01  0:27 ` Linus Walleij
  2021-08-02 16:05 ` [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Jakub Kicinski
  6 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2021-08-01  0:27 UTC (permalink / raw)
  To: netdev, David S . Miller, Jakub Kicinski
  Cc: Imre Kaloz, Krzysztof Halasa, Linus Walleij, Arnd Bergmann

This adds device tree probing support for the PTP module
adjacent to the ethernet module. It is pretty straight
forward, all resources are in the device tree as they
come to the platform device.

Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/net/ethernet/xscale/ptp_ixp46x.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xscale/ptp_ixp46x.c b/drivers/net/ethernet/xscale/ptp_ixp46x.c
index 3ed40b0d0ad2..1f382777aa5a 100644
--- a/drivers/net/ethernet/xscale/ptp_ixp46x.c
+++ b/drivers/net/ethernet/xscale/ptp_ixp46x.c
@@ -6,6 +6,7 @@
  */
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/mod_devicetable.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -309,9 +310,19 @@ static int ptp_ixp_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id ptp_ixp_match[] = {
+	{
+		.compatible = "intel,ixp46x-ptp-timer",
+	},
+	{ },
+};
+
 static struct platform_driver ptp_ixp_driver = {
-	.driver.name = "ptp-ixp46x",
-	.driver.suppress_bind_attrs = true,
+	.driver = {
+		.name = "ptp-ixp46x",
+		.of_match_table = ptp_ixp_match,
+		.suppress_bind_attrs = true,
+	},
 	.probe = ptp_ixp_probe,
 };
 module_platform_driver(ptp_ixp_driver);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT
  2021-08-01  0:27 [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Linus Walleij
                   ` (5 preceding siblings ...)
  2021-08-01  0:27 ` [PATCH net-next 6/6] ixp4xx_eth: Probe the PTP module from the device tree Linus Walleij
@ 2021-08-02 16:05 ` Jakub Kicinski
  6 siblings, 0 replies; 9+ messages in thread
From: Jakub Kicinski @ 2021-08-02 16:05 UTC (permalink / raw)
  To: Linus Walleij; +Cc: netdev, David S . Miller, Imre Kaloz, Krzysztof Halasa

On Sun,  1 Aug 2021 02:27:31 +0200 Linus Walleij wrote:
> This is a combination of a few cleanups from Arnd and some cleanup
> and device tree support work from me, together modernizing the
> PTP timer for the IXP46x platforms.

This set does not apply to net-next, please respin.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 5/6] ixp4xx_eth: Add devicetree bindings
  2021-08-01  0:27 ` [PATCH net-next 5/6] ixp4xx_eth: Add devicetree bindings Linus Walleij
@ 2021-08-03 20:38   ` Rob Herring
  0 siblings, 0 replies; 9+ messages in thread
From: Rob Herring @ 2021-08-03 20:38 UTC (permalink / raw)
  To: Linus Walleij
  Cc: David S . Miller, Jakub Kicinski, Krzysztof Halasa, Imre Kaloz,
	devicetree, Arnd Bergmann, netdev

On Sun, 01 Aug 2021 02:27:36 +0200, Linus Walleij wrote:
> This adds device tree bindings for the IXP46x PTP Timer, a companion
> to the IXP4xx ethernet in newer platforms.
> 
> Cc: devicetree@vger.kernel.org
> Cc: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  .../bindings/net/intel,ixp46x-ptp-timer.yaml  | 54 +++++++++++++++++++
>  1 file changed, 54 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-08-03 20:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-01  0:27 [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Linus Walleij
2021-08-01  0:27 ` [PATCH net-next 1/6] ixp4xx_eth: make ptp support a platform driver Linus Walleij
2021-08-01  0:27 ` [PATCH net-next 2/6] ixp4xx_eth: fix compile-testing Linus Walleij
2021-08-01  0:27 ` [PATCH net-next 3/6] ixp4xx_eth: enable compile testing Linus Walleij
2021-08-01  0:27 ` [PATCH net-next 4/6] ixp4xx_eth: Stop referring to GPIOs Linus Walleij
2021-08-01  0:27 ` [PATCH net-next 5/6] ixp4xx_eth: Add devicetree bindings Linus Walleij
2021-08-03 20:38   ` Rob Herring
2021-08-01  0:27 ` [PATCH net-next 6/6] ixp4xx_eth: Probe the PTP module from the device tree Linus Walleij
2021-08-02 16:05 ` [PATCH net-next 0/6] IXP46x PTP Timer clean-up and DT Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).