提交 b239e445 编写于 作者: L Linus Walleij

Merge tag 'gpio-updates-for-v5.9-part1' of...

Merge tag 'gpio-updates-for-v5.9-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into devel

gpio updates for v5.9

- use kobj_to_dev() in sysfs interface
- kerneldoc and documentation fixes
- relax the interrupt flags in gpio-mpc8xxx
- support new model in gpio-pca953x
- remove a redundant check from gpio-max732x
- support a new platform in gpio-zynq (+ some minor fixes)
- don't depend on GPIOLIB when already inside the "if GPIOLIB" in Kconfig
- support PM ops for suspend in gpio-omap
- minor tweaks in gpiolib
...@@ -19,6 +19,7 @@ Required properties: ...@@ -19,6 +19,7 @@ Required properties:
nxp,pca9698 nxp,pca9698
nxp,pcal6416 nxp,pcal6416
nxp,pcal6524 nxp,pcal6524
nxp,pcal9535
nxp,pcal9555a nxp,pcal9555a
maxim,max7310 maxim,max7310
maxim,max7312 maxim,max7312
......
...@@ -6,7 +6,9 @@ Required properties: ...@@ -6,7 +6,9 @@ Required properties:
- First cell is the GPIO line number - First cell is the GPIO line number
- Second cell is used to specify optional - Second cell is used to specify optional
parameters (unused) parameters (unused)
- compatible : Should be "xlnx,zynq-gpio-1.0" or "xlnx,zynqmp-gpio-1.0" - compatible : Should be "xlnx,zynq-gpio-1.0" or
"xlnx,zynqmp-gpio-1.0" or "xlnx,versal-gpio-1.0
or "xlnx,pmc-gpio-1.0
- clocks : Clock specifier (see clock bindings for details) - clocks : Clock specifier (see clock bindings for details)
- gpio-controller : Marks the device node as a GPIO controller. - gpio-controller : Marks the device node as a GPIO controller.
- interrupts : Interrupt specifier (see interrupt bindings for - interrupts : Interrupt specifier (see interrupt bindings for
......
...@@ -410,7 +410,7 @@ config GPIO_MXS ...@@ -410,7 +410,7 @@ config GPIO_MXS
config GPIO_OCTEON config GPIO_OCTEON
tristate "Cavium OCTEON GPIO" tristate "Cavium OCTEON GPIO"
depends on GPIOLIB && CAVIUM_OCTEON_SOC depends on CAVIUM_OCTEON_SOC
default y default y
help help
Say yes here to support the on-chip GPIO lines on the OCTEON Say yes here to support the on-chip GPIO lines on the OCTEON
...@@ -1117,7 +1117,7 @@ config GPIO_DLN2 ...@@ -1117,7 +1117,7 @@ config GPIO_DLN2
config HTC_EGPIO config HTC_EGPIO
bool "HTC EGPIO support" bool "HTC EGPIO support"
depends on GPIOLIB && ARM depends on ARM
help help
This driver supports the CPLD egpio chip present on This driver supports the CPLD egpio chip present on
several HTC phones. It provides basic support for input several HTC phones. It provides basic support for input
......
...@@ -5,7 +5,7 @@ subsystem. ...@@ -5,7 +5,7 @@ subsystem.
GPIO descriptors GPIO descriptors
Starting with commit 79a9becda894 the GPIO subsystem embarked on a journey Starting with commit 79a9becda894 the GPIO subsystem embarked on a journey
to move away from the global GPIO numberspace and toward a decriptor-based to move away from the global GPIO numberspace and toward a descriptor-based
approach. This means that GPIO consumers, drivers and machine descriptions approach. This means that GPIO consumers, drivers and machine descriptions
ideally have no use or idea of the global GPIO numberspace that has/was ideally have no use or idea of the global GPIO numberspace that has/was
used in the inception of the GPIO subsystem. used in the inception of the GPIO subsystem.
......
...@@ -417,7 +417,7 @@ static int mpc8xxx_probe(struct platform_device *pdev) ...@@ -417,7 +417,7 @@ static int mpc8xxx_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, mpc8xxx_gc->irqn, ret = devm_request_irq(&pdev->dev, mpc8xxx_gc->irqn,
mpc8xxx_gpio_irq_cascade, mpc8xxx_gpio_irq_cascade,
IRQF_NO_THREAD | IRQF_SHARED, "gpio-cascade", IRQF_SHARED, "gpio-cascade",
mpc8xxx_gc); mpc8xxx_gc);
if (ret) { if (ret) {
dev_err(&pdev->dev, "%s: failed to devm_request_irq(%d), ret = %d\n", dev_err(&pdev->dev, "%s: failed to devm_request_irq(%d), ret = %d\n",
......
...@@ -60,6 +60,7 @@ struct gpio_bank { ...@@ -60,6 +60,7 @@ struct gpio_bank {
struct clk *dbck; struct clk *dbck;
struct notifier_block nb; struct notifier_block nb;
unsigned int is_suspended:1; unsigned int is_suspended:1;
unsigned int needs_resume:1;
u32 mod_usage; u32 mod_usage;
u32 irq_usage; u32 irq_usage;
u32 dbck_enable_mask; u32 dbck_enable_mask;
...@@ -1504,9 +1505,34 @@ static int __maybe_unused omap_gpio_runtime_resume(struct device *dev) ...@@ -1504,9 +1505,34 @@ static int __maybe_unused omap_gpio_runtime_resume(struct device *dev)
return 0; return 0;
} }
static int omap_gpio_suspend(struct device *dev)
{
struct gpio_bank *bank = dev_get_drvdata(dev);
if (bank->is_suspended)
return 0;
bank->needs_resume = 1;
return omap_gpio_runtime_suspend(dev);
}
static int omap_gpio_resume(struct device *dev)
{
struct gpio_bank *bank = dev_get_drvdata(dev);
if (!bank->needs_resume)
return 0;
bank->needs_resume = 0;
return omap_gpio_runtime_resume(dev);
}
static const struct dev_pm_ops gpio_pm_ops = { static const struct dev_pm_ops gpio_pm_ops = {
SET_RUNTIME_PM_OPS(omap_gpio_runtime_suspend, omap_gpio_runtime_resume, SET_RUNTIME_PM_OPS(omap_gpio_runtime_suspend, omap_gpio_runtime_resume,
NULL) NULL)
SET_LATE_SYSTEM_SLEEP_PM_OPS(omap_gpio_suspend, omap_gpio_resume)
}; };
static struct platform_driver omap_gpio_driver = { static struct platform_driver omap_gpio_driver = {
......
...@@ -89,6 +89,7 @@ static const struct i2c_device_id pca953x_id[] = { ...@@ -89,6 +89,7 @@ static const struct i2c_device_id pca953x_id[] = {
{ "pcal6416", 16 | PCA953X_TYPE | PCA_LATCH_INT, }, { "pcal6416", 16 | PCA953X_TYPE | PCA_LATCH_INT, },
{ "pcal6524", 24 | PCA953X_TYPE | PCA_LATCH_INT, }, { "pcal6524", 24 | PCA953X_TYPE | PCA_LATCH_INT, },
{ "pcal9535", 16 | PCA953X_TYPE | PCA_LATCH_INT, },
{ "pcal9555a", 16 | PCA953X_TYPE | PCA_LATCH_INT, }, { "pcal9555a", 16 | PCA953X_TYPE | PCA_LATCH_INT, },
{ "max7310", 8 | PCA953X_TYPE, }, { "max7310", 8 | PCA953X_TYPE, },
...@@ -1145,6 +1146,7 @@ static const struct of_device_id pca953x_dt_ids[] = { ...@@ -1145,6 +1146,7 @@ static const struct of_device_id pca953x_dt_ids[] = {
{ .compatible = "nxp,pcal6416", .data = OF_953X(16, PCA_LATCH_INT), }, { .compatible = "nxp,pcal6416", .data = OF_953X(16, PCA_LATCH_INT), },
{ .compatible = "nxp,pcal6524", .data = OF_953X(24, PCA_LATCH_INT), }, { .compatible = "nxp,pcal6524", .data = OF_953X(24, PCA_LATCH_INT), },
{ .compatible = "nxp,pcal9535", .data = OF_953X(16, PCA_LATCH_INT), },
{ .compatible = "nxp,pcal9555a", .data = OF_953X(16, PCA_LATCH_INT), }, { .compatible = "nxp,pcal9555a", .data = OF_953X(16, PCA_LATCH_INT), },
{ .compatible = "maxim,max7310", .data = OF_953X( 8, 0), }, { .compatible = "maxim,max7310", .data = OF_953X( 8, 0), },
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -21,6 +22,9 @@ ...@@ -21,6 +22,9 @@
/* Maximum banks */ /* Maximum banks */
#define ZYNQ_GPIO_MAX_BANK 4 #define ZYNQ_GPIO_MAX_BANK 4
#define ZYNQMP_GPIO_MAX_BANK 6 #define ZYNQMP_GPIO_MAX_BANK 6
#define VERSAL_GPIO_MAX_BANK 4
#define PMC_GPIO_MAX_BANK 5
#define VERSAL_UNUSED_BANKS 2
#define ZYNQ_GPIO_BANK0_NGPIO 32 #define ZYNQ_GPIO_BANK0_NGPIO 32
#define ZYNQ_GPIO_BANK1_NGPIO 22 #define ZYNQ_GPIO_BANK1_NGPIO 22
...@@ -95,6 +99,7 @@ ...@@ -95,6 +99,7 @@
/* set to differentiate zynq from zynqmp, 0=zynqmp, 1=zynq */ /* set to differentiate zynq from zynqmp, 0=zynqmp, 1=zynq */
#define ZYNQ_GPIO_QUIRK_IS_ZYNQ BIT(0) #define ZYNQ_GPIO_QUIRK_IS_ZYNQ BIT(0)
#define GPIO_QUIRK_DATA_RO_BUG BIT(1) #define GPIO_QUIRK_DATA_RO_BUG BIT(1)
#define GPIO_QUIRK_VERSAL BIT(2)
struct gpio_regs { struct gpio_regs {
u32 datamsw[ZYNQMP_GPIO_MAX_BANK]; u32 datamsw[ZYNQMP_GPIO_MAX_BANK];
...@@ -116,6 +121,7 @@ struct gpio_regs { ...@@ -116,6 +121,7 @@ struct gpio_regs {
* @irq: interrupt for the GPIO device * @irq: interrupt for the GPIO device
* @p_data: pointer to platform data * @p_data: pointer to platform data
* @context: context registers * @context: context registers
* @dirlock: lock used for direction in/out synchronization
*/ */
struct zynq_gpio { struct zynq_gpio {
struct gpio_chip chip; struct gpio_chip chip;
...@@ -124,6 +130,7 @@ struct zynq_gpio { ...@@ -124,6 +130,7 @@ struct zynq_gpio {
int irq; int irq;
const struct zynq_platform_data *p_data; const struct zynq_platform_data *p_data;
struct gpio_regs context; struct gpio_regs context;
spinlock_t dirlock; /* lock */
}; };
/** /**
...@@ -196,6 +203,8 @@ static inline void zynq_gpio_get_bank_pin(unsigned int pin_num, ...@@ -196,6 +203,8 @@ static inline void zynq_gpio_get_bank_pin(unsigned int pin_num,
gpio->p_data->bank_min[bank]; gpio->p_data->bank_min[bank];
return; return;
} }
if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL)
bank = bank + VERSAL_UNUSED_BANKS;
} }
/* default */ /* default */
...@@ -297,6 +306,7 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) ...@@ -297,6 +306,7 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
{ {
u32 reg; u32 reg;
unsigned int bank_num, bank_pin_num; unsigned int bank_num, bank_pin_num;
unsigned long flags;
struct zynq_gpio *gpio = gpiochip_get_data(chip); struct zynq_gpio *gpio = gpiochip_get_data(chip);
zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio);
...@@ -310,9 +320,11 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) ...@@ -310,9 +320,11 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
return -EINVAL; return -EINVAL;
/* clear the bit in direction mode reg to set the pin as input */ /* clear the bit in direction mode reg to set the pin as input */
spin_lock_irqsave(&gpio->dirlock, flags);
reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
reg &= ~BIT(bank_pin_num); reg &= ~BIT(bank_pin_num);
writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
spin_unlock_irqrestore(&gpio->dirlock, flags);
return 0; return 0;
} }
...@@ -334,11 +346,13 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, ...@@ -334,11 +346,13 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin,
{ {
u32 reg; u32 reg;
unsigned int bank_num, bank_pin_num; unsigned int bank_num, bank_pin_num;
unsigned long flags;
struct zynq_gpio *gpio = gpiochip_get_data(chip); struct zynq_gpio *gpio = gpiochip_get_data(chip);
zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio);
/* set the GPIO pin as output */ /* set the GPIO pin as output */
spin_lock_irqsave(&gpio->dirlock, flags);
reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
reg |= BIT(bank_pin_num); reg |= BIT(bank_pin_num);
writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
...@@ -347,6 +361,7 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, ...@@ -347,6 +361,7 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin,
reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
reg |= BIT(bank_pin_num); reg |= BIT(bank_pin_num);
writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
spin_unlock_irqrestore(&gpio->dirlock, flags);
/* set the state of the pin */ /* set the state of the pin */
zynq_gpio_set_value(chip, pin, state); zynq_gpio_set_value(chip, pin, state);
...@@ -647,6 +662,8 @@ static void zynq_gpio_irqhandler(struct irq_desc *desc) ...@@ -647,6 +662,8 @@ static void zynq_gpio_irqhandler(struct irq_desc *desc)
int_enb = readl_relaxed(gpio->base_addr + int_enb = readl_relaxed(gpio->base_addr +
ZYNQ_GPIO_INTMASK_OFFSET(bank_num)); ZYNQ_GPIO_INTMASK_OFFSET(bank_num));
zynq_gpio_handle_bank_irq(gpio, bank_num, int_sts & ~int_enb); zynq_gpio_handle_bank_irq(gpio, bank_num, int_sts & ~int_enb);
if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL)
bank_num = bank_num + VERSAL_UNUSED_BANKS;
} }
chained_irq_exit(irqchip, desc); chained_irq_exit(irqchip, desc);
...@@ -676,6 +693,8 @@ static void zynq_gpio_save_context(struct zynq_gpio *gpio) ...@@ -676,6 +693,8 @@ static void zynq_gpio_save_context(struct zynq_gpio *gpio)
gpio->context.int_any[bank_num] = gpio->context.int_any[bank_num] =
readl_relaxed(gpio->base_addr + readl_relaxed(gpio->base_addr +
ZYNQ_GPIO_INTANY_OFFSET(bank_num)); ZYNQ_GPIO_INTANY_OFFSET(bank_num));
if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL)
bank_num = bank_num + VERSAL_UNUSED_BANKS;
} }
} }
...@@ -707,6 +726,8 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio) ...@@ -707,6 +726,8 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio)
writel_relaxed(~(gpio->context.int_en[bank_num]), writel_relaxed(~(gpio->context.int_en[bank_num]),
gpio->base_addr + gpio->base_addr +
ZYNQ_GPIO_INTEN_OFFSET(bank_num)); ZYNQ_GPIO_INTEN_OFFSET(bank_num));
if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL)
bank_num = bank_num + VERSAL_UNUSED_BANKS;
} }
} }
...@@ -715,6 +736,9 @@ static int __maybe_unused zynq_gpio_suspend(struct device *dev) ...@@ -715,6 +736,9 @@ static int __maybe_unused zynq_gpio_suspend(struct device *dev)
struct zynq_gpio *gpio = dev_get_drvdata(dev); struct zynq_gpio *gpio = dev_get_drvdata(dev);
struct irq_data *data = irq_get_irq_data(gpio->irq); struct irq_data *data = irq_get_irq_data(gpio->irq);
if (!device_may_wakeup(dev))
disable_irq(gpio->irq);
if (!irqd_is_wakeup_set(data)) { if (!irqd_is_wakeup_set(data)) {
zynq_gpio_save_context(gpio); zynq_gpio_save_context(gpio);
return pm_runtime_force_suspend(dev); return pm_runtime_force_suspend(dev);
...@@ -729,6 +753,9 @@ static int __maybe_unused zynq_gpio_resume(struct device *dev) ...@@ -729,6 +753,9 @@ static int __maybe_unused zynq_gpio_resume(struct device *dev)
struct irq_data *data = irq_get_irq_data(gpio->irq); struct irq_data *data = irq_get_irq_data(gpio->irq);
int ret; int ret;
if (!device_may_wakeup(dev))
enable_irq(gpio->irq);
if (!irqd_is_wakeup_set(data)) { if (!irqd_is_wakeup_set(data)) {
ret = pm_runtime_force_resume(dev); ret = pm_runtime_force_resume(dev);
zynq_gpio_restore_context(gpio); zynq_gpio_restore_context(gpio);
...@@ -778,6 +805,31 @@ static const struct dev_pm_ops zynq_gpio_dev_pm_ops = { ...@@ -778,6 +805,31 @@ static const struct dev_pm_ops zynq_gpio_dev_pm_ops = {
zynq_gpio_runtime_resume, NULL) zynq_gpio_runtime_resume, NULL)
}; };
static const struct zynq_platform_data versal_gpio_def = {
.label = "versal_gpio",
.quirks = GPIO_QUIRK_VERSAL,
.ngpio = 58,
.max_bank = VERSAL_GPIO_MAX_BANK,
.bank_min[0] = 0,
.bank_max[0] = 25, /* 0 to 25 are connected to MIOs (26 pins) */
.bank_min[3] = 26,
.bank_max[3] = 57, /* Bank 3 is connected to FMIOs (32 pins) */
};
static const struct zynq_platform_data pmc_gpio_def = {
.label = "pmc_gpio",
.ngpio = 116,
.max_bank = PMC_GPIO_MAX_BANK,
.bank_min[0] = 0,
.bank_max[0] = 25, /* 0 to 25 are connected to MIOs (26 pins) */
.bank_min[1] = 26,
.bank_max[1] = 51, /* Bank 1 are connected to MIOs (26 pins) */
.bank_min[3] = 52,
.bank_max[3] = 83, /* Bank 3 is connected to EMIOs (32 pins) */
.bank_min[4] = 84,
.bank_max[4] = 115, /* Bank 4 is connected to EMIOs (32 pins) */
};
static const struct zynq_platform_data zynqmp_gpio_def = { static const struct zynq_platform_data zynqmp_gpio_def = {
.label = "zynqmp_gpio", .label = "zynqmp_gpio",
.quirks = GPIO_QUIRK_DATA_RO_BUG, .quirks = GPIO_QUIRK_DATA_RO_BUG,
...@@ -815,6 +867,8 @@ static const struct zynq_platform_data zynq_gpio_def = { ...@@ -815,6 +867,8 @@ static const struct zynq_platform_data zynq_gpio_def = {
static const struct of_device_id zynq_gpio_of_match[] = { static const struct of_device_id zynq_gpio_of_match[] = {
{ .compatible = "xlnx,zynq-gpio-1.0", .data = &zynq_gpio_def }, { .compatible = "xlnx,zynq-gpio-1.0", .data = &zynq_gpio_def },
{ .compatible = "xlnx,zynqmp-gpio-1.0", .data = &zynqmp_gpio_def }, { .compatible = "xlnx,zynqmp-gpio-1.0", .data = &zynqmp_gpio_def },
{ .compatible = "xlnx,versal-gpio-1.0", .data = &versal_gpio_def },
{ .compatible = "xlnx,pmc-gpio-1.0", .data = &pmc_gpio_def },
{ /* end of table */ } { /* end of table */ }
}; };
MODULE_DEVICE_TABLE(of, zynq_gpio_of_match); MODULE_DEVICE_TABLE(of, zynq_gpio_of_match);
...@@ -876,7 +930,8 @@ static int zynq_gpio_probe(struct platform_device *pdev) ...@@ -876,7 +930,8 @@ static int zynq_gpio_probe(struct platform_device *pdev)
/* Retrieve GPIO clock */ /* Retrieve GPIO clock */
gpio->clk = devm_clk_get(&pdev->dev, NULL); gpio->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(gpio->clk)) { if (IS_ERR(gpio->clk)) {
dev_err(&pdev->dev, "input clock not found.\n"); if (PTR_ERR(gpio->clk) != -EPROBE_DEFER)
dev_err(&pdev->dev, "input clock not found.\n");
return PTR_ERR(gpio->clk); return PTR_ERR(gpio->clk);
} }
ret = clk_prepare_enable(gpio->clk); ret = clk_prepare_enable(gpio->clk);
...@@ -885,6 +940,8 @@ static int zynq_gpio_probe(struct platform_device *pdev) ...@@ -885,6 +940,8 @@ static int zynq_gpio_probe(struct platform_device *pdev)
return ret; return ret;
} }
spin_lock_init(&gpio->dirlock);
pm_runtime_set_active(&pdev->dev); pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev);
...@@ -892,9 +949,12 @@ static int zynq_gpio_probe(struct platform_device *pdev) ...@@ -892,9 +949,12 @@ static int zynq_gpio_probe(struct platform_device *pdev)
goto err_pm_dis; goto err_pm_dis;
/* disable interrupts for all banks */ /* disable interrupts for all banks */
for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) {
writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr +
ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); ZYNQ_GPIO_INTDIS_OFFSET(bank_num));
if (gpio->p_data->quirks & GPIO_QUIRK_VERSAL)
bank_num = bank_num + VERSAL_UNUSED_BANKS;
}
/* Set up the GPIO irqchip */ /* Set up the GPIO irqchip */
girq = &chip->irq; girq = &chip->irq;
...@@ -919,6 +979,8 @@ static int zynq_gpio_probe(struct platform_device *pdev) ...@@ -919,6 +979,8 @@ static int zynq_gpio_probe(struct platform_device *pdev)
goto err_pm_put; goto err_pm_put;
} }
irq_set_status_flags(gpio->irq, IRQ_DISABLE_UNLAZY);
device_init_wakeup(&pdev->dev, 1);
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
return 0; return 0;
......
...@@ -365,7 +365,7 @@ static DEVICE_ATTR_RW(active_low); ...@@ -365,7 +365,7 @@ static DEVICE_ATTR_RW(active_low);
static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr, static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr,
int n) int n)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct gpiod_data *data = dev_get_drvdata(dev); struct gpiod_data *data = dev_get_drvdata(dev);
struct gpio_desc *desc = data->desc; struct gpio_desc *desc = data->desc;
umode_t mode = attr->mode; umode_t mode = attr->mode;
......
...@@ -2594,10 +2594,9 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep, ...@@ -2594,10 +2594,9 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
bitmap_xor(value_bitmap, value_bitmap, bitmap_xor(value_bitmap, value_bitmap,
array_info->invert_mask, array_size); array_info->invert_mask, array_size);
if (bitmap_full(array_info->get_mask, array_size))
return 0;
i = find_first_zero_bit(array_info->get_mask, array_size); i = find_first_zero_bit(array_info->get_mask, array_size);
if (i == array_size)
return 0;
} else { } else {
array_info = NULL; array_info = NULL;
} }
...@@ -2878,10 +2877,9 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, ...@@ -2878,10 +2877,9 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
gpio_chip_set_multiple(array_info->chip, array_info->set_mask, gpio_chip_set_multiple(array_info->chip, array_info->set_mask,
value_bitmap); value_bitmap);
if (bitmap_full(array_info->set_mask, array_size))
return 0;
i = find_first_zero_bit(array_info->set_mask, array_size); i = find_first_zero_bit(array_info->set_mask, array_size);
if (i == array_size)
return 0;
} else { } else {
array_info = NULL; array_info = NULL;
} }
......
...@@ -497,7 +497,7 @@ extern int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ...@@ -497,7 +497,7 @@ extern int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
/** /**
* gpiochip_add_data() - register a gpio_chip * gpiochip_add_data() - register a gpio_chip
* @chip: the chip to register, with chip->base initialized * @gc: the chip to register, with chip->base initialized
* @data: driver-private data associated with this chip * @data: driver-private data associated with this chip
* *
* Context: potentially before irqs will work * Context: potentially before irqs will work
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册