summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpio-tegra.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 13:00:56 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 13:00:56 -0800
commitb0885d01f9ab1274109c02942c881d598f939623 (patch)
tree8c0e33fa141f2732a5c8e0e2db8b457d5cd865f9 /drivers/gpio/gpio-tegra.c
parentbad73c5aa069f1f14cc07ce7bbae8d463635560c (diff)
parentfc13d5a5b17c657b7682c145d367dcb859c507d9 (diff)
Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6
Pull GPIO updates from Grant Likely: "GPIO follow up patch and type change for v3.5 merge window Primarily device driver additions, features and bug fixes. Not much touching gpio common subsystem support. Should not be scary." * tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6: (34 commits) gpio: Provide the STMPE GPIO driver with its own IRQ Domain gpio: add TS-5500 DIO blocks support gpio: pcf857x: use client->irq for gpio_to_irq() gpio: stmpe: Add DT support for stmpe gpio gpio: pl061 depends on ARM gpio/pl061: remove old comment gpio: SPEAr: add spi chipselect control driver gpio: gpio-max710x: Support device tree probing gpio: twl4030: Use only TWL4030_MODULE_LED for LED configuration gpio: tegra: read output value when gpio is set in direction_out gpio: pca953x: Add compatible strings to gpio-pca953x driver gpio: pca953x: Register an IRQ domain gpio: mvebu: Set free callback for gpio_chip gpio: tegra: Drop exporting static functions gpio: tegra: Staticize non-exported symbols gpio: tegra: fix suspend/resume apis gpio-pch: Set parent dev for gpio chip gpio: em: Fix build errors GPIO: clps711x: use platform_device_unregister in gpio_clps711x_init() gpio/tc3589x: convert to use the simple irqdomain ...
Diffstat (limited to 'drivers/gpio/gpio-tegra.c')
-rw-r--r--drivers/gpio/gpio-tegra.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index d982593d7563..5389be8c2b51 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/irqdomain.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/pm.h>
#include <asm/mach/irq.h>
@@ -64,7 +65,7 @@ struct tegra_gpio_bank {
int bank;
int irq;
spinlock_t lvl_lock[4];
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
u32 cnf[4];
u32 out[4];
u32 oe[4];
@@ -109,20 +110,18 @@ static void tegra_gpio_enable(int gpio)
{
tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
}
-EXPORT_SYMBOL_GPL(tegra_gpio_enable);
static void tegra_gpio_disable(int gpio)
{
tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
}
-EXPORT_SYMBOL_GPL(tegra_gpio_disable);
-int tegra_gpio_request(struct gpio_chip *chip, unsigned offset)
+static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset)
{
return pinctrl_request_gpio(offset);
}
-void tegra_gpio_free(struct gpio_chip *chip, unsigned offset)
+static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset)
{
pinctrl_free_gpio(offset);
tegra_gpio_disable(offset);
@@ -135,6 +134,11 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
{
+ /* If gpio is in output mode then read from the out value */
+ if ((tegra_gpio_readl(GPIO_OE(offset)) >> GPIO_BIT(offset)) & 1)
+ return (tegra_gpio_readl(GPIO_OUT(offset)) >>
+ GPIO_BIT(offset)) & 0x1;
+
return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
}
@@ -285,8 +289,8 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
}
-#ifdef CONFIG_PM
-void tegra_gpio_resume(void)
+#ifdef CONFIG_PM_SLEEP
+static int tegra_gpio_resume(struct device *dev)
{
unsigned long flags;
int b;
@@ -308,9 +312,10 @@ void tegra_gpio_resume(void)
}
local_irq_restore(flags);
+ return 0;
}
-void tegra_gpio_suspend(void)
+static int tegra_gpio_suspend(struct device *dev)
{
unsigned long flags;
int b;
@@ -330,6 +335,7 @@ void tegra_gpio_suspend(void)
}
}
local_irq_restore(flags);
+ return 0;
}
static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable)
@@ -345,11 +351,15 @@ static struct irq_chip tegra_gpio_irq_chip = {
.irq_mask = tegra_gpio_irq_mask,
.irq_unmask = tegra_gpio_irq_unmask,
.irq_set_type = tegra_gpio_irq_set_type,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.irq_set_wake = tegra_gpio_wake_enable,
#endif
};
+static const struct dev_pm_ops tegra_gpio_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(tegra_gpio_suspend, tegra_gpio_resume)
+};
+
struct tegra_gpio_soc_config {
u32 bank_stride;
u32 upper_offset;
@@ -380,7 +390,6 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct tegra_gpio_soc_config *config;
- int irq_base;
struct resource *res;
struct tegra_gpio_bank *bank;
int gpio;
@@ -417,14 +426,11 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
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 = irq_domain_add_linear(pdev->dev.of_node,
+ tegra_gpio_chip.ngpio,
&irq_domain_simple_ops, NULL);
+ if (!irq_domain)
+ return -ENODEV;
for (i = 0; i < tegra_gpio_bank_count; i++) {
res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
@@ -464,7 +470,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
gpiochip_add(&tegra_gpio_chip);
for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) {
- int irq = irq_find_mapping(irq_domain, gpio);
+ int irq = irq_create_mapping(irq_domain, gpio);
/* No validity check; all Tegra GPIOs are valid IRQs */
bank = &tegra_gpio_banks[GPIO_BANK(gpio)];
@@ -493,6 +499,7 @@ static struct platform_driver tegra_gpio_driver = {
.driver = {
.name = "tegra-gpio",
.owner = THIS_MODULE,
+ .pm = &tegra_gpio_pm_ops,
.of_match_table = tegra_gpio_of_match,
},
.probe = tegra_gpio_probe,