diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
| -rw-r--r-- | drivers/gpio/gpiolib.c | 72 | 
1 files changed, 33 insertions, 39 deletions
| diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 7ec0822c0505..1427c1be749b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -571,6 +571,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,  			       struct lock_class_key *lock_key,  			       struct lock_class_key *request_key)  { +	struct fwnode_handle *fwnode = gc->parent ? dev_fwnode(gc->parent) : NULL;  	unsigned long	flags;  	int		ret = 0;  	unsigned	i; @@ -585,14 +586,18 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,  	if (!gdev)  		return -ENOMEM;  	gdev->dev.bus = &gpio_bus_type; +	gdev->dev.parent = gc->parent;  	gdev->chip = gc;  	gc->gpiodev = gdev; -	if (gc->parent) { -		gdev->dev.parent = gc->parent; -		gdev->dev.of_node = gc->parent->of_node; -	}  	of_gpio_dev_init(gc, gdev); +	acpi_gpio_dev_init(gc, gdev); + +	/* +	 * Assign fwnode depending on the result of the previous calls, +	 * if none of them succeed, assign it to the parent's one. +	 */ +	gdev->dev.fwnode = dev_fwnode(&gdev->dev) ?: fwnode;  	gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);  	if (gdev->id < 0) { @@ -1458,9 +1463,8 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,  				struct lock_class_key *lock_key,  				struct lock_class_key *request_key)  { +	struct fwnode_handle *fwnode = dev_fwnode(&gc->gpiodev->dev);  	struct irq_chip *irqchip = gc->irq.chip; -	const struct irq_domain_ops *ops = NULL; -	struct device_node *np;  	unsigned int type;  	unsigned int i; @@ -1472,7 +1476,6 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,  		return -EINVAL;  	} -	np = gc->gpiodev->dev.of_node;  	type = gc->irq.default_type;  	/* @@ -1480,16 +1483,10 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,  	 * used to configure the interrupts, as you may end up with  	 * conflicting triggers. Tell the user, and reset to NONE.  	 */ -	if (WARN(np && type != IRQ_TYPE_NONE, -		 "%s: Ignoring %u default trigger\n", np->full_name, type)) +	if (WARN(fwnode && type != IRQ_TYPE_NONE, +		 "%pfw: Ignoring %u default trigger\n", fwnode, type))  		type = IRQ_TYPE_NONE; -	if (has_acpi_companion(gc->parent) && type != IRQ_TYPE_NONE) { -		acpi_handle_warn(ACPI_HANDLE(gc->parent), -				 "Ignoring %u default trigger\n", type); -		type = IRQ_TYPE_NONE; -	} -  	if (gc->to_irq)  		chip_warn(gc, "to_irq is redefined in %s and you shouldn't rely on it\n", __func__); @@ -1505,15 +1502,11 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,  			return ret;  	} else {  		/* Some drivers provide custom irqdomain ops */ -		if (gc->irq.domain_ops) -			ops = gc->irq.domain_ops; - -		if (!ops) -			ops = &gpiochip_domain_ops; -		gc->irq.domain = irq_domain_add_simple(np, +		gc->irq.domain = irq_domain_create_simple(fwnode,  			gc->ngpio,  			gc->irq.first, -			ops, gc); +			gc->irq.domain_ops ?: &gpiochip_domain_ops, +			gc);  		if (!gc->irq.domain)  			return -EINVAL;  	} @@ -3677,11 +3670,12 @@ EXPORT_SYMBOL_GPL(fwnode_gpiod_get_index);   */  int gpiod_count(struct device *dev, const char *con_id)  { +	const struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL;  	int count = -ENOENT; -	if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) +	if (is_of_node(fwnode))  		count = of_gpio_get_count(dev, con_id); -	else if (IS_ENABLED(CONFIG_ACPI) && dev && ACPI_HANDLE(dev)) +	else if (is_acpi_node(fwnode))  		count = acpi_gpio_count(dev, con_id);  	if (count < 0) @@ -3819,18 +3813,17 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,  	int ret;  	/* Maybe we have a device name, maybe not */  	const char *devname = dev ? dev_name(dev) : "?"; +	const struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL;  	dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id); -	if (dev) { -		/* Using device tree? */ -		if (IS_ENABLED(CONFIG_OF) && dev->of_node) { -			dev_dbg(dev, "using device tree for GPIO lookup\n"); -			desc = of_find_gpio(dev, con_id, idx, &lookupflags); -		} else if (ACPI_COMPANION(dev)) { -			dev_dbg(dev, "using ACPI for GPIO lookup\n"); -			desc = acpi_find_gpio(dev, con_id, idx, &flags, &lookupflags); -		} +	/* Using device tree? */ +	if (is_of_node(fwnode)) { +		dev_dbg(dev, "using device tree for GPIO lookup\n"); +		desc = of_find_gpio(dev, con_id, idx, &lookupflags); +	} else if (is_acpi_node(fwnode)) { +		dev_dbg(dev, "using ACPI for GPIO lookup\n"); +		desc = acpi_find_gpio(dev, con_id, idx, &flags, &lookupflags);  	}  	/* @@ -3914,9 +3907,6 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,  	struct gpio_desc *desc = ERR_PTR(-ENODEV);  	int ret; -	if (!fwnode) -		return ERR_PTR(-EINVAL); -  	if (is_of_node(fwnode)) {  		desc = gpiod_get_from_of_node(to_of_node(fwnode),  					      propname, index, @@ -3932,7 +3922,8 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,  		acpi_gpio_update_gpiod_flags(&dflags, &info);  		acpi_gpio_update_gpiod_lookup_flags(&lflags, &info); -	} +	} else +		return ERR_PTR(-EINVAL);  	/* Currently only ACPI takes this path */  	ret = gpiod_request(desc, label); @@ -4213,11 +4204,13 @@ EXPORT_SYMBOL_GPL(gpiod_put_array);  static int gpio_bus_match(struct device *dev, struct device_driver *drv)  { +	struct fwnode_handle *fwnode = dev_fwnode(dev); +  	/*  	 * Only match if the fwnode doesn't already have a proper struct device  	 * created for it.  	 */ -	if (dev->fwnode && dev->fwnode->dev != dev) +	if (fwnode && fwnode->dev != dev)  		return 0;  	return 1;  } @@ -4256,7 +4249,8 @@ static int __init gpiolib_dev_init(void)  		return ret;  	} -	if (driver_register(&gpio_stub_drv) < 0) { +	ret = driver_register(&gpio_stub_drv); +	if (ret < 0) {  		pr_err("gpiolib: could not register GPIO stub driver\n");  		bus_unregister(&gpio_bus_type);  		return ret; | 
