Commit f6606d0c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'irq-core-2020-06-02' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
 "The generic interrupt departement provides:

   - Cleanup of the irq_domain API

   - Overhaul of the interrupt chip simulator

   - The usual pile of new interrupt chip drivers

   - Cleanups, improvements and fixes all over the place"

* tag 'irq-core-2020-06-02' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits)
  irqchip: Fix "Loongson HyperTransport Vector support" driver build on all non-MIPS platforms
  dt-bindings: interrupt-controller: Add Loongson PCH MSI
  irqchip: Add Loongson PCH MSI controller
  dt-bindings: interrupt-controller: Add Loongson PCH PIC
  irqchip: Add Loongson PCH PIC controller
  dt-bindings: interrupt-controller: Add Loongson HTVEC
  irqchip: Add Loongson HyperTransport Vector support
  genirq: Check irq_data_get_irq_chip() return value before use
  irqchip/sifive-plic: Improve boot prints for multiple PLIC instances
  irqchip/sifive-plic: Setup cpuhp once after boot CPU handler is present
  irqchip/sifive-plic: Set default irq affinity in plic_irqdomain_map()
  irqchip/gic-v2, v3: Drop extra IRQ_NOAUTOEN setting for (E)PPIs
  irqdomain: Allow software nodes for IRQ domain creation
  irqdomain: Get rid of special treatment for ACPI in __irq_domain_add()
  irqdomain: Make __irq_domain_add() less OF-dependent
  iio: dummy_evgen: Fix use after free on error in iio_dummy_evgen_create()
  irqchip/gic-v3-its: Balance initial LPI affinity across CPUs
  irqchip/gic-v3-its: Track LPI distribution on a per CPU basis
  genirq/irq_sim: Simplify the API
  irqdomain: Make irq_domain_reset_irq_data() available to  non-hierarchical users
  ...
parents d6f9469a d77aeb5d
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/interrupt-controller/loongson,htvec.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"

title: Loongson-3 HyperTransport Interrupt Vector Controller

maintainers:
  - Jiaxun Yang <jiaxun.yang@flygoat.com>

description:
  This interrupt controller is found in the Loongson-3 family of chips for
  receiving vectorized interrupts from PCH's interrupt controller.

properties:
  compatible:
    const: loongson,htvec-1.0

  reg:
    maxItems: 1

  interrupts:
    minItems: 1
    maxItems: 4
    description: Four parent interrupts that receive chained interrupts.

  interrupt-controller: true

  '#interrupt-cells':
    const: 1

required:
  - compatible
  - reg
  - interrupts
  - interrupt-controller
  - '#interrupt-cells'

additionalProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/irq.h>
    htvec: interrupt-controller@fb000080 {
      compatible = "loongson,htvec-1.0";
      reg = <0xfb000080 0x40>;
      interrupt-controller;
      #interrupt-cells = <1>;

      interrupt-parent = <&liointc>;
      interrupts = <24 IRQ_TYPE_LEVEL_HIGH>,
                    <25 IRQ_TYPE_LEVEL_HIGH>,
                    <26 IRQ_TYPE_LEVEL_HIGH>,
                    <27 IRQ_TYPE_LEVEL_HIGH>;
    };
...
+62 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/interrupt-controller/loongson,pch-msi.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"

title: Loongson PCH MSI Controller

maintainers:
  - Jiaxun Yang <jiaxun.yang@flygoat.com>

description:
  This interrupt controller is found in the Loongson LS7A family of PCH for
  transforming interrupts from PCIe MSI into HyperTransport vectorized
  interrupts.

properties:
  compatible:
    const: loongson,pch-msi-1.0

  reg:
    maxItems: 1

  loongson,msi-base-vec:
    description:
      u32 value of the base of parent HyperTransport vector allocated
      to PCH MSI.
    allOf:
      - $ref: "/schemas/types.yaml#/definitions/uint32"
      - minimum: 0
        maximum: 255

  loongson,msi-num-vecs:
    description:
      u32 value of the number of parent HyperTransport vectors allocated
      to PCH MSI.
    allOf:
      - $ref: "/schemas/types.yaml#/definitions/uint32"
      - minimum: 1
        maximum: 256

  msi-controller: true

required:
  - compatible
  - reg
  - msi-controller
  - loongson,msi-base-vec
  - loongson,msi-num-vecs

examples:
  - |
    #include <dt-bindings/interrupt-controller/irq.h>
    msi: msi-controller@2ff00000 {
      compatible = "loongson,pch-msi-1.0";
      reg = <0x2ff00000 0x4>;
      msi-controller;
      loongson,msi-base-vec = <64>;
      loongson,msi-num-vecs = <64>;
      interrupt-parent = <&htvec>;
    };
...
+56 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/interrupt-controller/loongson,pch-pic.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"

title: Loongson PCH PIC Controller

maintainers:
  - Jiaxun Yang <jiaxun.yang@flygoat.com>

description:
  This interrupt controller is found in the Loongson LS7A family of PCH for
  transforming interrupts from on-chip devices into HyperTransport vectorized
  interrupts.

