From: Piyush Mehta <piyush.mehta@xilinx.com> To: <arnd@arndb.de>, <zou_wei@huawei.com>, <gregkh@linuxfoundation.org>, <linus.walleij@linaro.org>, <michal.simek@xilinx.com>, <wendy.liang@xilinx.com>, <iwamatsu@nigauri.org>, <bgolaszewski@baylibre.com>, <robh+dt@kernel.org>, <rajan.vaja@xilinx.com> Cc: <linux-gpio@vger.kernel.org>, <devicetree@vger.kernel.org>, <git@xilinx.com>, <sgoud@xilinx.com>, <linux-arm-kernel@lists.infradead.org>, <linux-kernel@vger.kernel.org>, Piyush Mehta <piyush.mehta@xilinx.com> Subject: [PATCH V4 3/3] gpio: modepin: Add driver support for modepin GPIO controller Date: Wed, 22 Sep 2021 19:23:19 +0530 [thread overview] Message-ID: <20210922135319.3128153-4-piyush.mehta@xilinx.com> (raw) In-Reply-To: <20210922135319.3128153-1-piyush.mehta@xilinx.com> This patch adds driver support for the zynqmp modepin GPIO controller. GPIO modepin driver set and get the value and status of the PS_MODE pin, based on device-tree pin configuration. These four mode pins are configurable as input/output. The mode pin has a control register, which have lower four-bits [0:3] are configurable as input/output, next four-bits can be used for reading the data as input[4:7], and next setting the output pin state output[8:11]. By default value of mode pin register is 0. Signed-off-by: Piyush Mehta <piyush.mehta@xilinx.com> Acked-by: Michal Simek <michal.simek@xilinx.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> --- Changes in v2: - Modepin driver- Addressed review comments: - Update APIs - Removed unwanted variables - Handle return path for probe function Review Comments: https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta@xilinx.com/T/#m276c8a5c52f8dc1ed1cd91a2d660f78d498e4ae5 Changes in v3: - Addressed Linus and Arnd review comments: - Update probe function return value - Remove unnecessary print and header file - Update error message for set value method Review Comments: https://lore.kernel.org/linux-arm-kernel/20210805174219.3000667-4-piyush.mehta@xilinx.com/T/#m70acd39653033e32458633e21a2e6d21afdd16e6 Changes in v4: - Added input pin read status in modepin_gpio_get_value. - Updated modepin control bit for out configuration on set_value. Review Comments: https://lore.kernel.org/linux-arm-kernel/554508f5-8cb5-3840-9f61-f6cd6e5745d2@xilinx.com/T/#u https://lore.kernel.org/linux-arm-kernel/554508f5-8cb5-3840-9f61-f6cd6e5745d2@xilinx.com/T/#m60039005ebee312260d344c7d4383acb43c50f0f --- drivers/gpio/Kconfig | 12 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-zynqmp-modepin.c | 162 +++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 drivers/gpio/gpio-zynqmp-modepin.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index fae5141..37a6f77 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -763,6 +763,18 @@ config GPIO_ZYNQ help Say yes here to support Xilinx Zynq GPIO controller. +config GPIO_ZYNQMP_MODEPIN + tristate "ZynqMP ps-mode pin gpio configuration driver" + depends on ZYNQMP_FIRMWARE + default ZYNQMP_FIRMWARE + help + Say yes here to support the ZynqMP ps-mode pin gpio configuration + driver. + + This ps-mode pin gpio driver is based on GPIO framework, PS_MODE + is 4-bits boot mode pins. It sets and gets the status of + the ps-mode pin. Every pin can be configured as input/output. + config GPIO_LOONGSON1 tristate "Loongson1 GPIO support" depends on MACH_LOONGSON32 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fbcda63..71ee9fc2 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -184,3 +184,4 @@ obj-$(CONFIG_GPIO_XRA1403) += gpio-xra1403.o obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o +obj-$(CONFIG_GPIO_ZYNQMP_MODEPIN) += gpio-zynqmp-modepin.o diff --git a/drivers/gpio/gpio-zynqmp-modepin.c b/drivers/gpio/gpio-zynqmp-modepin.c new file mode 100644 index 0000000..a0d6938 --- /dev/null +++ b/drivers/gpio/gpio-zynqmp-modepin.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for the ps-mode pin configuration. + * + * Copyright (c) 2021 Xilinx, Inc. + */ + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/gpio/driver.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/firmware/xlnx-zynqmp.h> + +/* 4-bit boot mode pins */ +#define MODE_PINS 4 + +/** + * modepin_gpio_get_value - Get the state of the specified pin of GPIO device + * @chip: gpio_chip instance to be worked on + * @pin: gpio pin number within the device + * + * This function reads the state of the specified pin of the GPIO device. + * + * Return: 0 if the pin is low, 1 if pin is high, -EINVAL wrong pin configured + * or error value. + */ +static int modepin_gpio_get_value(struct gpio_chip *chip, unsigned int pin) +{ + u32 regval = 0; + int ret; + + ret = zynqmp_pm_bootmode_read(®val); + if (ret) + return ret; + + /* When [0:3] corresponding bit is set, then read output bit [8:11], + * if the bit is clear then read input bit [4:7] for status or value. + */ + if (regval & BIT(pin)) + return !!(regval & BIT(pin + 8)); + else + return !!(regval & BIT(pin + 4)); +} + +/** + * modepin_gpio_set_value - Modify the state of the pin with specified value + * @chip: gpio_chip instance to be worked on + * @pin: gpio pin number within the device + * @state: value used to modify the state of the specified pin + * + * This function reads the state of the specified pin of the GPIO device, mask + * with the capture state of GPIO pin, and update pin of GPIO device. + * + * Return: None. + */ +static void modepin_gpio_set_value(struct gpio_chip *chip, unsigned int pin, + int state) +{ + u32 bootpin_val = 0; + int ret; + + zynqmp_pm_bootmode_read(&bootpin_val); + + /* Configure pin as an output by set bit [0:3] */ + bootpin_val |= BIT(pin); + + if (state) + bootpin_val |= BIT(pin + 8); + else + bootpin_val &= ~BIT(pin + 8); + + /* Configure bootpin value */ + ret = zynqmp_pm_bootmode_write(bootpin_val); + if (ret) + pr_err("modepin: set value error %d for pin %d\n", ret, pin); +} + +/** + * modepin_gpio_dir_in - Set the direction of the specified GPIO pin as input + * @chip: gpio_chip instance to be worked on + * @pin: gpio pin number within the device + * + * Return: 0 always + */ +static int modepin_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) +{ + return 0; +} + +/** + * modepin_gpio_dir_out - Set the direction of the specified GPIO pin as output + * @chip: gpio_chip instance to be worked on + * @pin: gpio pin number within the device + * @state: value to be written to specified pin + * + * Return: 0 always + */ +static int modepin_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, + int state) +{ + return 0; +} + +/** + * modepin_gpio_probe - Initialization method for modepin_gpio + * @pdev: platform device instance + * + * Return: 0 on success, negative error otherwise. + */ +static int modepin_gpio_probe(struct platform_device *pdev) +{ + struct gpio_chip *chip; + int status; + + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + platform_set_drvdata(pdev, chip); + + /* configure the gpio chip */ + chip->base = -1; + chip->ngpio = MODE_PINS; + chip->owner = THIS_MODULE; + chip->parent = &pdev->dev; + chip->get = modepin_gpio_get_value; + chip->set = modepin_gpio_set_value; + chip->direction_input = modepin_gpio_dir_in; + chip->direction_output = modepin_gpio_dir_out; + chip->label = dev_name(&pdev->dev); + + /* modepin gpio registration */ + status = devm_gpiochip_add_data(&pdev->dev, chip, chip); + if (status) + return dev_err_probe(&pdev->dev, status, + "Failed to add GPIO chip\n"); + + return status; +} + +static const struct of_device_id modepin_platform_id[] = { + { .compatible = "xlnx,zynqmp-gpio-modepin", }, + { } +}; + +static struct platform_driver modepin_platform_driver = { + .driver = { + .name = "modepin-gpio", + .of_match_table = modepin_platform_id, + }, + .probe = modepin_gpio_probe, +}; + +module_platform_driver(modepin_platform_driver); + +MODULE_AUTHOR("Piyush Mehta <piyush.mehta@xilinx.com>"); +MODULE_DESCRIPTION("ZynqMP Boot PS_MODE Configuration"); +MODULE_LICENSE("GPL v2"); -- 2.7.4
WARNING: multiple messages have this Message-ID
From: Piyush Mehta <piyush.mehta@xilinx.com> To: <arnd@arndb.de>, <zou_wei@huawei.com>, <gregkh@linuxfoundation.org>, <linus.walleij@linaro.org>, <michal.simek@xilinx.com>, <wendy.liang@xilinx.com>, <iwamatsu@nigauri.org>, <bgolaszewski@baylibre.com>, <robh+dt@kernel.org>, <rajan.vaja@xilinx.com> Cc: <linux-gpio@vger.kernel.org>, <devicetree@vger.kernel.org>, <git@xilinx.com>, <sgoud@xilinx.com>, <linux-arm-kernel@lists.infradead.org>, <linux-kernel@vger.kernel.org>, Piyush Mehta <piyush.mehta@xilinx.com> Subject: [PATCH V4 3/3] gpio: modepin: Add driver support for modepin GPIO controller Date: Wed, 22 Sep 2021 19:23:19 +0530 [thread overview] Message-ID: <20210922135319.3128153-4-piyush.mehta@xilinx.com> (raw) In-Reply-To: <20210922135319.3128153-1-piyush.mehta@xilinx.com> This patch adds driver support for the zynqmp modepin GPIO controller. GPIO modepin driver set and get the value and status of the PS_MODE pin, based on device-tree pin configuration. These four mode pins are configurable as input/output. The mode pin has a control register, which have lower four-bits [0:3] are configurable as input/output, next four-bits can be used for reading the data as input[4:7], and next setting the output pin state output[8:11]. By default value of mode pin register is 0. Signed-off-by: Piyush Mehta <piyush.mehta@xilinx.com> Acked-by: Michal Simek <michal.simek@xilinx.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> --- Changes in v2: - Modepin driver- Addressed review comments: - Update APIs - Removed unwanted variables - Handle return path for probe function Review Comments: https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta@xilinx.com/T/#m276c8a5c52f8dc1ed1cd91a2d660f78d498e4ae5 Changes in v3: - Addressed Linus and Arnd review comments: - Update probe function return value - Remove unnecessary print and header file - Update error message for set value method Review Comments: https://lore.kernel.org/linux-arm-kernel/20210805174219.3000667-4-piyush.mehta@xilinx.com/T/#m70acd39653033e32458633e21a2e6d21afdd16e6 Changes in v4: - Added input pin read status in modepin_gpio_get_value. - Updated modepin control bit for out configuration on set_value. Review Comments: https://lore.kernel.org/linux-arm-kernel/554508f5-8cb5-3840-9f61-f6cd6e5745d2@xilinx.com/T/#u https://lore.kernel.org/linux-arm-kernel/554508f5-8cb5-3840-9f61-f6cd6e5745d2@xilinx.com/T/#m60039005ebee312260d344c7d4383acb43c50f0f --- drivers/gpio/Kconfig | 12 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-zynqmp-modepin.c | 162 +++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 drivers/gpio/gpio-zynqmp-modepin.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index fae5141..37a6f77 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -763,6 +763,18 @@ config GPIO_ZYNQ help Say yes here to support Xilinx Zynq GPIO controller. +config GPIO_ZYNQMP_MODEPIN + tristate "ZynqMP ps-mode pin gpio configuration driver" + depends on ZYNQMP_FIRMWARE + default ZYNQMP_FIRMWARE + help + Say yes here to support the ZynqMP ps-mode pin gpio configuration + driver. + + This ps-mode pin gpio driver is based on GPIO framework, PS_MODE + is 4-bits boot mode pins. It sets and gets the status of + the ps-mode pin. Every pin can be configured as input/output. + config GPIO_LOONGSON1 tristate "Loongson1 GPIO support" depends on MACH_LOONGSON32 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fbcda63..71ee9fc2 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -184,3 +184,4 @@ obj-$(CONFIG_GPIO_XRA1403) += gpio-xra1403.o obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o +obj-$(CONFIG_GPIO_ZYNQMP_MODEPIN) += gpio-zynqmp-modepin.o diff --git a/drivers/gpio/gpio-zynqmp-modepin.c b/drivers/gpio/gpio-zynqmp-modepin.c new file mode 100644 index 0000000..a0d6938 --- /dev/null +++ b/drivers/gpio/gpio-zynqmp-modepin.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for the ps-mode pin configuration. + * + * Copyright (c) 2021 Xilinx, Inc. + */ + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/gpio/driver.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/firmware/xlnx-zynqmp.h> + +/* 4-bit boot mode pins */ +#define MODE_PINS 4 + +/** + * modepin_gpio_get_value - Get the state of the specified pin of GPIO device + * @chip: gpio_chip instance to be worked on + * @pin: gpio pin number within the device + * + * This function reads the state of the specified pin of the GPIO device. + * + * Return: 0 if the pin is low, 1 if pin is high, -EINVAL wrong pin configured + * or error value. + */ +static int modepin_gpio_get_value(struct gpio_chip *chip, unsigned int pin) +{ + u32 regval = 0; + int ret; + + ret = zynqmp_pm_bootmode_read(®val); + if (ret) + return ret; + + /* When [0:3] corresponding bit is set, then read output bit [8:11], + * if the bit is clear then read input bit [4:7] for status or value. + */ + if (regval & BIT(pin)) + return !!(regval & BIT(pin + 8)); + else + return !!(regval & BIT(pin + 4)); +} + +/** + * modepin_gpio_set_value - Modify the state of the pin with specified value + * @chip: gpio_chip instance to be worked on + * @pin: gpio pin number within the device + * @state: value used to modify the state of the specified pin + * + * This function reads the state of the specified pin of the GPIO device, mask + * with the capture state of GPIO pin, and update pin of GPIO device. + * + * Return: None. + */ +static void modepin_gpio_set_value(struct gpio_chip *chip, unsigned int pin, + int state) +{ + u32 bootpin_val = 0; + int ret; + + zynqmp_pm_bootmode_read(&bootpin_val); + + /* Configure pin as an output by set bit [0:3] */ + bootpin_val |= BIT(pin); + + if (state) + bootpin_val |= BIT(pin + 8); + else + bootpin_val &= ~BIT(pin + 8); + + /* Configure bootpin value */ + ret = zynqmp_pm_bootmode_write(bootpin_val); + if (ret) + pr_err("modepin: set value error %d for pin %d\n", ret, pin); +} + +/** + * modepin_gpio_dir_in - Set the direction of the specified GPIO pin as input + * @chip: gpio_chip instance to be worked on + * @pin: gpio pin number within the device + * + * Return: 0 always + */ +static int modepin_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) +{ + return 0; +} + +/** + * modepin_gpio_dir_out - Set the direction of the specified GPIO pin as output + * @chip: gpio_chip instance to be worked on + * @pin: gpio pin number within the device + * @state: value to be written to specified pin + * + * Return: 0 always + */ +static int modepin_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, + int state) +{ + return 0; +} + +/** + * modepin_gpio_probe - Initialization method for modepin_gpio + * @pdev: platform device instance + * + * Return: 0 on success, negative error otherwise. + */ +static int modepin_gpio_probe(struct platform_device *pdev) +{ + struct gpio_chip *chip; + int status; + + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + platform_set_drvdata(pdev, chip); + + /* configure the gpio chip */ + chip->base = -1; + chip->ngpio = MODE_PINS; + chip->owner = THIS_MODULE; + chip->parent = &pdev->dev; + chip->get = modepin_gpio_get_value; + chip->set = modepin_gpio_set_value; + chip->direction_input = modepin_gpio_dir_in; + chip->direction_output = modepin_gpio_dir_out; + chip->label = dev_name(&pdev->dev); + + /* modepin gpio registration */ + status = devm_gpiochip_add_data(&pdev->dev, chip, chip); + if (status) + return dev_err_probe(&pdev->dev, status, + "Failed to add GPIO chip\n"); + + return status; +} + +static const struct of_device_id modepin_platform_id[] = { + { .compatible = "xlnx,zynqmp-gpio-modepin", }, + { } +}; + +static struct platform_driver modepin_platform_driver = { + .driver = { + .name = "modepin-gpio", + .of_match_table = modepin_platform_id, + }, + .probe = modepin_gpio_probe, +}; + +module_platform_driver(modepin_platform_driver); + +MODULE_AUTHOR("Piyush Mehta <piyush.mehta@xilinx.com>"); +MODULE_DESCRIPTION("ZynqMP Boot PS_MODE Configuration"); +MODULE_LICENSE("GPL v2"); -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-09-22 13:54 UTC|newest] Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-09-22 13:53 [PATCH V4 0/3] " Piyush Mehta 2021-09-22 13:53 ` Piyush Mehta 2021-09-22 13:53 ` [PATCH V4 1/3] firmware: zynqmp: Add MMIO read and write support for PS_MODE pin Piyush Mehta 2021-09-22 13:53 ` Piyush Mehta 2021-09-22 13:53 ` [PATCH V4 2/3] dt-bindings: gpio: zynqmp: Add binding documentation for modepin Piyush Mehta 2021-09-22 13:53 ` Piyush Mehta 2021-09-22 13:53 ` Piyush Mehta [this message] 2021-09-22 13:53 ` [PATCH V4 3/3] gpio: modepin: Add driver support for modepin GPIO controller Piyush Mehta 2021-09-23 8:10 ` [PATCH V4 0/3] " Bartosz Golaszewski 2021-09-23 8:10 ` Bartosz Golaszewski
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=20210922135319.3128153-4-piyush.mehta@xilinx.com \ --to=piyush.mehta@xilinx.com \ --cc=arnd@arndb.de \ --cc=bgolaszewski@baylibre.com \ --cc=devicetree@vger.kernel.org \ --cc=git@xilinx.com \ --cc=gregkh@linuxfoundation.org \ --cc=iwamatsu@nigauri.org \ --cc=linus.walleij@linaro.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-gpio@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=michal.simek@xilinx.com \ --cc=rajan.vaja@xilinx.com \ --cc=robh+dt@kernel.org \ --cc=sgoud@xilinx.com \ --cc=wendy.liang@xilinx.com \ --cc=zou_wei@huawei.com \ --subject='Re: [PATCH V4 3/3] gpio: modepin: Add driver support for modepin GPIO controller' \ /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
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.