summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-lpc32xx.c2
-rw-r--r--drivers/gpio/gpio-ml-ioh.c1
-rw-r--r--drivers/gpio/gpio-mpc8xxx.c30
-rw-r--r--drivers/gpio/gpio-pch.c1
-rw-r--r--drivers/gpio/gpio-samsung.c23
-rw-r--r--drivers/gpio/gpio-tegra.c59
6 files changed, 68 insertions, 48 deletions
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c
index 5b69480..ddfacc5 100644
--- a/drivers/gpio/gpio-lpc32xx.c
+++ b/drivers/gpio/gpio-lpc32xx.c
@@ -96,7 +96,7 @@ static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = {
};
static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = {
- "gpi000", "gpio01", "gpio02", "gpio03",
+ "gpio00", "gpio01", "gpio02", "gpio03",
"gpio04", "gpio05"
};
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c
index 03d6dd5..f0febe5 100644
--- a/drivers/gpio/gpio-ml-ioh.c
+++ b/drivers/gpio/gpio-ml-ioh.c
@@ -448,6 +448,7 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
chip->reg = chip->base;
chip->ch = i;
mutex_init(&chip->lock);
+ spin_lock_init(&chip->spinlock);
ioh_gpio_setup(chip, num_ports[i]);
ret = gpiochip_add(&chip->gpio);
if (ret) {
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 5cd04b6..e6568c1 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -37,7 +37,7 @@ struct mpc8xxx_gpio_chip {
* open drain mode safely
*/
u32 data;
- struct irq_host *irq;
+ struct irq_domain *irq;
void *of_dev_id_data;
};
@@ -281,7 +281,7 @@ static struct irq_chip mpc8xxx_irq_chip = {
.irq_set_type = mpc8xxx_irq_set_type,
};
-static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
+static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
@@ -296,24 +296,9 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq,
- unsigned int *out_flags)
-
-{
- /* interrupt sense values coming from the device tree equal either
- * EDGE_FALLING or EDGE_BOTH
- */
- *out_hwirq = intspec[0];
- *out_flags = intspec[1];
-
- return 0;
-}
-
-static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
+static struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
.map = mpc8xxx_gpio_irq_map,
- .xlate = mpc8xxx_gpio_irq_xlate,
+ .xlate = irq_domain_xlate_twocell,
};
static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
@@ -364,9 +349,8 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
if (hwirq == NO_IRQ)
goto skip_irq;
- mpc8xxx_gc->irq =
- irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
- &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
+ mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS,
+ &mpc8xxx_gpio_irq_ops, mpc8xxx_gc);
if (!mpc8xxx_gc->irq)
goto skip_irq;
@@ -374,8 +358,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
if (id)
mpc8xxx_gc->of_dev_id_data = id->data;
- mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
-
/* ack and mask all irqs */
out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
out_be32(mm_gc->regs + GPIO_IMR, 0);
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c
index 68fa55e..e8729cc 100644
--- a/drivers/gpio/gpio-pch.c
+++ b/drivers/gpio/gpio-pch.c
@@ -392,6 +392,7 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev,
chip->reg = chip->base;
pci_set_drvdata(pdev, chip);
mutex_init(&chip->lock);
+ spin_lock_init(&chip->spinlock);
pch_gpio_setup(chip);
ret = gpiochip_add(&chip->gpio);
if (ret) {
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
index a766177..0a79a11 100644
--- a/drivers/gpio/gpio-samsung.c
+++ b/drivers/gpio/gpio-samsung.c
@@ -2387,27 +2387,30 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
};
#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF)
-static int exynos4_gpio_xlate(struct gpio_chip *gc, struct device_node *np,
- const void *gpio_spec, u32 *flags)
+static int exynos4_gpio_xlate(struct gpio_chip *gc,
+ const struct of_phandle_args *gpiospec, u32 *flags)
{
- const __be32 *gpio = gpio_spec;
- const u32 n = be32_to_cpup(gpio);
- unsigned int pin = gc->base + be32_to_cpu(gpio[0]);
+ unsigned int pin;
if (WARN_ON(gc->of_gpio_n_cells < 4))
return -EINVAL;
- if (n > gc->ngpio)
+ if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
return -EINVAL;
- if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(be32_to_cpu(gpio[1]))))
+ if (gpiospec->args[0] > gc->ngpio)
+ return -EINVAL;
+
+ pin = gc->base + gpiospec->args[0];
+
+ if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
pr_warn("gpio_xlate: failed to set pin function\n");
- if (s3c_gpio_setpull(pin, be32_to_cpu(gpio[2])))
+ if (s3c_gpio_setpull(pin, gpiospec->args[2]))
pr_warn("gpio_xlate: failed to set pin pull up/down\n");
- if (s5p_gpio_set_drvstr(pin, be32_to_cpu(gpio[3])))
+ if (s5p_gpio_set_drvstr(pin, gpiospec->args[3]))
pr_warn("gpio_xlate: failed to set pin drive strength\n");
- return n;
+ return gpiospec->args[0];
}
static const struct of_device_id exynos4_gpio_dt_match[] __initdata = {
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index bdc2937..6f17671 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -25,6 +25,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/module.h>
+#include <linux/irqdomain.h>
#include <asm/mach/irq.h>
@@ -74,9 +75,10 @@ struct tegra_gpio_bank {
#endif
};
-
+static struct irq_domain *irq_domain;
static void __iomem *regs;
-static struct tegra_gpio_bank tegra_gpio_banks[7];
+static u32 tegra_gpio_bank_count;
+static struct tegra_gpio_bank *tegra_gpio_banks;
static inline void tegra_gpio_writel(u32 val, u32 reg)
{
@@ -139,7 +141,7 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
- return TEGRA_GPIO_TO_IRQ(offset);
+ return irq_find_mapping(irq_domain, offset);
}
static struct gpio_chip tegra_gpio_chip = {
@@ -155,28 +157,28 @@ static struct gpio_chip tegra_gpio_chip = {
static void tegra_gpio_irq_ack(struct irq_data *d)
{
- int gpio = d->irq - INT_GPIO_BASE;
+ int gpio = d->hwirq;
tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
}
static void tegra_gpio_irq_mask(struct irq_data *d)
{
- int gpio = d->irq - INT_GPIO_BASE;
+ int gpio = d->hwirq;
tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
}
static void tegra_gpio_irq_unmask(struct irq_data *d)
{
- int gpio = d->irq - INT_GPIO_BASE;
+ int gpio = d->hwirq;
tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
}
static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
- int gpio = d->irq - INT_GPIO_BASE;
+ int gpio = d->hwirq;
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
int port = GPIO_PORT(gpio);
int lvl_type;
@@ -273,7 +275,7 @@ void tegra_gpio_resume(void)
local_irq_save(flags);
- for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+ for (b = 0; b < tegra_gpio_bank_count; b++) {
struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -296,7 +298,7 @@ void tegra_gpio_suspend(void)
int p;
local_irq_save(flags);
- for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+ for (b = 0; b < tegra_gpio_bank_count; b++) {
struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -337,13 +339,44 @@ static struct lock_class_key gpio_lock_class;
static int __devinit tegra_gpio_probe(struct platform_device *pdev)
{
+ int irq_base;
struct resource *res;
struct tegra_gpio_bank *bank;
int gpio;
int i;
int j;
- for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+ for (;;) {
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count);
+ if (!res)
+ break;
+ tegra_gpio_bank_count++;
+ }
+ if (!tegra_gpio_bank_count) {
+ dev_err(&pdev->dev, "Missing IRQ resource\n");
+ return -ENODEV;
+ }
+
+ tegra_gpio_chip.ngpio = tegra_gpio_bank_count * 32;
+
+ tegra_gpio_banks = devm_kzalloc(&pdev->dev,
+ tegra_gpio_bank_count * sizeof(*tegra_gpio_banks),
+ GFP_KERNEL);
+ if (!tegra_gpio_banks) {
+ dev_err(&pdev->dev, "Couldn't allocate bank structure\n");
+ return -ENODEV;
+ }
+
+ irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0);
+ if (irq_base < 0) {
+ dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n");
+ return -ENODEV;
+ }
+ irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
+ tegra_gpio_chip.ngpio, irq_base, 0,
+ &irq_domain_simple_ops, NULL);
+
+ for (i = 0; i < tegra_gpio_bank_count; i++) {
res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
if (!res) {
dev_err(&pdev->dev, "Missing IRQ resource\n");
@@ -380,8 +413,8 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
gpiochip_add(&tegra_gpio_chip);
- for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) {
- int irq = TEGRA_GPIO_TO_IRQ(gpio);
+ for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) {
+ int irq = irq_find_mapping(irq_domain, gpio);
/* No validity check; all Tegra GPIOs are valid IRQs */
bank = &tegra_gpio_banks[GPIO_BANK(gpio)];
@@ -393,7 +426,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
set_irq_flags(irq, IRQF_VALID);
}
- for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+ for (i = 0; i < tegra_gpio_bank_count; i++) {
bank = &tegra_gpio_banks[i];
irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
OpenPOWER on IntegriCloud