devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: <Parthiban.Veerasooran@microchip.com>
To: <william.xuanziyang@huawei.com>
Cc: <netdev@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<Horatiu.Vultur@microchip.com>, <Woojung.Huh@microchip.com>,
	<Nicolas.Ferre@microchip.com>, <UNGLinuxDriver@microchip.com>,
	<Thorsten.Kummermehr@microchip.com>, <davem@davemloft.net>,
	<edumazet@google.com>, <kuba@kernel.org>, <pabeni@redhat.com>,
	<robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>,
	<conor+dt@kernel.org>, <corbet@lwn.net>,
	<Steen.Hegelund@microchip.com>, <rdunlap@infradead.org>,
	<horms@kernel.org>, <casper.casan@gmail.com>, <andrew@lunn.ch>
Subject: Re: [RFC PATCH net-next 2/6] net: ethernet: add mac-phy interrupt support with reset complete handling
Date: Tue, 12 Sep 2023 12:28:53 +0000	[thread overview]
Message-ID: <bc5ac28d-a514-dd8a-31ee-25dfa4536a38@microchip.com> (raw)
In-Reply-To: <5f434392-0e87-ecbc-9c9a-ad08a809206a@huawei.com>

Hi Ziyang,

On 11/09/23 6:21 pm, Ziyang Xuan (William) wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> Register MAC-PHY interrupt and handle reset complete interrupt. Reset
>> complete bit is set when the MAC-PHY reset complete and ready for
>> configuration. When it is set, it will generate a non-maskable interrupt
>> to alert the SPI host. Additionally reset complete bit in the STS0
>> register has to be written by one upon reset complete to clear the
>> interrupt.
>>
>> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
>> ---
>>   drivers/net/ethernet/oa_tc6.c | 141 ++++++++++++++++++++++++++++++++--
>>   include/linux/oa_tc6.h        |  16 +++-
>>   2 files changed, 150 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
>> index 613cf034430a..0019f70345b6 100644
>> --- a/drivers/net/ethernet/oa_tc6.c
>> +++ b/drivers/net/ethernet/oa_tc6.c
>> @@ -6,6 +6,7 @@
>>    */
>>
>>   #include <linux/bitfield.h>
>> +#include <linux/interrupt.h>
>>   #include <linux/oa_tc6.h>
>>
>>   static int oa_tc6_spi_transfer(struct spi_device *spi, u8 *ptx, u8 *prx,
>> @@ -160,10 +161,16 @@ int oa_tc6_perform_ctrl(struct oa_tc6 *tc6, u32 addr, u32 val[], u8 len,
>>        if (ret)
>>                goto err_ctrl;
>>
>> -     /* Check echoed/received control reply */
>> -     ret = oa_tc6_check_control(tc6, tx_buf, rx_buf, len, wnr, ctrl_prot);
>> -     if (ret)
>> -             goto err_ctrl;
>> +     /* In case of reset write, the echoed control command doesn't have any
>> +      * valid data. So no need to check for error.
>> +      */
>> +     if (addr != OA_TC6_RESET) {
>> +             /* Check echoed/received control reply */
>> +             ret = oa_tc6_check_control(tc6, tx_buf, rx_buf, len, wnr,
>> +                                        ctrl_prot);
>> +             if (ret)
>> +                     goto err_ctrl;
>> +     }
>>
>>        if (!wnr) {
>>                /* Copy read data from the rx data in case of ctrl read */
>> @@ -186,6 +193,88 @@ int oa_tc6_perform_ctrl(struct oa_tc6 *tc6, u32 addr, u32 val[], u8 len,
>>        return ret;
>>   }
>>
>> +static int oa_tc6_handler(void *data)
>> +{
>> +     struct oa_tc6 *tc6 = data;
>> +     u32 regval;
>> +     int ret;
>> +
>> +     while (likely(!kthread_should_stop())) {
>> +             wait_event_interruptible(tc6->tc6_wq, tc6->int_flag ||
>> +                                      kthread_should_stop());
>> +             if (tc6->int_flag) {
>> +                     tc6->int_flag = false;
>> +                     ret = oa_tc6_perform_ctrl(tc6, OA_TC6_STS0, &regval, 1,
>> +                                               false, false);
>> +                     if (ret) {
>> +                             dev_err(&tc6->spi->dev, "Failed to read STS0\n");
>> +                             continue;
>> +                     }
>> +                     /* Check for reset complete interrupt status */
>> +                     if (regval & RESETC) {
>> +                             regval = RESETC;
>> +                             /* SPI host should write RESETC bit with one to
>> +                              * clear the reset interrupt status.
>> +                              */
>> +                             ret = oa_tc6_perform_ctrl(tc6, OA_TC6_STS0,
>> +                                                       &regval, 1, true,
>> +                                                       false);
>> +                             if (ret) {
>> +                                     dev_err(&tc6->spi->dev,
>> +                                             "Failed to write STS0\n");
>> +                                     continue;
>> +                             }
>> +                             complete(&tc6->rst_complete);
>> +                     }
>> +             }
>> +     }
>> +     return 0;
>> +}
>> +
>> +static irqreturn_t macphy_irq(int irq, void *dev_id)
>> +{
>> +     struct oa_tc6 *tc6 = dev_id;
>> +
>> +     /* Wake tc6 task to perform interrupt action */
>> +     tc6->int_flag = true;
>> +     wake_up_interruptible(&tc6->tc6_wq);
>> +
>> +     return IRQ_HANDLED;
>> +}
>> +
>> +static int oa_tc6_sw_reset(struct oa_tc6 *tc6)
>> +{
>> +     long timeleft;
>> +     u32 regval;
>> +     int ret;
>> +
>> +     /* Perform software reset with both protected and unprotected control
>> +      * commands because the driver doesn't know the current status of the
>> +      * MAC-PHY.
>> +      */
>> +     regval = SW_RESET;
>> +     reinit_completion(&tc6->rst_complete);
>> +     ret = oa_tc6_perform_ctrl(tc6, OA_TC6_RESET, &regval, 1, true, false);
>> +     if (ret) {
>> +             dev_err(&tc6->spi->dev, "RESET register write failed\n");
>> +             return ret;
>> +     }
>> +
>> +     ret = oa_tc6_perform_ctrl(tc6, OA_TC6_RESET, &regval, 1, true, true);
>> +     if (ret) {
>> +             dev_err(&tc6->spi->dev, "RESET register write failed\n");
>> +             return ret;
>> +     }
>> +     timeleft = wait_for_completion_interruptible_timeout(&tc6->rst_complete,
>> +                                                          msecs_to_jiffies(1));
>> +     if (timeleft <= 0) {
>> +             dev_err(&tc6->spi->dev, "MAC-PHY reset failed\n");
>> +             return -ENODEV;
>> +     }
>> +
>> +     return 0;
>> +}
>> +
>>   int oa_tc6_write_register(struct oa_tc6 *tc6, u32 addr, u32 val[], u8 len)
>>   {
>>        return oa_tc6_perform_ctrl(tc6, addr, val, len, true, tc6->ctrl_prot);
>> @@ -201,6 +290,7 @@ EXPORT_SYMBOL_GPL(oa_tc6_read_register);
>>   struct oa_tc6 *oa_tc6_init(struct spi_device *spi)
>>   {
>>        struct oa_tc6 *tc6;
>> +     int ret;
>>
>>        if (!spi)
>>                return NULL;
>> @@ -211,12 +301,51 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi)
>>
>>        tc6->spi = spi;
>>
>> +     /* Used for triggering the OA TC6 task */
>> +     init_waitqueue_head(&tc6->tc6_wq);
>> +
>> +     init_completion(&tc6->rst_complete);
>> +
>> +     /* This task performs the SPI transfer */
>> +     tc6->tc6_task = kthread_run(oa_tc6_handler, tc6, "OA TC6 Task");
>> +     if (IS_ERR(tc6->tc6_task))
>> +             goto err_tc6_task;
>> +
>> +     /* Set the highest priority to the tc6 task as it is time critical */
>> +     sched_set_fifo(tc6->tc6_task);
>> +
>> +     /* Register MAC-PHY interrupt service routine */
>> +     ret = devm_request_irq(&spi->dev, spi->irq, macphy_irq, 0, "macphy int",
>> +                            tc6);
>> +     if ((ret != -ENOTCONN) && ret < 0) {
>> +             dev_err(&spi->dev, "Error attaching macphy irq %d\n", ret);
>> +             goto err_macphy_irq;
>> +     }
>> +
>> +     /* Perform MAC-PHY software reset */
>> +     if (oa_tc6_sw_reset(tc6))
>> +             goto err_macphy_reset;
>> +
>>        return tc6;
>> +
>> +err_macphy_reset:
>> +     devm_free_irq(&tc6->spi->dev, tc6->spi->irq, tc6);
>> +err_macphy_irq:
>> +     kthread_stop(tc6->tc6_task);
>> +err_tc6_task:
>> +     kfree(tc6);
>> +     return NULL;
>>   }
>>   EXPORT_SYMBOL_GPL(oa_tc6_init);
>>
>> -void oa_tc6_deinit(struct oa_tc6 *tc6)
>> +int oa_tc6_deinit(struct oa_tc6 *tc6)
>>   {
>> -     kfree(tc6);
>> +     int ret;
>> +
>> +     devm_free_irq(&tc6->spi->dev, tc6->spi->irq, tc6);
>> +     ret = kthread_stop(tc6->tc6_task);
> 
> kthread_stop() will the result of threadfn(). Here mean that if threadfn()
> return non-zero, deinit() will fail. But the KTHREAD_SHOULD_STOP already be set.
> And oa_tc6_handler() will end. Please check it is what you want.
Ok will handle it properly in the next revision.

Best Regards,
Parthiban V
> 
>> +     if (!ret)
>> +             kfree(tc6);
>> +     return ret;
>>   }
>>   EXPORT_SYMBOL_GPL(oa_tc6_deinit);
>> diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h
>> index 5e0a58ab1dcd..315f061c2dfe 100644
>> --- a/include/linux/oa_tc6.h
>> +++ b/include/linux/oa_tc6.h
>> @@ -17,15 +17,29 @@
>>   #define CTRL_HDR_LEN GENMASK(7, 1)   /* Length */
>>   #define CTRL_HDR_P   BIT(0)          /* Parity Bit */
>>
>> +/* Open Alliance TC6 Standard Control and Status Registers */
>> +#define OA_TC6_RESET 0x0003          /* Reset Control and Status Register */
>> +#define OA_TC6_STS0  0x0008          /* Status Register #0 */
>> +
>> +/* RESET register field */
>> +#define SW_RESET     BIT(0)          /* Software Reset */
>> +
>> +/* STATUS0 register field */
>> +#define RESETC               BIT(6)          /* Reset Complete */
>> +
>>   #define TC6_HDR_SIZE 4               /* Ctrl command header size as per OA */
>>   #define TC6_FTR_SIZE 4               /* Ctrl command footer size ss per OA */
>>
>>   struct oa_tc6 {
>>        struct spi_device *spi;
>>        bool ctrl_prot;
>> +     struct task_struct *tc6_task;
>> +     wait_queue_head_t tc6_wq;
>> +     bool int_flag;
>> +     struct completion rst_complete;
>>   };
>>
>>   struct oa_tc6 *oa_tc6_init(struct spi_device *spi);
>> -void oa_tc6_deinit(struct oa_tc6 *tc6);
>> +int oa_tc6_deinit(struct oa_tc6 *tc6);
>>   int oa_tc6_write_register(struct oa_tc6 *tc6, u32 addr, u32 value[], u8 len);
>>   int oa_tc6_read_register(struct oa_tc6 *tc6, u32 addr, u32 value[], u8 len);
>>


  parent reply	other threads:[~2023-09-12 12:29 UTC|newest]

Thread overview: 84+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-08 14:29 [RFC PATCH net-next 0/6] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
2023-09-08 14:29 ` [RFC PATCH net-next 1/6] net: ethernet: implement OPEN Alliance control transaction interface Parthiban Veerasooran
2023-09-09 13:33   ` Andrew Lunn
2023-09-12 13:03     ` Parthiban.Veerasooran
2023-09-13  1:32       ` Andrew Lunn
2023-09-21 12:27         ` Parthiban.Veerasooran
2023-09-21 19:16           ` Andrew Lunn
2023-09-22  4:31             ` Parthiban.Veerasooran
2023-09-13  1:36   ` Andrew Lunn
2023-09-19 11:40     ` Parthiban.Veerasooran
2023-09-13  2:11   ` Andrew Lunn
2023-09-19 11:38     ` Parthiban.Veerasooran
2023-09-19 15:13       ` Andrew Lunn
2023-09-20 12:40         ` Parthiban.Veerasooran
2023-09-20 13:37           ` Andrew Lunn
2023-09-21  9:15             ` Parthiban.Veerasooran
2023-09-13  2:16   ` Andrew Lunn
2023-09-19 11:13     ` Parthiban.Veerasooran
2023-09-19 12:58       ` Andrew Lunn
2023-09-21 12:36         ` Parthiban.Veerasooran
2023-09-21 19:19           ` Andrew Lunn
2023-09-22  4:39             ` Parthiban.Veerasooran
2023-09-26 12:54               ` Fwd: " Parthiban.Veerasooran
2023-09-08 14:29 ` [RFC PATCH net-next 2/6] net: ethernet: add mac-phy interrupt support with reset complete handling Parthiban Veerasooran
2023-09-09 13:39   ` Andrew Lunn
2023-09-12 12:44     ` Parthiban.Veerasooran
2023-09-13  2:19       ` Andrew Lunn
2023-09-19 11:04         ` Parthiban.Veerasooran
2023-09-11 12:51   ` Ziyang Xuan (William)
2023-09-12 12:10     ` Andrew Lunn
2023-09-12 12:28     ` Parthiban.Veerasooran [this message]
2023-09-13  2:39   ` Andrew Lunn
2023-09-19 13:07     ` Parthiban.Veerasooran
2023-09-19 13:21       ` Lukasz Majewski
2023-09-13  8:44   ` Lukasz Majewski
2023-09-13 12:36     ` Andrew Lunn
2023-09-13 13:26       ` Lukasz Majewski
2023-09-19 13:40         ` Parthiban.Veerasooran
2023-09-19 13:51           ` Lukasz Majewski
2023-09-08 14:29 ` [RFC PATCH net-next 3/6] net: ethernet: implement OA TC6 configuration function Parthiban Veerasooran
2023-09-14  0:46   ` Andrew Lunn
2023-09-19 10:57     ` Parthiban.Veerasooran
2023-09-19 12:54       ` Andrew Lunn
2023-09-20 12:42         ` Parthiban.Veerasooran
2023-09-08 14:29 ` [RFC PATCH net-next 4/6] net: ethernet: implement data transaction interface Parthiban Veerasooran
2023-09-10 17:58   ` Simon Horman
2023-09-12 13:47     ` Parthiban.Veerasooran
2023-09-11 12:59   ` Ziyang Xuan (William)
2023-09-12 10:32     ` Parthiban.Veerasooran
2023-09-14  1:18   ` Andrew Lunn
2023-09-18 10:02     ` Parthiban.Veerasooran
2023-09-18 13:01       ` Andrew Lunn
2023-09-19 10:12         ` Parthiban.Veerasooran
2023-09-08 14:29 ` [RFC PATCH net-next 5/6] microchip: lan865x: add driver support for Microchip's LAN865X MACPHY Parthiban Veerasooran
2023-09-10 17:44   ` Simon Horman
2023-09-12 10:53     ` Parthiban.Veerasooran
2023-09-11 13:17   ` Ziyang Xuan (William)
2023-09-12 11:41     ` Parthiban.Veerasooran
2023-09-14  1:51   ` Andrew Lunn
2023-09-19  9:18     ` Parthiban.Veerasooran
2023-09-19 12:50       ` Andrew Lunn
2023-09-20 12:53         ` Parthiban.Veerasooran
2023-09-14  1:55   ` Andrew Lunn
2023-09-18 11:23     ` Parthiban.Veerasooran
2023-09-15 13:01   ` David Wretman
2023-09-18 11:22     ` Parthiban.Veerasooran
2023-09-08 14:29 ` [RFC PATCH net-next 6/6] microchip: lan865x: add device-tree " Parthiban Veerasooran
2023-09-10 10:55   ` Krzysztof Kozlowski
2023-09-12 12:15     ` Parthiban.Veerasooran
2023-09-12 13:17       ` Krzysztof Kozlowski
2023-09-19 10:51         ` Parthiban.Veerasooran
2023-09-14  2:07   ` Andrew Lunn
2023-09-19 10:40     ` Parthiban.Veerasooran
2023-09-10 10:55 ` [RFC PATCH net-next 0/6] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Krzysztof Kozlowski
     [not found]   ` <fab8908e-ce74-eff0-8e67-6259b3ad5e1e@microchip.com>
2023-09-13 15:45     ` Krzysztof Kozlowski
2023-09-18  9:23       ` Parthiban.Veerasooran
2023-09-15 13:56 ` Alexander Dahl
2023-09-15 14:22   ` Andrew Lunn
2023-09-18  6:16     ` Parthiban.Veerasooran
2023-09-18  6:12   ` Parthiban.Veerasooran
2023-09-18  9:02     ` Fwd: " Parthiban.Veerasooran
2023-09-19  9:03       ` Parthiban.Veerasooran
2023-09-19 16:23         ` Jay Monkman
2023-09-19 18:09         ` Hennerich, Michael

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bc5ac28d-a514-dd8a-31ee-25dfa4536a38@microchip.com \
    --to=parthiban.veerasooran@microchip.com \
    --cc=Horatiu.Vultur@microchip.com \
    --cc=Nicolas.Ferre@microchip.com \
    --cc=Steen.Hegelund@microchip.com \
    --cc=Thorsten.Kummermehr@microchip.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=Woojung.Huh@microchip.com \
    --cc=andrew@lunn.ch \
    --cc=casper.casan@gmail.com \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=rdunlap@infradead.org \
    --cc=robh+dt@kernel.org \
    --cc=william.xuanziyang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).