#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
-#include <linux/of_gpio.h>
#include <linux/io.h>
#include <linux/gpio/driver.h>
#include <linux/slab.h>
/**
* struct xgpio_instance - Stores information about GPIO device
- * @mmchip: OF GPIO chip for memory mapped banks
+ * @gc: GPIO chip
+ * @regs: register block
* @gpio_width: GPIO width for every channel
* @gpio_state: GPIO state shadow register
* @gpio_dir: GPIO direction shadow register
* @gpio_lock: Lock used for synchronization
*/
struct xgpio_instance {
- struct of_mm_gpio_chip mmchip;
+ struct gpio_chip gc;
+ void __iomem *regs;
unsigned int gpio_width[2];
u32 gpio_state[2];
u32 gpio_dir[2];
*/
static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
struct xgpio_instance *chip = gpiochip_get_data(gc);
u32 val;
- val = xgpio_readreg(mm_gc->regs + XGPIO_DATA_OFFSET +
+ val = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
xgpio_regoffset(chip, gpio));
return !!(val & BIT(xgpio_offset(chip, gpio)));
static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
{
unsigned long flags;
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
struct xgpio_instance *chip = gpiochip_get_data(gc);
int index = xgpio_index(chip, gpio);
int offset = xgpio_offset(chip, gpio);
else
chip->gpio_state[index] &= ~BIT(offset);
- xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
+ xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
unsigned long *bits)
{
unsigned long flags;
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
struct xgpio_instance *chip = gpiochip_get_data(gc);
int index = xgpio_index(chip, 0);
int offset, i;
if (*mask == 0)
break;
if (index != xgpio_index(chip, i)) {
- xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
+ xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
xgpio_regoffset(chip, i),
chip->gpio_state[index]);
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
}
}
- xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
+ xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
xgpio_regoffset(chip, i), chip->gpio_state[index]);
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
{
unsigned long flags;
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
struct xgpio_instance *chip = gpiochip_get_data(gc);
int index = xgpio_index(chip, gpio);
int offset = xgpio_offset(chip, gpio);
/* Set the GPIO bit in shadow register and set direction as input */
chip->gpio_dir[index] |= BIT(offset);
- xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET +
+ xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
{
unsigned long flags;
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
struct xgpio_instance *chip = gpiochip_get_data(gc);
int index = xgpio_index(chip, gpio);
int offset = xgpio_offset(chip, gpio);
chip->gpio_state[index] |= BIT(offset);
else
chip->gpio_state[index] &= ~BIT(offset);
- xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
+ xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
/* Clear the GPIO bit in shadow register and set direction as output */
chip->gpio_dir[index] &= ~BIT(offset);
- xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET +
+ xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
/**
* xgpio_save_regs - Set initial values of GPIO pins
- * @mm_gc: Pointer to memory mapped GPIO chip structure
+ * @chip: Pointer to GPIO instance
*/
-static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
+static void xgpio_save_regs(struct xgpio_instance *chip)
{
- struct xgpio_instance *chip =
- container_of(mm_gc, struct xgpio_instance, mmchip);
-
- xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
- xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
+ xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
+ xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
if (!chip->gpio_width[1])
return;
- xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
+ xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
chip->gpio_state[1]);
- xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
+ xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
chip->gpio_dir[1]);
}
/**
- * 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 int xgpio_remove(struct platform_device *pdev)
-{
- struct xgpio_instance *chip = platform_get_drvdata(pdev);
-
- of_mm_gpiochip_remove(&chip->mmchip);
-
- return 0;
-}
-
-/**
* xgpio_of_probe - Probe method for the GPIO device.
* @pdev: pointer to the platform device
*
spin_lock_init(&chip->gpio_lock[1]);
}
- chip->mmchip.gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
- chip->mmchip.gc.parent = &pdev->dev;
- chip->mmchip.gc.direction_input = xgpio_dir_in;
- chip->mmchip.gc.direction_output = xgpio_dir_out;
- chip->mmchip.gc.get = xgpio_get;
- chip->mmchip.gc.set = xgpio_set;
- chip->mmchip.gc.set_multiple = xgpio_set_multiple;
+ chip->gc.base = -1;
+ chip->gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
+ chip->gc.parent = &pdev->dev;
+ chip->gc.direction_input = xgpio_dir_in;
+ chip->gc.direction_output = xgpio_dir_out;
+ chip->gc.get = xgpio_get;
+ chip->gc.set = xgpio_set;
+ chip->gc.set_multiple = xgpio_set_multiple;
+
+ chip->gc.label = dev_name(&pdev->dev);
+
+ chip->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(chip->regs)) {
+ dev_err(&pdev->dev, "failed to ioremap memory resource\n");
+ return PTR_ERR(chip->regs);
+ }
- chip->mmchip.save_regs = xgpio_save_regs;
+ xgpio_save_regs(chip);
- /* Call the OF gpio helper to setup and register the GPIO device */
- status = of_mm_gpiochip_add_data(np, &chip->mmchip, chip);
+ status = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip);
if (status) {
- pr_err("%pOF: error in probe function with status %d\n",
- np, status);
+ dev_err(&pdev->dev, "failed to add GPIO chip\n");
return status;
}
static struct platform_driver xgpio_plat_driver = {
.probe = xgpio_probe,
- .remove = xgpio_remove,
.driver = {
.name = "gpio-xilinx",
.of_match_table = xgpio_of_match,