diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-08 09:46:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-08 09:46:29 -0700 |
commit | f01603979a4afaad7504a728918b678d572cda9e (patch) | |
tree | c88ced8221cbc6eba9e1ea8a421d7cae7c9f8cd5 /drivers/gpio/gpio-imx-scu.c | |
parent | 3002b7a31894cfa0e57080f7e0961b5fee788aa3 (diff) | |
parent | 3c92506d86785967fd7e7933e04491b9276c2f00 (diff) | |
download | linux-f01603979a4afaad7504a728918b678d572cda9e.tar.gz linux-f01603979a4afaad7504a728918b678d572cda9e.tar.bz2 linux-f01603979a4afaad7504a728918b678d572cda9e.zip |
Merge tag 'gpio-updates-for-v6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio updates from Bartosz Golaszewski:
"We have a single new driver, support for a bunch of new models,
improvements in drivers and core gpiolib code as well device-tree
bindings changes.
Summary:
New driver:
- IMX System Controller Unit GPIOs
GPIO core:
- add fdinfo output for the GPIO character device file descriptors
(allows user-space to determine which processes own which GPIO
lines)
- improvements to OF GPIO code
- new quirk for Asus UM325UAZ in gpiolib-acpi
- new quirk for Freescale SPI in gpiolib-of
Driver improvements:
- add a new macro that reduces the amount of boilerplate code in ISA
drivers and use it in relevant drivers
- support two new models in gpio-pca953x
- support new model in gpio-f7188x
- convert more drivers to use immutable irq chips
- other minor tweaks
Device-tree bindings:
- add DT bindings for gpio-imx-scu
- convert Xilinx GPIO bindings to YAML
- reference the properties from the SPI peripheral device-tree
bindings instead of providing custom ones in the GPIO controller
document
- add parsing of GPIO hog nodes to the DT bindings for gpio-mpfs-gpio
- relax the node name requirements in gpio-stmpe
- add new models for gpio-rcar and gpio-pxa95xx
- add a new vendor prefix: Diodes (for Diodes, Inc.)
Misc:
- pulled in the immutable branch from the x86 platform drivers tree
including support for a new simatic board that depends on GPIO
changes"
* tag 'gpio-updates-for-v6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (36 commits)
gpio: tc3589x: Make irqchip immutable
gpiolib: cdev: add fdinfo output for line request file descriptors
gpio: twl4030: Reorder functions which allows to drop a forward declaraion
gpiolib: fix OOB access in quirk callbacks
gpiolib: of: factor out conversion from OF flags
gpiolib: rework quirk handling in of_find_gpio()
gpiolib: of: make Freescale SPI quirk similar to all others
gpiolib: of: do not ignore requested index when applying quirks
gpio: ws16c48: Ensure number of irq matches number of base
gpio: 104-idio-16: Ensure number of irq matches number of base
gpio: 104-idi-48: Ensure number of irq matches number of base
gpio: 104-dio-48e: Ensure number of irq matches number of base
counter: 104-quad-8: Ensure number of irq matches number of base
isa: Introduce the module_isa_driver_with_irq helper macro
gpio: pca953x: Add support for PCAL6534
gpio: pca953x: Swap if statements to save later complexity
gpio: pca953x: Fix pca953x_gpio_set_pull_up_down()
dt-bindings: gpio: pca95xx: add entry for pcal6534 and PI4IOE5V6534Q
dt-bindings: vendor-prefixes: add Diodes
gpio: mt7621: Switch to use platform_get_irq() function
...
Diffstat (limited to 'drivers/gpio/gpio-imx-scu.c')
-rw-r--r-- | drivers/gpio/gpio-imx-scu.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-imx-scu.c b/drivers/gpio/gpio-imx-scu.c new file mode 100644 index 000000000000..17be21b8f3b7 --- /dev/null +++ b/drivers/gpio/gpio-imx-scu.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2021~2022 NXP + * + * The driver exports a standard gpiochip interface + * to control the PIN resources on SCU domain. + */ + +#include <linux/module.h> +#include <linux/gpio/driver.h> +#include <linux/platform_device.h> +#include <linux/firmware/imx/svc/rm.h> +#include <dt-bindings/firmware/imx/rsrc.h> + +struct scu_gpio_priv { + struct gpio_chip chip; + struct mutex lock; + struct device *dev; + struct imx_sc_ipc *handle; +}; + +static unsigned int scu_rsrc_arr[] = { + IMX_SC_R_BOARD_R0, + IMX_SC_R_BOARD_R1, + IMX_SC_R_BOARD_R2, + IMX_SC_R_BOARD_R3, + IMX_SC_R_BOARD_R4, + IMX_SC_R_BOARD_R5, + IMX_SC_R_BOARD_R6, + IMX_SC_R_BOARD_R7, +}; + +static int imx_scu_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct scu_gpio_priv *priv = gpiochip_get_data(chip); + int level; + int err; + + if (offset >= chip->ngpio) + return -EINVAL; + + mutex_lock(&priv->lock); + + /* to read PIN state via scu api */ + err = imx_sc_misc_get_control(priv->handle, + scu_rsrc_arr[offset], 0, &level); + mutex_unlock(&priv->lock); + + if (err) { + dev_err(priv->dev, "SCU get failed: %d\n", err); + return err; + } + + return level; +} + +static void imx_scu_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) +{ + struct scu_gpio_priv *priv = gpiochip_get_data(chip); + int err; + + if (offset >= chip->ngpio) + return; + + mutex_lock(&priv->lock); + + /* to set PIN output level via scu api */ + err = imx_sc_misc_set_control(priv->handle, + scu_rsrc_arr[offset], 0, value); + mutex_unlock(&priv->lock); + + if (err) + dev_err(priv->dev, "SCU set (%d) failed: %d\n", + scu_rsrc_arr[offset], err); +} + +static int imx_scu_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + if (offset >= chip->ngpio) + return -EINVAL; + + return GPIO_LINE_DIRECTION_OUT; +} + +static int imx_scu_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct scu_gpio_priv *priv; + struct gpio_chip *gc; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + ret = imx_scu_get_handle(&priv->handle); + if (ret) + return ret; + + priv->dev = dev; + mutex_init(&priv->lock); + + gc = &priv->chip; + gc->base = -1; + gc->parent = dev; + gc->ngpio = sizeof(scu_rsrc_arr)/sizeof(unsigned int); + gc->label = dev_name(dev); + gc->get = imx_scu_gpio_get; + gc->set = imx_scu_gpio_set; + gc->get_direction = imx_scu_gpio_get_direction; + + platform_set_drvdata(pdev, priv); + + return devm_gpiochip_add_data(dev, gc, priv); +} + +static const struct of_device_id imx_scu_gpio_dt_ids[] = { + { .compatible = "fsl,imx8qxp-sc-gpio" }, + { /* sentinel */ } +}; + +static struct platform_driver imx_scu_gpio_driver = { + .driver = { + .name = "gpio-imx-scu", + .of_match_table = imx_scu_gpio_dt_ids, + }, + .probe = imx_scu_gpio_probe, +}; + +static int __init _imx_scu_gpio_init(void) +{ + return platform_driver_register(&imx_scu_gpio_driver); +} + +subsys_initcall_sync(_imx_scu_gpio_init); + +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>"); +MODULE_DESCRIPTION("NXP GPIO over IMX SCU API"); +MODULE_LICENSE("GPL"); |