#define LAN8841_PTP_INT_STS_PTP_TX_TS_INT      BIT(12)
 #define LAN8841_PTP_INT_STS_PTP_RX_TS_OVRFL_INT        BIT(9)
 #define LAN8841_PTP_INT_STS_PTP_RX_TS_INT      BIT(8)
+#define LAN8841_PTP_INT_STS_PTP_GPIO_CAP_INT   BIT(2)
 
 static void lan8841_ptp_flush_fifo(struct kszphy_ptp_priv *ptp_priv, bool egress)
 {
        phy_read_mmd(phydev, 2, LAN8841_PTP_INT_STS);
 }
 
+#define LAN8841_PTP_GPIO_CAP_STS                       506
+#define LAN8841_PTP_GPIO_SEL                           327
+#define LAN8841_PTP_GPIO_SEL_GPIO_SEL(gpio)            ((gpio) << 8)
+#define LAN8841_PTP_GPIO_RE_LTC_SEC_HI_CAP             498
+#define LAN8841_PTP_GPIO_RE_LTC_SEC_LO_CAP             499
+#define LAN8841_PTP_GPIO_RE_LTC_NS_HI_CAP              500
+#define LAN8841_PTP_GPIO_RE_LTC_NS_LO_CAP              501
+#define LAN8841_PTP_GPIO_FE_LTC_SEC_HI_CAP             502
+#define LAN8841_PTP_GPIO_FE_LTC_SEC_LO_CAP             503
+#define LAN8841_PTP_GPIO_FE_LTC_NS_HI_CAP              504
+#define LAN8841_PTP_GPIO_FE_LTC_NS_LO_CAP              505
+
+static void lan8841_gpio_process_cap(struct kszphy_ptp_priv *ptp_priv)
+{
+       struct phy_device *phydev = ptp_priv->phydev;
+       struct ptp_clock_event ptp_event = {0};
+       int pin, ret, tmp;
+       s32 sec, nsec;
+
+       pin = ptp_find_pin_unlocked(ptp_priv->ptp_clock, PTP_PF_EXTTS, 0);
+       if (pin == -1)
+               return;
+
+       tmp = phy_read_mmd(phydev, 2, LAN8841_PTP_GPIO_CAP_STS);
+       if (tmp < 0)
+               return;
+
+       ret = phy_write_mmd(phydev, 2, LAN8841_PTP_GPIO_SEL,
+                           LAN8841_PTP_GPIO_SEL_GPIO_SEL(pin));
+       if (ret)
+               return;
+
+       mutex_lock(&ptp_priv->ptp_lock);
+       if (tmp & BIT(pin)) {
+               sec = phy_read_mmd(phydev, 2, LAN8841_PTP_GPIO_RE_LTC_SEC_HI_CAP);
+               sec <<= 16;
+               sec |= phy_read_mmd(phydev, 2, LAN8841_PTP_GPIO_RE_LTC_SEC_LO_CAP);
+
+               nsec = phy_read_mmd(phydev, 2, LAN8841_PTP_GPIO_RE_LTC_NS_HI_CAP) & 0x3fff;
+               nsec <<= 16;
+               nsec |= phy_read_mmd(phydev, 2, LAN8841_PTP_GPIO_RE_LTC_NS_LO_CAP);
+       } else {
+               sec = phy_read_mmd(phydev, 2, LAN8841_PTP_GPIO_FE_LTC_SEC_HI_CAP);
+               sec <<= 16;
+               sec |= phy_read_mmd(phydev, 2, LAN8841_PTP_GPIO_FE_LTC_SEC_LO_CAP);
+
+               nsec = phy_read_mmd(phydev, 2, LAN8841_PTP_GPIO_FE_LTC_NS_HI_CAP) & 0x3fff;
+               nsec <<= 16;
+               nsec |= phy_read_mmd(phydev, 2, LAN8841_PTP_GPIO_FE_LTC_NS_LO_CAP);
+       }
+       mutex_unlock(&ptp_priv->ptp_lock);
+       ret = phy_write_mmd(phydev, 2, LAN8841_PTP_GPIO_SEL, 0);
+       if (ret)
+               return;
+
+       ptp_event.index = 0;
+       ptp_event.timestamp = ktime_set(sec, nsec);
+       ptp_event.type = PTP_CLOCK_EXTTS;
+       ptp_clock_event(ptp_priv->ptp_clock, &ptp_event);
+}
+
 static void lan8841_handle_ptp_interrupt(struct phy_device *phydev)
 {
        struct kszphy_priv *priv = phydev->priv;
 
        do {
                status = phy_read_mmd(phydev, 2, LAN8841_PTP_INT_STS);
+
                if (status & LAN8841_PTP_INT_STS_PTP_TX_TS_INT)
                        lan8841_ptp_process_tx_ts(ptp_priv);
 
                if (status & LAN8841_PTP_INT_STS_PTP_RX_TS_INT)
                        lan8841_ptp_process_rx_ts(ptp_priv);
 
+               if (status & LAN8841_PTP_INT_STS_PTP_GPIO_CAP_INT)
+                       lan8841_gpio_process_cap(ptp_priv);
+
                if (status & LAN8841_PTP_INT_STS_PTP_TX_TS_OVRFL_INT) {
                        lan8841_ptp_flush_fifo(ptp_priv, true);
                        skb_queue_purge(&ptp_priv->tx_queue);
        switch (func) {
        case PTP_PF_NONE:
        case PTP_PF_PEROUT:
+       case PTP_PF_EXTTS:
                break;
        default:
                return -1;
        return ret;
 }
 
+#define LAN8841_PTP_GPIO_CAP_EN                        496
+#define LAN8841_PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(gpio)   (BIT(gpio))
+#define LAN8841_PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(gpio)   (BIT(gpio) << 8)
+#define LAN8841_PTP_INT_EN_PTP_GPIO_CAP_EN     BIT(2)
+
+static int lan8841_ptp_extts_on(struct kszphy_ptp_priv *ptp_priv, int pin,
+                               u32 flags)
+{
+       struct phy_device *phydev = ptp_priv->phydev;
+       u16 tmp = 0;
+       int ret;
+
+       /* Set GPIO to be intput */
+       ret = phy_set_bits_mmd(phydev, 2, LAN8841_GPIO_EN, BIT(pin));
+       if (ret)
+               return ret;
+
+       ret = phy_clear_bits_mmd(phydev, 2, LAN8841_GPIO_BUF, BIT(pin));
+       if (ret)
+               return ret;
+
+       /* Enable capture on the edges of the pin */
+       if (flags & PTP_RISING_EDGE)
+               tmp |= LAN8841_PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin);
+       if (flags & PTP_FALLING_EDGE)
+               tmp |= LAN8841_PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin);
+       ret = phy_write_mmd(phydev, 2, LAN8841_PTP_GPIO_CAP_EN, tmp);
+       if (ret)
+               return ret;
+
+       /* Enable interrupt */
+       return phy_modify_mmd(phydev, 2, LAN8841_PTP_INT_EN,
+                             LAN8841_PTP_INT_EN_PTP_GPIO_CAP_EN,
+                             LAN8841_PTP_INT_EN_PTP_GPIO_CAP_EN);
+}
+
+static int lan8841_ptp_extts_off(struct kszphy_ptp_priv *ptp_priv, int pin)
+{
+       struct phy_device *phydev = ptp_priv->phydev;
+       int ret;
+
+       /* Set GPIO to be output */
+       ret = phy_clear_bits_mmd(phydev, 2, LAN8841_GPIO_EN, BIT(pin));
+       if (ret)
+               return ret;
+
+       ret = phy_clear_bits_mmd(phydev, 2, LAN8841_GPIO_BUF, BIT(pin));
+       if (ret)
+               return ret;
+
+       /* Disable capture on both of the edges */
+       ret = phy_modify_mmd(phydev, 2, LAN8841_PTP_GPIO_CAP_EN,
+                            LAN8841_PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin) |
+                            LAN8841_PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin),
+                            0);
+       if (ret)
+               return ret;
+
+       /* Disable interrupt */
+       return phy_modify_mmd(phydev, 2, LAN8841_PTP_INT_EN,
+                             LAN8841_PTP_INT_EN_PTP_GPIO_CAP_EN,
+                             0);
+}
+
+static int lan8841_ptp_extts(struct ptp_clock_info *ptp,
+                            struct ptp_clock_request *rq, int on)
+{
+       struct kszphy_ptp_priv *ptp_priv = container_of(ptp, struct kszphy_ptp_priv,
+                                                       ptp_clock_info);
+       int pin;
+       int ret;
+
+       /* Reject requests with unsupported flags */
+       if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |
+                               PTP_EXTTS_EDGES |
+                               PTP_STRICT_FLAGS))
+               return -EOPNOTSUPP;
+
+       pin = ptp_find_pin(ptp_priv->ptp_clock, PTP_PF_EXTTS, rq->extts.index);
+       if (pin == -1 || pin >= LAN8841_PTP_GPIO_NUM)
+               return -EINVAL;
+
+       mutex_lock(&ptp_priv->ptp_lock);
+       if (on)
+               ret = lan8841_ptp_extts_on(ptp_priv, pin, rq->extts.flags);
+       else
+               ret = lan8841_ptp_extts_off(ptp_priv, pin);
+       mutex_unlock(&ptp_priv->ptp_lock);
+
+       return ret;
+}
+
 static int lan8841_ptp_enable(struct ptp_clock_info *ptp,
                              struct ptp_clock_request *rq, int on)
 {
        switch (rq->type) {
+       case PTP_CLK_REQ_EXTTS:
+               return lan8841_ptp_extts(ptp, rq, on);
        case PTP_CLK_REQ_PEROUT:
                return lan8841_ptp_perout(ptp, rq, on);
        default:
        .verify         = lan8841_ptp_verify,
        .enable         = lan8841_ptp_enable,
        .n_per_out      = LAN8841_PTP_GPIO_NUM,
+       .n_ext_ts       = LAN8841_PTP_GPIO_NUM,
        .n_pins         = LAN8841_PTP_GPIO_NUM,
 };