static int mpc8xxx_probe()

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