Re: [PATCH net-next 1/5] net: ethernet: oa_tc6: Allow custom reset settle time values
From: Alvin Šipraga
Date: Wed Nov 04 2026 - 09:21:23 EST
On Tue, Nov 03, 2026 at 06:09:14PM +0200, Iustin Stolniceanu wrote:
> From: Ciprian Regus <ciprian.regus@xxxxxxxxxx>
>
> oa_tc6_init() waits a fixed 1 ms after deasserting the reset GPIO
> before accessing the MAC-PHY. The reset timing parameters of a MAC-PHY
> device are outside of the OA TC6 scope. For example, the ADIN1110 needs
> up to 50 ms after RESET is deasserted before its registers can be
> accessed.
>
> Add a reset_settle_us field to struct oa_tc6_quirks so drivers can
> set this time. If it is not set, the GPIO reset keeps the existing
> 1 ms wait.
>
> When set, also apply the wait after the software reset, before polling
> STATUS0 for RESETC. This is needed for devices that tristate their SDO
> pin during a reset. Drivers that don't set reset_settle_us keep the
> current behaviour.
Would it maybe make sense to split this into two quirk values? Something
like hwreset_settle_us and softreset_settle_us? The ADIN1110 datasheet
seems to have a slightly lower value for software reset.
Either way,
Reviewed-by: Alvin Šipraga <alvin.sipraga@xxxxxxxxxx>
>
> Signed-off-by: Ciprian Regus <ciprian.regus@xxxxxxxxxx>
> Co-developed-by: Iustin Stolniceanu <iustin.stolniceanu@xxxxxxxxxx>
> Signed-off-by: Iustin Stolniceanu <iustin.stolniceanu@xxxxxxxxxx>
> ---
> drivers/net/ethernet/oa_tc6.c | 18 ++++++++++++++----
> include/linux/oa_tc6.h | 2 ++
> 2 files changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
> index 364027c39fa4..68437b226528 100644
> --- a/drivers/net/ethernet/oa_tc6.c
> +++ b/drivers/net/ethernet/oa_tc6.c
> @@ -89,6 +89,7 @@ struct oa_tc6 {
> bool int_flag;
> bool disable_traffic;
> bool prot_ctrl;
> + u32 reset_settle_us;
> enum oa_tc6_quirk_flag quirk_flags;
> struct gpio_desc *reset_gpio;
> };
> @@ -652,6 +653,9 @@ static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6)
> if (ret)
> return ret;
>
> + if (tc6->reset_settle_us)
> + fsleep(tc6->reset_settle_us);
If you have a separate softreset version, you can just set the value
if (quirks) and flseep() here unconditionally.
> +
> /* Poll for soft reset complete for every 1ms until 1s timeout */
> ret = readx_poll_timeout(oa_tc6_read_status0, tc6, regval,
> regval & OA_TC6_STATUS0_RESETC,
> @@ -1474,8 +1478,10 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev,
> mutex_init(&tc6->spi_ctrl_lock);
> spin_lock_init(&tc6->tx_skb_lock);
>
> - if (quirks)
> + if (quirks) {
> tc6->quirk_flags = quirks->quirk_flags;
> + tc6->reset_settle_us = quirks->reset_settle_us;
> + }
>
> /* Set the SPI controller to pump at realtime priority */
> tc6->spi->rt = true;
> @@ -1515,12 +1521,16 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev,
> "failed to get reset gpio\n"));
>
> if (tc6->reset_gpio) {
> - /* Keep the reset asserted for 10 us and then allow 1 ms of
> - * settle time for the crystal oscillator startup.
> + /* Keep the reset asserted for 10 us and then allow the reset
> + * settle time (1 ms by default) for the crystal oscillator
> + * startup.
> */
> fsleep(10);
> gpiod_set_value_cansleep(tc6->reset_gpio, 0);
> - fsleep(1000);
> + if (tc6->reset_settle_us)
> + fsleep(tc6->reset_settle_us);
> + else
> + fsleep(1000);
> }
>
> /* Check the PROTE bit status so that we can reset the device */
> diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h
> index 27f652d4920b..139dd4c33950 100644
> --- a/include/linux/oa_tc6.h
> +++ b/include/linux/oa_tc6.h
> @@ -72,6 +72,8 @@ enum oa_tc6_quirk_flag {
>
> struct oa_tc6_quirks {
> enum oa_tc6_quirk_flag quirk_flags;
> + /* Wait after the GPIO reset (default 1 ms) and the software reset */
> + u32 reset_settle_us;
> };
>
> struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev,
> --
> 2.43.0
>