aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-23 21:24:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-23 21:24:10 -0400
commit514e250f67d2b2a8ab08dc9c3650af19a411c926 (patch)
tree5cb431c3a7c4792358ee82798281976db0412786 /drivers/gpio
parentb91fd4d5aad0c1124654341814067ca3f59490fc (diff)
parentcfb10898efe1bc1f3eb8d8f37f164d9e2ac8b43a (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/Kconfig2
-rw-r--r--drivers/gpio/gpio-langwell.c17
-rw-r--r--drivers/gpio/gpio-ml-ioh.c3
-rw-r--r--drivers/gpio/gpio-mxs.c3
-rw-r--r--drivers/gpio/gpio-omap.c48
-rw-r--r--drivers/gpio/gpio-pch.c3
-rw-r--r--drivers/gpio/gpio-sch.c6
-rw-r--r--drivers/gpio/gpio-viperboard.c3
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
637config GPIO_MCP23S08 637config 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:
496err_gpiochip_add: 496err_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
1264static void omap_gpio_init_context(struct gpio_bank *p);
1265
1262static int omap_gpio_runtime_resume(struct device *dev) 1266static 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)
1405static 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
1387static void omap_gpio_restore_context(struct gpio_bank *bank) 1428static 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
1465static void omap_gpio_init_context(struct gpio_bank *p) {}
1424#endif 1466#endif
1425 1467
1426static const struct dev_pm_ops gpio_pm_ops = { 1468static 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:
424err_request_irq: 424err_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
431err_gpiochip_add: 430err_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
274err_sch_gpio_resume: 274err_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
280err_sch_gpio_core: 278err_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
448err_gpiob: 448err_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
451err_gpioa: 452err_gpioa:
452 return ret; 453 return ret;