properties:
  compatible:
    const: loongson,pch-pic-1.0

  reg:
    maxItems: 1

  loongson,pic-base-vec:
    description:
      u32 value of the base of parent HyperTransport vector allocated
      to PCH PIC.
    allOf:
      - $ref: "/schemas/types.yaml#/definitions/uint32"
      - minimum: 0
        maximum: 192

  interrupt-controller: true

  '#interrupt-cells':
    const: 2

required:
  - compatible
  - reg
  - loongson,pic-base-vec
  - interrupt-controller
  - '#interrupt-cells'

examples:
  - |
    #include <dt-bindings/interrupt-controller/irq.h>
    pic: interrupt-controller@10000000 {
      compatible = "loongson,pch-pic-1.0";
      reg = <0x10000000 0x400>;
      interrupt-controller;
      #interrupt-cells = <2>;
      loongson,pic-base-vec = <64>;
      interrupt-parent = <&htvec>;
    };
...
+1 −1
Original line number Diff line number Diff line
@@ -387,7 +387,7 @@ void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
 *
 * @domain:	The platform-msi domain
 * @virq:	The base irq from which to perform the allocate operation
 * @nvec:	How many interrupts to free from @virq
 * @nr_irqs:	How many interrupts to free from @virq
 *
 * Return 0 on success, or an error code on failure. Must be called
 * with irq_domain_mutex held (which can only be done as part of a
+42 −11
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irq_sim.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
@@ -48,7 +49,7 @@ struct gpio_mockup_line_status {
struct gpio_mockup_chip {
	struct gpio_chip gc;
	struct gpio_mockup_line_status *lines;
	struct irq_sim irqsim;
	struct irq_domain *irq_sim_domain;
	struct dentry *dbg_dir;
	struct mutex lock;
};
@@ -144,14 +145,12 @@ static void gpio_mockup_set_multiple(struct gpio_chip *gc,
static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
				  unsigned int offset, int value)
{
	int curr, irq, irq_type, ret = 0;
	struct gpio_desc *desc;
	struct gpio_chip *gc;
	struct irq_sim *sim;
	int curr, irq, irq_type;

	gc = &chip->gc;
	desc = &gc->gpiodev->descs[offset];
	sim = &chip->irqsim;

	mutex_lock(&chip->lock);

@@ -161,14 +160,28 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
		if (curr == value)
			goto out;

		irq = irq_sim_irqnum(sim, offset);
		irq = irq_find_mapping(chip->irq_sim_domain, offset);
		if (!irq)
			/*
			 * This is fine - it just means, nobody is listening
			 * for interrupts on this line, otherwise
			 * irq_create_mapping() would have been called from
			 * the to_irq() callback.
			 */
			goto set_value;

		irq_type = irq_get_trigger_type(irq);

		if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
		    (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING)))
			irq_sim_fire(sim, offset);
		    (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING))) {
			ret = irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING,
						    true);
			if (ret)
				goto out;
		}
	}

set_value:
	/* Change the value unless we're actively driving the line. */
	if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
	    !test_bit(FLAG_IS_OUT, &desc->flags))
@@ -177,7 +190,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
out:
	chip->lines[offset].pull = value;
	mutex_unlock(&chip->lock);
	return 0;
	return ret;
}

static int gpio_mockup_set_config(struct gpio_chip *gc,
@@ -236,7 +249,7 @@ static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
{
	struct gpio_mockup_chip *chip = gpiochip_get_data(gc);

	return irq_sim_irqnum(&chip->irqsim, offset);
	return irq_create_mapping(chip->irq_sim_domain, offset);
}

static void gpio_mockup_free(struct gpio_chip *gc, unsigned int offset)
@@ -389,6 +402,19 @@ static int gpio_mockup_name_lines(struct device *dev,
	return 0;
}

static void gpio_mockup_dispose_mappings(void *data)
{
	struct gpio_mockup_chip *chip = data;
	struct gpio_chip *gc = &chip->gc;
	int i, irq;

	for (i = 0; i < gc->ngpio; i++) {
		irq = irq_find_mapping(chip->irq_sim_domain, i);
		if (irq)
			irq_dispose_mapping(irq);
	}
}

static int gpio_mockup_probe(struct platform_device *pdev)
{
	struct gpio_mockup_chip *chip;
@@ -456,8 +482,13 @@ static int gpio_mockup_probe(struct platform_device *pdev)
			return rv;
	}

	rv = devm_irq_sim_init(dev, &chip->irqsim, gc->ngpio);
	if (rv < 0)
	chip->irq_sim_domain = devm_irq_domain_create_sim(dev, NULL,
							  gc->ngpio);
	if (IS_ERR(chip->irq_sim_domain))
		return PTR_ERR(chip->irq_sim_domain);

	rv = devm_add_action_or_reset(dev, gpio_mockup_dispose_mappings, chip);
	if (rv)
		return rv;

	rv = devm_gpiochip_add_data(dev, &chip->gc, chip);
Loading