Commit a51aec41 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull pin control fixes from Linus Walleij:
 "Some late pin control fixes, the most generally annoying will probably
  be the AMD IRQ storm fix affecting the Microsoft surface.

  Summary:

   - Three fixes pertaining to Broadcom DT bindings. Some stuff didn't
     work out as inteded, we need to back out

   - A resume bug fix in the STM32 driver

   - Disable and mask the interrupts on probe in the AMD pinctrl driver,
     affecting Microsoft surface"

* tag 'pinctrl-v5.15-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: amd: disable and mask interrupts on probe
  pinctrl: stm32: use valid pin identifier in stm32_pinctrl_resume()
  Revert "pinctrl: bcm: ns: support updated DT binding as syscon subnode"
  dt-bindings: pinctrl: brcm,ns-pinmux: drop unneeded CRU from example
  Revert "dt-bindings: pinctrl: bcm4708-pinmux: rework binding to use syscon"
parents 87066fdd 4e5a04be
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -32,13 +32,13 @@ properties:
  "#size-cells":
    const: 1

  pinctrl:
    $ref: ../pinctrl/brcm,ns-pinmux.yaml

patternProperties:
  '^clock-controller@[a-f0-9]+$':
    $ref: ../clock/brcm,iproc-clocks.yaml

  '^pin-controller@[a-f0-9]+$':
    $ref: ../pinctrl/brcm,ns-pinmux.yaml

  '^thermal@[a-f0-9]+$':
    $ref: ../thermal/brcm,ns-thermal.yaml

@@ -73,9 +73,10 @@ examples:
                                 "iprocfast", "sata1", "sata2";
        };

        pinctrl {
        pin-controller@1c0 {
            compatible = "brcm,bcm4708-pinmux";
            offset = <0x1c0>;
            reg = <0x1c0 0x24>;
            reg-names = "cru_gpio_control";
        };

        thermal@2c0 {
+14 −19
Original line number Diff line number Diff line
@@ -17,9 +17,6 @@ description:

  A list of pins varies across chipsets so few bindings are available.

  Node of the pinmux must be nested in the CRU (Central Resource Unit) "syscon"
  node.

properties:
  compatible:
    enum:
@@ -27,10 +24,11 @@ properties:
      - brcm,bcm4709-pinmux
      - brcm,bcm53012-pinmux

  offset:
    description: offset of pin registers in the CRU block
  reg:
    maxItems: 1
    $ref: /schemas/types.yaml#/definitions/uint32-array

  reg-names:
    const: cru_gpio_control

patternProperties:
  '-pins$':
@@ -72,23 +70,20 @@ allOf:
                        uart1_grp ]

required:
  - offset
  - reg
  - reg-names

additionalProperties: false

examples:
  - |
    cru@1800c100 {
        compatible = "syscon", "simple-mfd";
        reg = <0x1800c100 0x1a4>;

        pinctrl {
    pin-controller@1800c1c0 {
        compatible = "brcm,bcm4708-pinmux";
            offset = <0xc0>;
        reg = <0x1800c1c0 0x24>;
        reg-names = "cru_gpio_control";

        spi-pins {
            function = "spi";
            groups = "spi_grp";
        };
    };
    };
+10 −19
Original line number Diff line number Diff line
@@ -5,7 +5,6 @@

#include <linux/err.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -13,7 +12,6 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#define FLAG_BCM4708		BIT(1)
@@ -24,8 +22,7 @@ struct ns_pinctrl {
	struct device *dev;
	unsigned int chipset_flag;
	struct pinctrl_dev *pctldev;
	struct regmap *regmap;
	u32 offset;
	void __iomem *base;

	struct pinctrl_desc pctldesc;
	struct ns_pinctrl_group *groups;
@@ -232,9 +229,9 @@ static int ns_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
		unset |= BIT(pin_number);
	}

	regmap_read(ns_pinctrl->regmap, ns_pinctrl->offset, &tmp);
	tmp = readl(ns_pinctrl->base);
	tmp &= ~unset;
	regmap_write(ns_pinctrl->regmap, ns_pinctrl->offset, tmp);
	writel(tmp, ns_pinctrl->base);

	return 0;
}
@@ -266,13 +263,13 @@ static const struct of_device_id ns_pinctrl_of_match_table[] = {
static int ns_pinctrl_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	const struct of_device_id *of_id;
	struct ns_pinctrl *ns_pinctrl;
	struct pinctrl_desc *pctldesc;
	struct pinctrl_pin_desc *pin;
	struct ns_pinctrl_group *group;
	struct ns_pinctrl_function *function;
	struct resource *res;
	int i;

	ns_pinctrl = devm_kzalloc(dev, sizeof(*ns_pinctrl), GFP_KERNEL);
@@ -290,18 +287,12 @@ static int ns_pinctrl_probe(struct platform_device *pdev)
		return -EINVAL;
	ns_pinctrl->chipset_flag = (uintptr_t)of_id->data;

	ns_pinctrl->regmap = syscon_node_to_regmap(of_get_parent(np));
	if (IS_ERR(ns_pinctrl->regmap)) {
		int err = PTR_ERR(ns_pinctrl->regmap);

		dev_err(dev, "Failed to map pinctrl regs: %d\n", err);

		return err;
	}

	if (of_property_read_u32(np, "offset", &ns_pinctrl->offset)) {
		dev_err(dev, "Failed to get register offset\n");
		return -ENOENT;
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
					   "cru_gpio_control");
	ns_pinctrl->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(ns_pinctrl->base)) {
		dev_err(dev, "Failed to map pinctrl regs\n");
		return PTR_ERR(ns_pinctrl->base);
	}

	memcpy(pctldesc, &ns_pinctrl_desc, sizeof(*pctldesc));
+31 −0
Original line number Diff line number Diff line
@@ -840,6 +840,34 @@ static const struct pinconf_ops amd_pinconf_ops = {
	.pin_config_group_set = amd_pinconf_group_set,
};

static void amd_gpio_irq_init(struct amd_gpio *gpio_dev)
{
	struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
	unsigned long flags;
	u32 pin_reg, mask;
	int i;

	mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3) |
		BIT(INTERRUPT_MASK_OFF) | BIT(INTERRUPT_ENABLE_OFF) |
		BIT(WAKE_CNTRL_OFF_S4);

	for (i = 0; i < desc->npins; i++) {
		int pin = desc->pins[i].number;
		const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);

		if (!pd)
			continue;

		raw_spin_lock_irqsave(&gpio_dev->lock, flags);

		pin_reg = readl(gpio_dev->base + i * 4);
		pin_reg &= ~mask;
		writel(pin_reg, gpio_dev->base + i * 4);

		raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
	}
}

#ifdef CONFIG_PM_SLEEP
static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
{
@@ -976,6 +1004,9 @@ static int amd_gpio_probe(struct platform_device *pdev)
		return PTR_ERR(gpio_dev->pctrl);
	}

	/* Disable and mask interrupts */
	amd_gpio_irq_init(gpio_dev);

	girq = &gpio_dev->gc.irq;
	girq->chip = &amd_gpio_irqchip;
	/* This will let us handle the parent IRQ in the driver */
+2 −2
Original line number Diff line number Diff line
@@ -1644,8 +1644,8 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
	struct stm32_pinctrl_group *g = pctl->groups;
	int i;

	for (i = g->pin; i < g->pin + pctl->ngroups; i++)
		stm32_pinctrl_restore_gpio_regs(pctl, i);
	for (i = 0; i < pctl->ngroups; i++, g++)
		stm32_pinctrl_restore_gpio_regs(pctl, g->pin);

	return 0;
}