GPIO fixes for the v3.10 series:
- 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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (GNU/Linux) iQIcBAABAgAGBQJRnofTAAoJEEEQszewGV1zcwEQAJcPAYa/+h4vYAYtQ95dK2Wo l155ifP7UmpHmEVkTiDsNG7ugGeoaPtfAh3y5ovSqSikr4NrtCVAZ+daivZnJzDu IzrutXAJiJn+5hE7k6loq979o1xbIJVQtPORJDb7KoeoS0tmPvBt2DDBvyFYZXR+ +hhsG1PNDq4cBXsxNPPAUbYSsXjUeuNib1kM/wdgBJ+h0p8BT24Wc7C61y/ndl+R fAXfZNpJnBTF451z683FwuTziC5P3S30nf3uU0n0n4qwn3/TzlNMgdp7SO2zbDqh bsp/mVQ0PCunOWylthRTf5mW0rRy4RfZZsEcSk2YV750nJ/MT1VTloCPppHPga2i R117Ype9cQyxtKpPRcNaaTJXZsCy7S0/dTMVAWXCIV2tjXASQ11a1HAKLTi3vzqL ygl/vsb2W1mLL50B+KDqFtSgVBR9i4eyTx4KRE6Sg96XxjUzhIqAKUUC0ZJHgO4F sJPqHxbWvlhge8p0Z+SEbWuznQrt8RZfQP8197B3/bvGQ6i2uPcBYQdyWxyD3bFR IvUuy0kN/GtlGHx4+REbLinLkX2ngXmSoZePxR+eDSccqy0XSe+dscdg1gGir2g4 6bG8zidXvCIkuaVlkPV1DJY5kzZrHnGGqgtNBrb7nRY7MA6jZ114sBIvR7dAkR7g xQyHh1q9vkRzttOInwB0 =dxQl -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
514e250f67
8 changed files with 64 additions and 21 deletions
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -496,8 +496,7 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
|
|||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 @@ static int omap_gpio_runtime_suspend(struct device *dev)
|
|||
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 = {
|
||||
|
|
|
@ -424,8 +424,7 @@ static int pch_gpio_probe(struct pci_dev *pdev,
|
|||
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:
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue