diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-23 18:24:10 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-23 18:24:10 -0700 |
commit | 514e250f67d2b2a8ab08dc9c3650af19a411c926 (patch) | |
tree | 5cb431c3a7c4792358ee82798281976db0412786 /drivers | |
parent | b91fd4d5aad0c1124654341814067ca3f59490fc (diff) | |
parent | cfb10898efe1bc1f3eb8d8f37f164d9e2ac8b43a (diff) | |
download | linux-514e250f67d2b2a8ab08dc9c3650af19a411c926.tar.bz2 |
Merge tag 'gpio-fixes-v3.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO fixes from Linus Walleij:
- An OMAP fix that makes ethernet work again.
- Fix for build problem when building the MCP23S08 driver as module.
- IRQ conflicts in the Langwell driver.
- Fix IRQ coherency issues in the MXS driver.
- Return correct errorcode on errorpath when removing GPIO chips.
* tag 'gpio-fixes-v3.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
gpio: Don't override the error code in probe error handling
gpio: mxs: Use set and clear capabilities of the gpio controller
gpio-langwell: fix irq conflicts when DT is not used
gpio: mcp23s08: Fix build error when CONFIG_SPI_MASTER=y && CONFIG_I2C=m
gpio/omap: ensure gpio context is initialised
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpio/Kconfig | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-langwell.c | 17 | ||||
-rw-r--r-- | drivers/gpio/gpio-ml-ioh.c | 3 | ||||
-rw-r--r-- | drivers/gpio/gpio-mxs.c | 3 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 48 | ||||
-rw-r--r-- | drivers/gpio/gpio-pch.c | 3 | ||||
-rw-r--r-- | drivers/gpio/gpio-sch.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpio-viperboard.c | 3 |
8 files changed, 64 insertions, 21 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 87d567089f13..573c449c49b9 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -636,7 +636,7 @@ config GPIO_MAX7301 config GPIO_MCP23S08 tristate "Microchip MCP23xxx I/O expander" - depends on SPI_MASTER || I2C + depends on (SPI_MASTER && !I2C) || I2C help SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 I/O expanders. diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index 634c3d37f7b5..62ef10a641c4 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c @@ -324,6 +324,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev, resource_size_t start, len; struct lnw_gpio *lnw; u32 gpio_base; + u32 irq_base; int retval; int ngpio = id->driver_data; @@ -345,6 +346,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev, retval = -EFAULT; goto err_ioremap; } + irq_base = *(u32 *)base; gpio_base = *((u32 *)base + 1); /* release the IO mapping, since we already get the info from bar1 */ iounmap(base); @@ -365,13 +367,6 @@ static int lnw_gpio_probe(struct pci_dev *pdev, goto err_ioremap; } - lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, - &lnw_gpio_irq_ops, lnw); - if (!lnw->domain) { - retval = -ENOMEM; - goto err_ioremap; - } - lnw->reg_base = base; lnw->chip.label = dev_name(&pdev->dev); lnw->chip.request = lnw_gpio_request; @@ -384,6 +379,14 @@ static int lnw_gpio_probe(struct pci_dev *pdev, lnw->chip.ngpio = ngpio; lnw->chip.can_sleep = 0; lnw->pdev = pdev; + + lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ngpio, irq_base, + &lnw_gpio_irq_ops, lnw); + if (!lnw->domain) { + retval = -ENOMEM; + goto err_ioremap; + } + pci_set_drvdata(pdev, lnw); retval = gpiochip_add(&lnw->chip); if (retval) { diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index b73366523fae..0966f2637ad2 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -496,8 +496,7 @@ err_irq_alloc_descs: err_gpiochip_add: while (--i >= 0) { chip--; - ret = gpiochip_remove(&chip->gpio); - if (ret) + if (gpiochip_remove(&chip->gpio)) dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i); } kfree(chip_save); diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index 25000b0f8453..f8e6af20dfbf 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c @@ -326,7 +326,8 @@ static int mxs_gpio_probe(struct platform_device *pdev) err = bgpio_init(&port->bgc, &pdev->dev, 4, port->base + PINCTRL_DIN(port), - port->base + PINCTRL_DOUT(port), NULL, + port->base + PINCTRL_DOUT(port) + MXS_SET, + port->base + PINCTRL_DOUT(port) + MXS_CLR, port->base + PINCTRL_DOE(port), NULL, 0); if (err) goto out_irqdesc_free; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 2050891d9c65..d3f7d2db870f 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -69,6 +69,7 @@ struct gpio_bank { bool is_mpuio; bool dbck_flag; bool loses_context; + bool context_valid; int stride; u32 width; int context_loss_count; @@ -1128,6 +1129,10 @@ static int omap_gpio_probe(struct platform_device *pdev) bank->loses_context = true; } else { bank->loses_context = pdata->loses_context; + + if (bank->loses_context) + bank->get_context_loss_count = + pdata->get_context_loss_count; } @@ -1178,9 +1183,6 @@ static int omap_gpio_probe(struct platform_device *pdev) omap_gpio_chip_init(bank); omap_gpio_show_rev(bank); - if (bank->loses_context) - bank->get_context_loss_count = pdata->get_context_loss_count; - pm_runtime_put(bank->dev); list_add_tail(&bank->node, &omap_gpio_list); @@ -1259,6 +1261,8 @@ update_gpio_context_count: return 0; } +static void omap_gpio_init_context(struct gpio_bank *p); + static int omap_gpio_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -1268,6 +1272,20 @@ static int omap_gpio_runtime_resume(struct device *dev) int c; spin_lock_irqsave(&bank->lock, flags); + + /* + * On the first resume during the probe, the context has not + * been initialised and so initialise it now. Also initialise + * the context loss count. + */ + if (bank->loses_context && !bank->context_valid) { + omap_gpio_init_context(bank); + + if (bank->get_context_loss_count) + bank->context_loss_count = + bank->get_context_loss_count(bank->dev); + } + _gpio_dbck_enable(bank); /* @@ -1384,6 +1402,29 @@ void omap2_gpio_resume_after_idle(void) } #if defined(CONFIG_PM_RUNTIME) +static void omap_gpio_init_context(struct gpio_bank *p) +{ + struct omap_gpio_reg_offs *regs = p->regs; + void __iomem *base = p->base; + + p->context.ctrl = __raw_readl(base + regs->ctrl); + p->context.oe = __raw_readl(base + regs->direction); + p->context.wake_en = __raw_readl(base + regs->wkup_en); + p->context.leveldetect0 = __raw_readl(base + regs->leveldetect0); + p->context.leveldetect1 = __raw_readl(base + regs->leveldetect1); + p->context.risingdetect = __raw_readl(base + regs->risingdetect); + p->context.fallingdetect = __raw_readl(base + regs->fallingdetect); + p->context.irqenable1 = __raw_readl(base + regs->irqenable); + p->context.irqenable2 = __raw_readl(base + regs->irqenable2); + + if (regs->set_dataout && p->regs->clr_dataout) + p->context.dataout = __raw_readl(base + regs->set_dataout); + else + p->context.dataout = __raw_readl(base + regs->dataout); + + p->context_valid = true; +} + static void omap_gpio_restore_context(struct gpio_bank *bank) { __raw_writel(bank->context.wake_en, @@ -1421,6 +1462,7 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) #else #define omap_gpio_runtime_suspend NULL #define omap_gpio_runtime_resume NULL +static void omap_gpio_init_context(struct gpio_bank *p) {} #endif static const struct dev_pm_ops gpio_pm_ops = { diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index cdf599687cf7..0fec097e838d 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -424,8 +424,7 @@ end: err_request_irq: irq_free_descs(irq_base, gpio_pins[chip->ioh]); - ret = gpiochip_remove(&chip->gpio); - if (ret) + if (gpiochip_remove(&chip->gpio)) dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); err_gpiochip_add: diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 1e4de16ceb41..5af65719b95d 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -272,10 +272,8 @@ static int sch_gpio_probe(struct platform_device *pdev) return 0; err_sch_gpio_resume: - err = gpiochip_remove(&sch_gpio_core); - if (err) - dev_err(&pdev->dev, "%s failed, %d\n", - "gpiochip_remove()", err); + if (gpiochip_remove(&sch_gpio_core)) + dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); err_sch_gpio_core: release_region(res->start, resource_size(res)); diff --git a/drivers/gpio/gpio-viperboard.c b/drivers/gpio/gpio-viperboard.c index 095ab14cea4d..5ac2919197fe 100644 --- a/drivers/gpio/gpio-viperboard.c +++ b/drivers/gpio/gpio-viperboard.c @@ -446,7 +446,8 @@ static int vprbrd_gpio_probe(struct platform_device *pdev) return ret; err_gpiob: - ret = gpiochip_remove(&vb_gpio->gpioa); + if (gpiochip_remove(&vb_gpio->gpioa)) + dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); err_gpioa: return ret; |