Skip to content

Commit

Permalink
Merge tag 'pinctrl-v5.15-3' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/linusw/linux-pinctrl

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"
  • Loading branch information
torvalds committed Oct 25, 2021
2 parents 87066fd + 4e5a04b commit a51aec4
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 45 deletions.
11 changes: 6 additions & 5 deletions Documentation/devicetree/bindings/mfd/brcm,cru.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 {
Expand Down
33 changes: 14 additions & 19 deletions Documentation/devicetree/bindings/pinctrl/brcm,ns-pinmux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,18 @@ 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:
- brcm,bcm4708-pinmux
- 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$':
Expand Down Expand Up @@ -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 {
compatible = "brcm,bcm4708-pinmux";
offset = <0xc0>;
spi-pins {
function = "spi";
groups = "spi_grp";
};
pin-controller@1800c1c0 {
compatible = "brcm,bcm4708-pinmux";
reg = <0x1800c1c0 0x24>;
reg-names = "cru_gpio_control";
spi-pins {
function = "spi";
groups = "spi_grp";
};
};
29 changes: 10 additions & 19 deletions drivers/pinctrl/bcm/pinctrl-ns.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@

#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>
#include <linux/pinctrl/pinconf-generic.h>
#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)
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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));
Expand Down
31 changes: 31 additions & 0 deletions drivers/pinctrl/pinctrl-amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 */
Expand Down
4 changes: 2 additions & 2 deletions drivers/pinctrl/stm32/pinctrl-stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit a51aec4

Please sign in to comment.