diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-23 21:24:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-23 21:24:10 -0400 |
commit | 514e250f67d2b2a8ab08dc9c3650af19a411c926 (patch) | |
tree | 5cb431c3a7c4792358ee82798281976db0412786 /drivers/gpio | |
parent | b91fd4d5aad0c1124654341814067ca3f59490fc (diff) | |
parent | cfb10898efe1bc1f3eb8d8f37f164d9e2ac8b43a (diff) |
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/gpio')
-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 | |||
636 | 636 | ||
637 | config GPIO_MCP23S08 | 637 | config GPIO_MCP23S08 |
638 | tristate "Microchip MCP23xxx I/O expander" | 638 | tristate "Microchip MCP23xxx I/O expander" |
639 | depends on SPI_MASTER || I2C | 639 | depends on (SPI_MASTER && !I2C) || I2C |
640 | help | 640 | help |
641 | SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 | 641 | SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 |
642 | I/O expanders. | 642 | 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, | |||
324 | resource_size_t start, len; | 324 | resource_size_t start, len; |
325 | struct lnw_gpio *lnw; | 325 | struct lnw_gpio *lnw; |
326 | u32 gpio_base; | 326 | u32 gpio_base; |
327 | u32 irq_base; | ||
327 | int retval; | 328 | int retval; |
328 | int ngpio = id->driver_data; | 329 | int ngpio = id->driver_data; |
329 | 330 | ||
@@ -345,6 +346,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev, | |||
345 | retval = -EFAULT; | 346 | retval = -EFAULT; |
346 | goto err_ioremap; | 347 | goto err_ioremap; |
347 | } | 348 | } |
349 | irq_base = *(u32 *)base; | ||
348 | gpio_base = *((u32 *)base + 1); | 350 | gpio_base = *((u32 *)base + 1); |
349 | /* release the IO mapping, since we already get the info from bar1 */ | 351 | /* release the IO mapping, since we already get the info from bar1 */ |
350 | iounmap(base); | 352 | iounmap(base); |
@@ -365,13 +367,6 @@ static int lnw_gpio_probe(struct pci_dev *pdev, | |||
365 | goto err_ioremap; | 367 | goto err_ioremap; |
366 | } | 368 | } |
367 | 369 | ||
368 | lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, | ||
369 | &lnw_gpio_irq_ops, lnw); | ||
370 | if (!lnw->domain) { | ||
371 | retval = -ENOMEM; | ||
372 | goto err_ioremap; | ||
373 | } | ||
374 | |||
375 | lnw->reg_base = base; | 370 | lnw->reg_base = base; |
376 | lnw->chip.label = dev_name(&pdev->dev); | 371 | lnw->chip.label = dev_name(&pdev->dev); |
377 | lnw->chip.request = lnw_gpio_request; | 372 | lnw->chip.request = lnw_gpio_request; |
@@ -384,6 +379,14 @@ static int lnw_gpio_probe(struct pci_dev *pdev, | |||
384 | lnw->chip.ngpio = ngpio; | 379 | lnw->chip.ngpio = ngpio; |
385 | lnw->chip.can_sleep = 0; | 380 | lnw->chip.can_sleep = 0; |
386 | lnw->pdev = pdev; | 381 | lnw->pdev = pdev; |
382 | |||
383 | lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ngpio, irq_base, | ||
384 | &lnw_gpio_irq_ops, lnw); | ||
385 | if (!lnw->domain) { | ||
386 | retval = -ENOMEM; | ||
387 | goto err_ioremap; | ||
388 | } | ||
389 | |||
387 | pci_set_drvdata(pdev, lnw); | 390 | pci_set_drvdata(pdev, lnw); |
388 | retval = gpiochip_add(&lnw->chip); | 391 | retval = gpiochip_add(&lnw->chip); |
389 | if (retval) { | 392 | 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: | |||
496 | err_gpiochip_add: | 496 | err_gpiochip_add: |
497 | while (--i >= 0) { | 497 | while (--i >= 0) { |
498 | chip--; | 498 | chip--; |
499 | ret = gpiochip_remove(&chip->gpio); | 499 | if (gpiochip_remove(&chip->gpio)) |
500 | if (ret) | ||
501 | dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i); | 500 | dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i); |
502 | } | 501 | } |
503 | kfree(chip_save); | 502 | 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) | |||
326 | 326 | ||
327 | err = bgpio_init(&port->bgc, &pdev->dev, 4, | 327 | err = bgpio_init(&port->bgc, &pdev->dev, 4, |
328 | port->base + PINCTRL_DIN(port), | 328 | port->base + PINCTRL_DIN(port), |
329 | port->base + PINCTRL_DOUT(port), NULL, | 329 | port->base + PINCTRL_DOUT(port) + MXS_SET, |
330 | port->base + PINCTRL_DOUT(port) + MXS_CLR, | ||
330 | port->base + PINCTRL_DOE(port), NULL, 0); | 331 | port->base + PINCTRL_DOE(port), NULL, 0); |
331 | if (err) | 332 | if (err) |
332 | goto out_irqdesc_free; | 333 | 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 { | |||
69 | bool is_mpuio; | 69 | bool is_mpuio; |
70 | bool dbck_flag; | 70 | bool dbck_flag; |
71 | bool loses_context; | 71 | bool loses_context; |
72 | bool context_valid; | ||
72 | int stride; | 73 | int stride; |
73 | u32 width; | 74 | u32 width; |
74 | int context_loss_count; | 75 | int context_loss_count; |
@@ -1128,6 +1129,10 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
1128 | bank->loses_context = true; | 1129 | bank->loses_context = true; |
1129 | } else { | 1130 | } else { |
1130 | bank->loses_context = pdata->loses_context; | 1131 | bank->loses_context = pdata->loses_context; |
1132 | |||
1133 | if (bank->loses_context) | ||
1134 | bank->get_context_loss_count = | ||
1135 | pdata->get_context_loss_count; | ||
1131 | } | 1136 | } |
1132 | 1137 | ||
1133 | 1138 | ||
@@ -1178,9 +1183,6 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
1178 | omap_gpio_chip_init(bank); | 1183 | omap_gpio_chip_init(bank); |
1179 | omap_gpio_show_rev(bank); | 1184 | omap_gpio_show_rev(bank); |
1180 | 1185 | ||
1181 | if (bank->loses_context) | ||
1182 | bank->get_context_loss_count = pdata->get_context_loss_count; | ||
1183 | |||
1184 | pm_runtime_put(bank->dev); | 1186 | pm_runtime_put(bank->dev); |
1185 | 1187 | ||
1186 | list_add_tail(&bank->node, &omap_gpio_list); | 1188 | list_add_tail(&bank->node, &omap_gpio_list); |
@@ -1259,6 +1261,8 @@ update_gpio_context_count: | |||
1259 | return 0; | 1261 | return 0; |
1260 | } | 1262 | } |
1261 | 1263 | ||
1264 | static void omap_gpio_init_context(struct gpio_bank *p); | ||
1265 | |||
1262 | static int omap_gpio_runtime_resume(struct device *dev) | 1266 | static int omap_gpio_runtime_resume(struct device *dev) |
1263 | { | 1267 | { |
1264 | struct platform_device *pdev = to_platform_device(dev); | 1268 | struct platform_device *pdev = to_platform_device(dev); |
@@ -1268,6 +1272,20 @@ static int omap_gpio_runtime_resume(struct device *dev) | |||
1268 | int c; | 1272 | int c; |
1269 | 1273 | ||
1270 | spin_lock_irqsave(&bank->lock, flags); | 1274 | spin_lock_irqsave(&bank->lock, flags); |
1275 | |||
1276 | /* | ||
1277 | * On the first resume during the probe, the context has not | ||
1278 | * been initialised and so initialise it now. Also initialise | ||
1279 | * the context loss count. | ||
1280 | */ | ||
1281 | if (bank->loses_context && !bank->context_valid) { | ||
1282 | omap_gpio_init_context(bank); | ||
1283 | |||
1284 | if (bank->get_context_loss_count) | ||
1285 | bank->context_loss_count = | ||
1286 | bank->get_context_loss_count(bank->dev); | ||
1287 | } | ||
1288 | |||
1271 | _gpio_dbck_enable(bank); | 1289 | _gpio_dbck_enable(bank); |
1272 | 1290 | ||
1273 | /* | 1291 | /* |
@@ -1384,6 +1402,29 @@ void omap2_gpio_resume_after_idle(void) | |||
1384 | } | 1402 | } |
1385 | 1403 | ||
1386 | #if defined(CONFIG_PM_RUNTIME) | 1404 | #if defined(CONFIG_PM_RUNTIME) |
1405 | static void omap_gpio_init_context(struct gpio_bank *p) | ||
1406 | { | ||
1407 | struct omap_gpio_reg_offs *regs = p->regs; | ||
1408 | void __iomem *base = p->base; | ||
1409 | |||
1410 | p->context.ctrl = __raw_readl(base + regs->ctrl); | ||
1411 | p->context.oe = __raw_readl(base + regs->direction); | ||
1412 | p->context.wake_en = __raw_readl(base + regs->wkup_en); | ||
1413 | p->context.leveldetect0 = __raw_readl(base + regs->leveldetect0); | ||
1414 | p->context.leveldetect1 = __raw_readl(base + regs->leveldetect1); | ||
1415 | p->context.risingdetect = __raw_readl(base + regs->risingdetect); | ||
1416 | p->context.fallingdetect = __raw_readl(base + regs->fallingdetect); | ||
1417 | p->context.irqenable1 = __raw_readl(base + regs->irqenable); | ||
1418 | p->context.irqenable2 = __raw_readl(base + regs->irqenable2); | ||
1419 | |||
1420 | if (regs->set_dataout && p->regs->clr_dataout) | ||
1421 | p->context.dataout = __raw_readl(base + regs->set_dataout); | ||
1422 | else | ||
1423 | p->context.dataout = __raw_readl(base + regs->dataout); | ||
1424 | |||
1425 | p->context_valid = true; | ||
1426 | } | ||
1427 | |||
1387 | static void omap_gpio_restore_context(struct gpio_bank *bank) | 1428 | static void omap_gpio_restore_context(struct gpio_bank *bank) |
1388 | { | 1429 | { |
1389 | __raw_writel(bank->context.wake_en, | 1430 | __raw_writel(bank->context.wake_en, |
@@ -1421,6 +1462,7 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) | |||
1421 | #else | 1462 | #else |
1422 | #define omap_gpio_runtime_suspend NULL | 1463 | #define omap_gpio_runtime_suspend NULL |
1423 | #define omap_gpio_runtime_resume NULL | 1464 | #define omap_gpio_runtime_resume NULL |
1465 | static void omap_gpio_init_context(struct gpio_bank *p) {} | ||
1424 | #endif | 1466 | #endif |
1425 | 1467 | ||
1426 | static const struct dev_pm_ops gpio_pm_ops = { | 1468 | 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: | |||
424 | err_request_irq: | 424 | err_request_irq: |
425 | irq_free_descs(irq_base, gpio_pins[chip->ioh]); | 425 | irq_free_descs(irq_base, gpio_pins[chip->ioh]); |
426 | 426 | ||
427 | ret = gpiochip_remove(&chip->gpio); | 427 | if (gpiochip_remove(&chip->gpio)) |
428 | if (ret) | ||
429 | dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); | 428 | dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); |
430 | 429 | ||
431 | err_gpiochip_add: | 430 | 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) | |||
272 | return 0; | 272 | return 0; |
273 | 273 | ||
274 | err_sch_gpio_resume: | 274 | err_sch_gpio_resume: |
275 | err = gpiochip_remove(&sch_gpio_core); | 275 | if (gpiochip_remove(&sch_gpio_core)) |
276 | if (err) | 276 | dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); |
277 | dev_err(&pdev->dev, "%s failed, %d\n", | ||
278 | "gpiochip_remove()", err); | ||
279 | 277 | ||
280 | err_sch_gpio_core: | 278 | err_sch_gpio_core: |
281 | release_region(res->start, resource_size(res)); | 279 | 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) | |||
446 | return ret; | 446 | return ret; |
447 | 447 | ||
448 | err_gpiob: | 448 | err_gpiob: |
449 | ret = gpiochip_remove(&vb_gpio->gpioa); | 449 | if (gpiochip_remove(&vb_gpio->gpioa)) |
450 | dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); | ||
450 | 451 | ||
451 | err_gpioa: | 452 | err_gpioa: |
452 | return ret; | 453 | return ret; |