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;
}