static int pxa_gpio_probe()

in gpio-pxa.c [613:719]


static int pxa_gpio_probe(struct platform_device *pdev)
{
	struct pxa_gpio_chip *pchip;
	struct pxa_gpio_bank *c;
	struct clk *clk;
	struct pxa_gpio_platform_data *info;
	void __iomem *gpio_reg_base;
	int gpio, ret;
	int irq0 = 0, irq1 = 0, irq_mux;

	pchip = devm_kzalloc(&pdev->dev, sizeof(*pchip), GFP_KERNEL);
	if (!pchip)
		return -ENOMEM;
	pchip->dev = &pdev->dev;

	info = dev_get_platdata(&pdev->dev);
	if (info) {
		irq_base = info->irq_base;
		if (irq_base <= 0)
			return -EINVAL;
		pxa_last_gpio = pxa_gpio_nums(pdev);
		pchip->set_wake = info->gpio_set_wake;
	} else {
		irq_base = pxa_gpio_probe_dt(pdev, pchip);
		if (irq_base < 0)
			return -EINVAL;
	}

	if (!pxa_last_gpio)
		return -EINVAL;

	pchip->irqdomain = irq_domain_add_legacy(pdev->dev.of_node,
						 pxa_last_gpio + 1, irq_base,
						 0, &pxa_irq_domain_ops, pchip);
	if (!pchip->irqdomain)
		return -ENOMEM;

	irq0 = platform_get_irq_byname_optional(pdev, "gpio0");
	irq1 = platform_get_irq_byname_optional(pdev, "gpio1");
	irq_mux = platform_get_irq_byname(pdev, "gpio_mux");
	if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0)
		|| (irq_mux <= 0))
		return -EINVAL;

	pchip->irq0 = irq0;
	pchip->irq1 = irq1;

	gpio_reg_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(gpio_reg_base))
		return PTR_ERR(gpio_reg_base);

	clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(clk)) {
		dev_err(&pdev->dev, "Error %ld to get gpio clock\n",
			PTR_ERR(clk));
		return PTR_ERR(clk);
	}
	ret = clk_prepare_enable(clk);
	if (ret) {
		clk_put(clk);
		return ret;
	}

	/* Initialize GPIO chips */
	ret = pxa_init_gpio_chip(pchip, pxa_last_gpio + 1, gpio_reg_base);
	if (ret) {
		clk_put(clk);
		return ret;
	}

	/* clear all GPIO edge detects */
	for_each_gpio_bank(gpio, c, pchip) {
		writel_relaxed(0, c->regbase + GFER_OFFSET);
		writel_relaxed(0, c->regbase + GRER_OFFSET);
		writel_relaxed(~0, c->regbase + GEDR_OFFSET);
		/* unmask GPIO edge detect for AP side */
		if (gpio_is_mmp_type(gpio_type))
			writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
	}

	if (irq0 > 0) {
		ret = devm_request_irq(&pdev->dev,
				       irq0, pxa_gpio_direct_handler, 0,
				       "gpio-0", pchip);
		if (ret)
			dev_err(&pdev->dev, "request of gpio0 irq failed: %d\n",
				ret);
	}
	if (irq1 > 0) {
		ret = devm_request_irq(&pdev->dev,
				       irq1, pxa_gpio_direct_handler, 0,
				       "gpio-1", pchip);
		if (ret)
			dev_err(&pdev->dev, "request of gpio1 irq failed: %d\n",
				ret);
	}
	ret = devm_request_irq(&pdev->dev,
			       irq_mux, pxa_gpio_demux_handler, 0,
				       "gpio-mux", pchip);
	if (ret)
		dev_err(&pdev->dev, "request of gpio-mux irq failed: %d\n",
				ret);

	pxa_gpio_chip = pchip;

	return 0;
}