in gpio-omap.c [1371:1486]
static int omap_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
const struct omap_gpio_platform_data *pdata;
struct gpio_bank *bank;
struct irq_chip *irqc;
int ret;
pdata = device_get_match_data(dev);
pdata = pdata ?: dev_get_platdata(dev);
if (!pdata)
return -EINVAL;
bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL);
if (!bank)
return -ENOMEM;
irqc = devm_kzalloc(dev, sizeof(*irqc), GFP_KERNEL);
if (!irqc)
return -ENOMEM;
irqc->irq_startup = omap_gpio_irq_startup,
irqc->irq_shutdown = omap_gpio_irq_shutdown,
irqc->irq_ack = dummy_irq_chip.irq_ack,
irqc->irq_mask = omap_gpio_mask_irq,
irqc->irq_unmask = omap_gpio_unmask_irq,
irqc->irq_set_type = omap_gpio_irq_type,
irqc->irq_set_wake = omap_gpio_wake_enable,
irqc->irq_bus_lock = omap_gpio_irq_bus_lock,
irqc->irq_bus_sync_unlock = gpio_irq_bus_sync_unlock,
irqc->name = dev_name(&pdev->dev);
irqc->flags = IRQCHIP_MASK_ON_SUSPEND;
irqc->parent_device = dev;
bank->irq = platform_get_irq(pdev, 0);
if (bank->irq <= 0) {
if (!bank->irq)
bank->irq = -ENXIO;
return dev_err_probe(dev, bank->irq, "can't get irq resource\n");
}
bank->chip.parent = dev;
bank->chip.owner = THIS_MODULE;
bank->dbck_flag = pdata->dbck_flag;
bank->stride = pdata->bank_stride;
bank->width = pdata->bank_width;
bank->is_mpuio = pdata->is_mpuio;
bank->non_wakeup_gpios = pdata->non_wakeup_gpios;
bank->regs = pdata->regs;
if (node) {
if (!of_property_read_bool(node, "ti,gpio-always-on"))
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;
}
if (bank->regs->set_dataout && bank->regs->clr_dataout)
bank->set_dataout = omap_set_gpio_dataout_reg;
else
bank->set_dataout = omap_set_gpio_dataout_mask;
raw_spin_lock_init(&bank->lock);
raw_spin_lock_init(&bank->wa_lock);
/* Static mapping, never released */
bank->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(bank->base)) {
return PTR_ERR(bank->base);
}
if (bank->dbck_flag) {
bank->dbck = devm_clk_get(dev, "dbclk");
if (IS_ERR(bank->dbck)) {
dev_err(dev,
"Could not get gpio dbck. Disable debounce\n");
bank->dbck_flag = false;
} else {
clk_prepare(bank->dbck);
}
}
platform_set_drvdata(pdev, bank);
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
if (bank->is_mpuio)
omap_mpuio_init(bank);
omap_gpio_mod_init(bank);
ret = omap_gpio_chip_init(bank, irqc);
if (ret) {
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
if (bank->dbck_flag)
clk_unprepare(bank->dbck);
return ret;
}
omap_gpio_show_rev(bank);
bank->nb.notifier_call = gpio_omap_cpu_notifier;
cpu_pm_register_notifier(&bank->nb);
pm_runtime_put(dev);
return 0;
}