Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 514e250f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents b91fd4d5 cfb10898
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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.
+10 −7
Original line number Diff line number Diff line
@@ -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) {
+1 −2
Original line number Diff line number Diff line
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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;
+45 −3
Original line number Diff line number Diff line
@@ -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 = {
Loading