Commit 116a3308 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'gpio-fixes-for-v7.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:

 - fix kerneldocs for gpio-timberdale and gpio-nomadik

 - clear the "requested" flag in error path in gpiod_request_commit()

 - call of_xlate() if provided when setting up shared GPIOs

 - handle pins shared by child firmware nodes of consumer devices

 - fix return value check in gpio-qixis-fpga

 - fix suspend on gpio-mxc

 - fix gpio-microchip DT bindings

* tag 'gpio-fixes-for-v7.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  dt-bindings: gpio: fix microchip #interrupt-cells
  gpio: shared: shorten the critical section in gpiochip_setup_shared()
  gpio: mxc: map Both Edge pad wakeup to Rising Edge
  gpio: qixis-fpga: Fix error handling for devm_regmap_init_mmio()
  gpio: shared: handle pins shared by child nodes of devices
  gpio: shared: call gpio_chip::of_xlate() if set
  gpiolib: clear requested flag if line is invalid
  gpio: nomadik: repair some kernel-doc comments
  gpio: timberdale: repair kernel-doc comments
  gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()
parents 441c63ff 6b5ef8c8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ properties:
    const: 2

  "#interrupt-cells":
    const: 1
    const: 2

  ngpios:
    description:
@@ -86,7 +86,7 @@ examples:
        gpio-controller;
        #gpio-cells = <2>;
        interrupt-controller;
        #interrupt-cells = <1>;
        #interrupt-cells = <2>;
        interrupts = <53>, <53>, <53>, <53>,
                     <53>, <53>, <53>, <53>,
                     <53>, <53>, <53>, <53>,
+9 −1
Original line number Diff line number Diff line
@@ -584,12 +584,13 @@ static bool mxc_gpio_set_pad_wakeup(struct mxc_gpio_port *port, bool enable)
	unsigned long config;
	bool ret = false;
	int i, type;
	bool is_imx8qm = of_device_is_compatible(port->dev->of_node, "fsl,imx8qm-gpio");

	static const u32 pad_type_map[] = {
		IMX_SCU_WAKEUP_OFF,		/* 0 */
		IMX_SCU_WAKEUP_RISE_EDGE,	/* IRQ_TYPE_EDGE_RISING */
		IMX_SCU_WAKEUP_FALL_EDGE,	/* IRQ_TYPE_EDGE_FALLING */
		IMX_SCU_WAKEUP_FALL_EDGE,	/* IRQ_TYPE_EDGE_BOTH */
		IMX_SCU_WAKEUP_RISE_EDGE,	/* IRQ_TYPE_EDGE_BOTH */
		IMX_SCU_WAKEUP_HIGH_LVL,	/* IRQ_TYPE_LEVEL_HIGH */
		IMX_SCU_WAKEUP_OFF,		/* 5 */
		IMX_SCU_WAKEUP_OFF,		/* 6 */
@@ -604,6 +605,13 @@ static bool mxc_gpio_set_pad_wakeup(struct mxc_gpio_port *port, bool enable)
				config = pad_type_map[type];
			else
				config = IMX_SCU_WAKEUP_OFF;

			if (is_imx8qm && config == IMX_SCU_WAKEUP_FALL_EDGE) {
				dev_warn_once(port->dev,
					      "No falling-edge support for wakeup on i.MX8QM\n");
				config = IMX_SCU_WAKEUP_OFF;
			}

			ret |= mxc_gpio_generic_config(port, i, config);
		}
	}
+2 −2
Original line number Diff line number Diff line
@@ -60,8 +60,8 @@ static int qixis_cpld_gpio_probe(struct platform_device *pdev)
			return PTR_ERR(reg);

		regmap = devm_regmap_init_mmio(&pdev->dev, reg, &regmap_config_8r_8v);
		if (!regmap)
			return -ENODEV;
		if (IS_ERR(regmap))
			return PTR_ERR(regmap);

		/* In this case, the offset of our register is 0 inside the
		 * regmap area that we just created.
+41 −16
Original line number Diff line number Diff line
@@ -443,8 +443,8 @@ static bool gpio_shared_dev_is_reset_gpio(struct device *consumer,
}
#endif /* CONFIG_RESET_GPIO */

