// SPDX-License-Identifier: GPL-2.0-only /* * Xilinx gpio driver for xps/axi_gpio IP. * * Copyright 2008 - 2013 Xilinx, Inc. */ #include <linux/bitmap.h> #include <linux/bitops.h> #include <linux/clk.h> #include <linux/errno.h> #include <linux/gpio/driver.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/irq.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/slab.h> /* Register Offset Definitions */ #define XGPIO_DATA_OFFSET … #define XGPIO_TRI_OFFSET … #define XGPIO_CHANNEL0_OFFSET … #define XGPIO_CHANNEL1_OFFSET … #define XGPIO_GIER_OFFSET … #define XGPIO_GIER_IE … #define XGPIO_IPISR_OFFSET … #define XGPIO_IPIER_OFFSET … /* Read/Write access to the GPIO registers */ #if defined(CONFIG_ARCH_ZYNQ) || defined(CONFIG_X86) #define xgpio_readreg(offset) … #define xgpio_writereg(offset, val) … #else #define xgpio_readreg … #define xgpio_writereg … #endif /** * struct xgpio_instance - Stores information about GPIO device * @gc: GPIO chip * @regs: register block * @hw_map: GPIO pin mapping on hardware side * @sw_map: GPIO pin mapping on software side * @state: GPIO write state shadow register * @last_irq_read: GPIO read state register from last interrupt * @dir: GPIO direction shadow register * @gpio_lock: Lock used for synchronization * @irq: IRQ used by GPIO device * @enable: GPIO IRQ enable/disable bitfield * @rising_edge: GPIO IRQ rising edge enable/disable bitfield * @falling_edge: GPIO IRQ falling edge enable/disable bitfield * @clk: clock resource for this driver */ struct xgpio_instance { … }; static inline int xgpio_from_bit(struct xgpio_instance *chip, int bit) { … } static inline int xgpio_to_bit(struct xgpio_instance *chip, int gpio) { … } static inline u32 xgpio_get_value32(const unsigned long *map, int bit) { … } static inline void xgpio_set_value32(unsigned long *map, int bit, u32 v) { … } static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch) { … } static void xgpio_read_ch(struct xgpio_instance *chip, int reg, int bit, unsigned long *a) { … } static void xgpio_write_ch(struct xgpio_instance *chip, int reg, int bit, unsigned long *a) { … } static void xgpio_read_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a) { … } static void xgpio_write_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a) { … } /** * xgpio_get - Read the specified signal of the GPIO device. * @gc: Pointer to gpio_chip device structure. * @gpio: GPIO signal number. * * This function reads the specified signal of the GPIO device. * * Return: * 0 if direction of GPIO signals is set as input otherwise it * returns negative error value. */ static int xgpio_get(struct gpio_chip *gc, unsigned int gpio) { … } /** * xgpio_set - Write the specified signal of the GPIO device. * @gc: Pointer to gpio_chip device structure. * @gpio: GPIO signal number. * @val: Value to be written to specified signal. * * This function writes the specified value in to the specified signal of the * GPIO device. */ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) { … } /** * xgpio_set_multiple - Write the specified signals of the GPIO device. * @gc: Pointer to gpio_chip device structure. * @mask: Mask of the GPIOS to modify. * @bits: Value to be wrote on each GPIO * * This function writes the specified values into the specified signals of the * GPIO devices. */ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { … } /** * xgpio_dir_in - Set the direction of the specified GPIO signal as input. * @gc: Pointer to gpio_chip device structure. * @gpio: GPIO signal number. * * Return: * 0 - if direction of GPIO signals is set as input * otherwise it returns negative error value. */ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) { … } /** * xgpio_dir_out - Set the direction of the specified GPIO signal as output. * @gc: Pointer to gpio_chip device structure. * @gpio: GPIO signal number. * @val: Value to be written to specified signal. * * This function sets the direction of specified GPIO signal as output. * * Return: * If all GPIO signals of GPIO chip is configured as input then it returns * error otherwise it returns 0. */ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { … } /** * xgpio_save_regs - Set initial values of GPIO pins * @chip: Pointer to GPIO instance */ static void xgpio_save_regs(struct xgpio_instance *chip) { … } static int xgpio_request(struct gpio_chip *chip, unsigned int offset) { … } static void xgpio_free(struct gpio_chip *chip, unsigned int offset) { … } static int __maybe_unused xgpio_suspend(struct device *dev) { … } /** * xgpio_remove - Remove method for the GPIO device. * @pdev: pointer to the platform device * * This function remove gpiochips and frees all the allocated resources. * * Return: 0 always */ static void xgpio_remove(struct platform_device *pdev) { … } /** * xgpio_irq_ack - Acknowledge a child GPIO interrupt. * @irq_data: per IRQ and chip data passed down to chip functions * This currently does nothing, but irq_ack is unconditionally called by * handle_edge_irq and therefore must be defined. */ static void xgpio_irq_ack(struct irq_data *irq_data) { … } static int __maybe_unused xgpio_resume(struct device *dev) { … } static int __maybe_unused xgpio_runtime_suspend(struct device *dev) { … } static int __maybe_unused xgpio_runtime_resume(struct device *dev) { … } static const struct dev_pm_ops xgpio_dev_pm_ops = …; /** * xgpio_irq_mask - Write the specified signal of the GPIO device. * @irq_data: per IRQ and chip data passed down to chip functions */ static void xgpio_irq_mask(struct irq_data *irq_data) { … } /** * xgpio_irq_unmask - Write the specified signal of the GPIO device. * @irq_data: per IRQ and chip data passed down to chip functions */ static void xgpio_irq_unmask(struct irq_data *irq_data) { … } /** * xgpio_set_irq_type - Write the specified signal of the GPIO device. * @irq_data: Per IRQ and chip data passed down to chip functions * @type: Interrupt type that is to be set for the gpio pin * * Return: * 0 if interrupt type is supported otherwise -EINVAL */ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type) { … } /** * xgpio_irqhandler - Gpio interrupt service routine * @desc: Pointer to interrupt description */ static void xgpio_irqhandler(struct irq_desc *desc) { … } static const struct irq_chip xgpio_irq_chip = …; /** * xgpio_probe - Probe method for the GPIO device. * @pdev: pointer to the platform device * * Return: * It returns 0, if the driver is bound to the GPIO device, or * a negative value if there is an error. */ static int xgpio_probe(struct platform_device *pdev) { … } static const struct of_device_id xgpio_of_match[] = …; MODULE_DEVICE_TABLE(of, xgpio_of_match); static struct platform_driver xgpio_plat_driver = …; static int __init xgpio_init(void) { … } subsys_initcall(xgpio_init); static void __exit xgpio_exit(void) { … } module_exit(xgpio_exit); MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;