[PATCH 1/2] watchdog: Add a driver for the photonicat watchdog
Stefan Roese
sr at denx.de
Tue Oct 22 12:46:07 CEST 2024
On 8/29/24 10:30, Coia Prant wrote:
> This driver supports the photonicat watchdog timers.
>
> Signed-off-by: Coia Prant <coiaprant at gmail.com>
Why did you send this driver twice? Please send only 1/1 patch next
time.
> ---
> drivers/watchdog/Kconfig | 6 +
> drivers/watchdog/Makefile | 1 +
> drivers/watchdog/pcat_wdt.c | 218 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 225 insertions(+)
> create mode 100644 drivers/watchdog/pcat_wdt.c
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 0c3e9913..f0a52ecf 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -421,4 +421,10 @@ config WDT_FTWDT010
> help
> Faraday Technology ftwdt010 watchdog is an architecture independent
> watchdog. It is usually used in SoC chip design.
> +
> +config WDT_PCAT
> + bool "photonicat board watchdog support"
> + depends on WDT && SERIAL && DM
> + help
> + Select this to enable watchdog timer on photonicat board.
What is a "photonicat board"? Which SoC is used? Manufacturer?
And empty line missing here?
> endmenu
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 7b39adcf..829b5ed1 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -50,3 +50,4 @@ obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
> obj-$(CONFIG_WDT_SUNXI) += sunxi_wdt.o
> obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o
> obj-$(CONFIG_WDT_XILINX) += xilinx_wwdt.o
> +obj-$(CONFIG_WDT_PCAT) += pcat_wdt.o
Please sort alphabetically.
> \ No newline at end of file
> diff --git a/drivers/watchdog/pcat_wdt.c b/drivers/watchdog/pcat_wdt.c
> new file mode 100644
> index 00000000..cac07fb6
> --- /dev/null
> +++ b/drivers/watchdog/pcat_wdt.c
> @@ -0,0 +1,218 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include <dm.h>
> +#include <dm/device_compat.h>
> +#include <wdt.h>
> +#include <asm/gpio.h>
> +#include <linux/delay.h>
> +#include <serial.h>
> +#include <dm/device-internal.h>
Sorting of header includes looks not correct.
> +
> +struct pcat_wdt_priv
> +{
> + struct udevice *serial_dev;
> + struct dm_serial_ops *serial_ops;
> + uint16_t packet_count;
> +};
> +
> +static uint16_t pcat_pmu_serial_compute_crc16(const uint8_t *data,
> + size_t len)
alignment?
> +{
> + uint16_t crc = 0xFFFF;
> + size_t i;
> + unsigned int j;
> +
> + for (i = 0; i < len; i++)
> + {
Coding style is wrong. Please use Linux coding style with U-Boot code as
well. scripts/checkpatch.pl will help you finding issues.
I'll stop the review here and will continue, once you've sent v2.
Thanks,
Stefan
> + crc ^= data[i];
> + for (j = 0; j < 8; j++)
> + {
> + if (crc & 1)
> + {
> + crc = (crc >> 1) ^ 0xA001;
> + }
> + else
> + {
> + crc >>= 1;
> + }
> + }
> + }
> +
> + return crc;
> +}
> +
> +static int pcat_wdt_reset(struct udevice *dev)
> +{
> + struct pcat_wdt_priv *priv = dev_get_priv(dev);
> + uint8_t packet[13] = "\xA5\x01\x81\x00\x00\x03\x00\x01\x00"
> + "\x00\x00\x00\x5A";
> + uint16_t crc;
> + int err = 0;
> + unsigned int i;
> +
> + packet[3] = priv->packet_count & 0xFF;
> + packet[4] = (priv->packet_count >> 8) & 0xFF;
> + priv->packet_count++;
> +
> + crc = pcat_pmu_serial_compute_crc16(packet + 1, 9);
> + packet[10] = crc & 0xFF;
> + packet[11] = (crc >> 8) & 0xFF;
> +
> + i = 0;
> + while (i < 13)
> + {
> + err = priv->serial_ops->putc(
> + priv->serial_dev, ((const char *)packet)[i]);
> + if (!err)
> + {
> + i++;
> + }
> + else if (err == -EAGAIN)
> + {
> + ;
> + }
> + else
> + {
> + pr_err("%s: unable to send watchdog setup "
> + "request: %d\n",
> + __func__, err);
> + break;
> + }
> + }
> + return err;
> +}
> +
> +static int pcat_wdt_setup(struct pcat_wdt_priv *priv, u64 timeout)
> +{
> + uint8_t packet[16] = "\xA5\x01\x81\x00\x00\x06\x00\x13\x00"
> + "\x3C\x3C\x00\x00\x00\x00\x5A";
> + uint16_t crc;
> + int err = 0;
> + unsigned int i;
> +
> + if (timeout > 255)
> + {
> + pr_warn("%s: timeout cannot be more than 255s\n",
> + __func__);
> + timeout = 255;
> + }
> +
> + packet[3] = priv->packet_count & 0xFF;
> + packet[4] = (priv->packet_count >> 8) & 0xFF;
> + priv->packet_count++;
> + packet[11] = timeout & 0xFF;
> +
> + crc = pcat_pmu_serial_compute_crc16(packet + 1, 12);
> + packet[13] = crc & 0xFF;
> + packet[14] = (crc >> 8) & 0xFF;
> +
> + i = 0;
> + while (i < 16)
> + {
> + err = priv->serial_ops->putc(
> + priv->serial_dev, ((const char *)packet)[i]);
> + if (!err)
> + {
> + i++;
> + }
> + else if (err == -EAGAIN)
> + {
> + ;
> + }
> + else
> + {
> + pr_err("%s: unable to send watchdog setup "
> + "request: %d\n",
> + __func__, err);
> + break;
> + }
> + }
> +
> + return err;
> +}
> +
> +static int pcat_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
> +{
> + struct pcat_wdt_priv *priv = dev_get_priv(dev);
> +
> + pcat_wdt_setup(priv, timeout);
> +
> + return 0;
> +}
> +
> +static int pcat_wdt_stop(struct udevice *dev)
> +{
> + struct pcat_wdt_priv *priv = dev_get_priv(dev);
> +
> + pcat_wdt_setup(priv, 0);
> +
> + return 0;
> +}
> +
> +static int dm_probe(struct udevice *dev)
> +{
> + struct pcat_wdt_priv *priv = dev_get_priv(dev);
> + struct udevice *serial_dev = NULL;
> + struct dm_serial_ops *ops;
> + int ret;
> +
> + ret = uclass_get_device_by_phandle(UCLASS_SERIAL, dev, "port",
> + &serial_dev);
> + if (ret)
> + {
> + pr_err("%s: unable to find serial port device: %d\n",
> + __func__, ret);
> + return ret;
> + }
> +
> + ret = device_probe(serial_dev);
> + if (ret)
> + {
> + pr_err("%s: unable to probe serial port device: %d\n",
> + __func__, ret);
> + return ret;
> + }
> +
> + ops = serial_get_ops(serial_dev);
> + if (!ops)
> + {
> + printf("Cannot get ops for PMU serial port!\n");
> + return -EINVAL;
> + }
> +
> + if (ops->setconfig)
> + {
> + ops->setconfig(serial_dev, SERIAL_DEFAULT_CONFIG);
> + }
> + if (ops->setbrg)
> + {
> + ops->setbrg(serial_dev, 115200);
> + }
> +
> + priv->serial_dev = serial_dev;
> + priv->serial_ops = ops;
> + priv->packet_count = 0;
> +
> + pcat_wdt_stop(dev);
> +
> + return 0;
> +}
> +
> +static const struct wdt_ops pcat_wdt_ops = {
> + .start = pcat_wdt_start,
> + .reset = pcat_wdt_reset,
> + .stop = pcat_wdt_stop,
> +};
> +
> +static const struct udevice_id pcat_wdt_ids[] = {
> + {.compatible = "linux,wdt-pcat"},
> + {}};
> +
> +U_BOOT_DRIVER(wdt_pcat) = {
> + .name = "wdt_pcat",
> + .id = UCLASS_WDT,
> + .of_match = pcat_wdt_ids,
> + .ops = &pcat_wdt_ops,
> + .probe = dm_probe,
> + .priv_auto = sizeof(struct pcat_wdt_priv),
> +};
> \ No newline at end of file
Viele Grüße,
Stefan Roese
--
DENX Software Engineering GmbH, Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de
More information about the U-Boot
mailing list