int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id,
				 unsigned long lflags)
int gpio_shared_add_proxy_lookup(struct device *consumer, struct fwnode_handle *fwnode,
				 const char *con_id, unsigned long lflags)
{
	const char *dev_id = dev_name(consumer);
	struct gpiod_lookup_table *lookup;
@@ -458,7 +458,7 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id,
			if (!ref->fwnode && device_is_compatible(consumer, "reset-gpio")) {
				if (!gpio_shared_dev_is_reset_gpio(consumer, entry, ref))
					continue;
			} else if (!device_match_fwnode(consumer, ref->fwnode)) {
			} else if (fwnode != ref->fwnode) {
				continue;
			}

@@ -506,8 +506,9 @@ static void gpio_shared_remove_adev(struct auxiliary_device *adev)
	auxiliary_device_uninit(adev);
}

int gpio_device_setup_shared(struct gpio_device *gdev)
int gpiochip_setup_shared(struct gpio_chip *gc)
{
	struct gpio_device *gdev = gc->gpiodev;
	struct gpio_shared_entry *entry;
	struct gpio_shared_ref *ref;
	struct gpio_desc *desc;
@@ -538,6 +539,27 @@ int gpio_device_setup_shared(struct gpio_device *gdev)
		if (list_count_nodes(&entry->refs) <= 1)
			continue;

		scoped_guard(mutex, &entry->lock) {
#if IS_ENABLED(CONFIG_OF)
			if (is_of_node(entry->fwnode) && gc->of_xlate) {
				/*
				 * This is the earliest that we can tranlate the
				 * devicetree offset to the chip offset.
				 */
				struct of_phandle_args gpiospec = { };

				gpiospec.np = to_of_node(entry->fwnode);
				gpiospec.args_count = 2;
				gpiospec.args[0] = entry->offset;

				ret = gc->of_xlate(gc, &gpiospec, NULL);
				if (ret < 0)
					return ret;

				entry->offset = ret;
			}
#endif /* CONFIG_OF */

			desc = &gdev->descs[entry->offset];

			__set_bit(GPIOD_FLAG_SHARED, &desc->flags);
@@ -552,6 +574,7 @@ int gpio_device_setup_shared(struct gpio_device *gdev)

			pr_debug("GPIO %u owned by %s is shared by multiple consumers\n",
				 entry->offset, gpio_device_get_label(gdev));
		}

		list_for_each_entry(ref, &entry->refs, list) {
			pr_debug("Setting up a shared GPIO entry for %s (con_id: '%s')\n",
@@ -575,6 +598,8 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)
	struct gpio_shared_ref *ref;

	list_for_each_entry(entry, &gpio_shared_list, list) {
		guard(mutex)(&entry->lock);

		if (!device_match_fwnode(&gdev->dev, entry->fwnode))
			continue;

+7 −4
Original line number Diff line number Diff line
@@ -11,17 +11,19 @@
struct gpio_device;
struct gpio_desc;
struct device;
struct fwnode_handle;

#if IS_ENABLED(CONFIG_GPIO_SHARED)

int gpio_device_setup_shared(struct gpio_device *gdev);
int gpiochip_setup_shared(struct gpio_chip *gc);
void gpio_device_teardown_shared(struct gpio_device *gdev);
int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id,
				 unsigned long lflags);
int gpio_shared_add_proxy_lookup(struct device *consumer,
				 struct fwnode_handle *fwnode,
				 const char *con_id, unsigned long lflags);

#else

static inline int gpio_device_setup_shared(struct gpio_device *gdev)
static inline int gpiochip_setup_shared(struct gpio_chip *gc)
{
	return 0;
}
@@ -29,6 +31,7 @@ static inline int gpio_device_setup_shared(struct gpio_device *gdev)
static inline void gpio_device_teardown_shared(struct gpio_device *gdev) { }

static inline int gpio_shared_add_proxy_lookup(struct device *consumer,
					       struct fwnode_handle *fwnode,
					       const char *con_id,
					       unsigned long lflags)
{
Loading