in gpio-mpc8xxx.c [304:421]
static int mpc8xxx_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mpc8xxx_gpio_chip *mpc8xxx_gc;
struct gpio_chip *gc;
const struct mpc8xxx_gpio_devtype *devtype = NULL;
struct fwnode_handle *fwnode;
int ret;
mpc8xxx_gc = devm_kzalloc(&pdev->dev, sizeof(*mpc8xxx_gc), GFP_KERNEL);
if (!mpc8xxx_gc)
return -ENOMEM;
platform_set_drvdata(pdev, mpc8xxx_gc);
raw_spin_lock_init(&mpc8xxx_gc->lock);
mpc8xxx_gc->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mpc8xxx_gc->regs))
return PTR_ERR(mpc8xxx_gc->regs);
gc = &mpc8xxx_gc->gc;
gc->parent = &pdev->dev;
if (device_property_read_bool(&pdev->dev, "little-endian")) {
ret = bgpio_init(gc, &pdev->dev, 4,
mpc8xxx_gc->regs + GPIO_DAT,
NULL, NULL,
mpc8xxx_gc->regs + GPIO_DIR, NULL,
BGPIOF_BIG_ENDIAN);
if (ret)
return ret;
dev_dbg(&pdev->dev, "GPIO registers are LITTLE endian\n");
} else {
ret = bgpio_init(gc, &pdev->dev, 4,
mpc8xxx_gc->regs + GPIO_DAT,
NULL, NULL,
mpc8xxx_gc->regs + GPIO_DIR, NULL,
BGPIOF_BIG_ENDIAN
| BGPIOF_BIG_ENDIAN_BYTE_ORDER);
if (ret)
return ret;
dev_dbg(&pdev->dev, "GPIO registers are BIG endian\n");
}
mpc8xxx_gc->direction_output = gc->direction_output;
devtype = device_get_match_data(&pdev->dev);
if (!devtype)
devtype = &mpc8xxx_gpio_devtype_default;
/*
* It's assumed that only a single type of gpio controller is available
* on the current machine, so overwriting global data is fine.
*/
if (devtype->irq_set_type)
mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type;
if (devtype->gpio_dir_out)
gc->direction_output = devtype->gpio_dir_out;
if (devtype->gpio_get)
gc->get = devtype->gpio_get;
gc->to_irq = mpc8xxx_gpio_to_irq;
/*
* The GPIO Input Buffer Enable register(GPIO_IBE) is used to control
* the input enable of each individual GPIO port. When an individual
* GPIO port’s direction is set to input (GPIO_GPDIR[DRn=0]), the
* associated input enable must be set (GPIOxGPIE[IEn]=1) to propagate
* the port value to the GPIO Data Register.
*/
fwnode = dev_fwnode(&pdev->dev);
if (of_device_is_compatible(np, "fsl,qoriq-gpio") ||
of_device_is_compatible(np, "fsl,ls1028a-gpio") ||
of_device_is_compatible(np, "fsl,ls1088a-gpio") ||
is_acpi_node(fwnode))
gc->write_reg(mpc8xxx_gc->regs + GPIO_IBE, 0xffffffff);
ret = devm_gpiochip_add_data(&pdev->dev, gc, mpc8xxx_gc);
if (ret) {
dev_err(&pdev->dev,
"GPIO chip registration failed with status %d\n", ret);
return ret;
}
mpc8xxx_gc->irqn = platform_get_irq(pdev, 0);
if (!mpc8xxx_gc->irqn)
return 0;
mpc8xxx_gc->irq = irq_domain_create_linear(fwnode,
MPC8XXX_GPIO_PINS,
&mpc8xxx_gpio_irq_ops,
mpc8xxx_gc);
if (!mpc8xxx_gc->irq)
return 0;
/* ack and mask all irqs */
gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0xffffffff);
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0);
ret = devm_request_irq(&pdev->dev, mpc8xxx_gc->irqn,
mpc8xxx_gpio_irq_cascade,
IRQF_NO_THREAD | IRQF_SHARED, "gpio-cascade",
mpc8xxx_gc);
if (ret) {
dev_err(&pdev->dev,
"failed to devm_request_irq(%d), ret = %d\n",
mpc8xxx_gc->irqn, ret);
goto err;
}
return 0;
err:
irq_domain_remove(mpc8xxx_gc->irq);
return ret;
}