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
This commit is contained in:
@@ -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:
|
|||||||
- 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
|
|||||||
|
|
||||||
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
|
|||||||
|
|
||||||
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.
|
|||||||
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)
|
|||||||
|
|
||||||
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 {
|
|||||||
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)
|
|||||||
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[] = {
|
|||||||
|
|
||||||
{ "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[] = {
|
|||||||
|
|
||||||
{ .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 @@
|
|||||||
#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 @@
|
|||||||
/* 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 @@
|
|||||||
/* 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 {
|
|||||||
* @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 {
|
|||||||
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,
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 = {
|
|||||||
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 = {
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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);
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
|||||||
Reference in New Issue
Block a user