1. 09 11月, 2017 2 次提交
  2. 02 11月, 2017 8 次提交
    • P
      irqchip: mips-gic: Make IPI bitmaps static · 61dc367e
      Paul Burton 提交于
      We have 2 bitmaps used to keep track of interrupts dedicated to IPIs in
      the MIPS GIC irqchip driver. These bitmaps are only used from the one
      compilation unit of that driver, and so can be made static. Do so in
      order to avoid polluting the symbol table & global namespace.
      Signed-off-by: NPaul Burton <paul.burton@mips.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-mips@linux-mips.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      61dc367e
    • P
      irqchip: mips-gic: Share register writes in gic_set_type() · 5af3e93e
      Paul Burton 提交于
      The gic_set_type() function included writes to the MIPS GIC polarity,
      trigger & dual-trigger registers in each case of a switch statement
      determining the IRQs type. This is all well & good when we only have a
      single cluster & thus a single GIC whose register we want to update. It
      will lead to significant duplication once we have multi-cluster support
      & multiple GICs to update.
      
      Refactor this such that we determine values for the polarity, trigger &
      dual-trigger registers and then have a single set of register writes
      following the switch statement. This will allow us to write the same
      values to each GIC in a multi-cluster system in a later patch, rather
      than needing to duplicate more register writes in each case.
      Signed-off-by: NPaul Burton <paul.burton@mips.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-mips@linux-mips.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      5af3e93e
    • P
      irqchip: mips-gic: Remove gic_vpes variable · 82857688
      Paul Burton 提交于
      Following the past few patches nothing uses the gic_vpes variable any
      longer. Remove the dead code.
      Signed-off-by: NPaul Burton <paul.burton@mips.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-mips@linux-mips.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      82857688
    • P
      irqchip: mips-gic: Use num_possible_cpus() to reserve IPIs · 25c51dad
      Paul Burton 提交于
      Reserving a number of IPIs based upon the number of VPs reported by the
      GIC makes little sense for a few reasons:
      
       - The kernel may have been configured with NR_CPUS less than the number
         of VPs in the cluster, in which case using gic_vpes causes us to
         reserve more interrupts for IPIs than we will possibly use.
      
       - If a kernel is configured without support for multi-threading & runs
         on a system with multi-threading & multiple VPs per core then we'll
         similarly reserve more interrupts for IPIs than we will possibly use.
      
       - In systems with multiple clusters the GIC can only provide us with
         the number of VPs in its cluster, not across all clusters. In this
         case we'll reserve fewer interrupts for IPIs than we need.
      
      Fix these issues by using num_possible_cpus() instead, which in all
      cases is actually indicative of how many IPIs we may need.
      Signed-off-by: NPaul Burton <paul.burton@mips.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-mips@linux-mips.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      25c51dad
    • P
      irqchip: mips-gic: Configure EIC when CPUs come online · 890f6b55
      Paul Burton 提交于
      Rather than configuring EIC mode for all CPUs during boot, configure it
      locally on each when they come online. This will become important with
      multi-cluster support, since clusters may be powered on & off (for
      example via hotplug) and would lose the EIC configuration when powered
      off.
      Signed-off-by: NPaul Burton <paul.burton@mips.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-mips@linux-mips.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      890f6b55
    • P
      irqchip: mips-gic: Mask local interrupts when CPUs come online · 25ac19e1
      Paul Burton 提交于
      We currently walk through the range 0..gic_vpes-1, expecting these
      values all to be valid Linux CPU numbers to provide to mips_cm_vp_id(),
      and masking all routable local interrupts during boot. This approach has
      a few drawbacks:
      
       - In multi-cluster systems we won't have access to all CPU's GIC local
         registers when the driver is probed, since clusters (and their GICs)
         may be powered down at this point & only brought online later.
      
       - In multi-cluster systems we may power down clusters at runtime, for
         example if we offline all CPUs within it via hotplug, and the
         cluster's GIC may lose state. We therefore need to reinitialise it
         when powering back up, which this approach does not take into
         account.
      
       - The range 0..gic_vpes-1 may not all be valid Linux CPU numbers, for
         example if we run a kernel configured to support fewer CPUs than the
         system it is running on actually has. In this case we'll get garbage
         values from mips_cm_vp_id() as we read past the end of the cpu_data
         array.
      
      Fix this and simplify the code somewhat by writing an all-bits-set
      value to the VP-local reset mask register when a CPU is brought online,
      before any local interrupts are configured for it. This removes the need
      for us to access all CPUs during driver probe, removing all of the
      problems described above.
      
      In the name of simplicity we drop the checks for routability of
      interrupts and simply clear the mask bits for all interrupts. Bits for
      non-routable local interrupts will have no effect so there's no point
      performing extra work to avoid modifying them.
      Signed-off-by: NPaul Burton <paul.burton@mips.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-mips@linux-mips.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      25ac19e1
    • P
      irqchip: mips-gic: Use irq_cpu_online to (un)mask all-VP(E) IRQs · da61fcf9
      Paul Burton 提交于
      The gic_all_vpes_local_irq_controller chip currently attempts to operate
      on all CPUs/VPs in the system when masking or unmasking an interrupt.
      This has a few drawbacks:
      
       - In multi-cluster systems we may not always have access to all CPUs in
         the system. When all CPUs in a cluster are powered down that
         cluster's GIC may also power down, in which case we cannot configure
         its state.
      
       - Relatedly, if we power down a cluster after having configured
         interrupts for CPUs within it then the cluster's GIC may lose state &
         we need to reconfigure it. The current approach doesn't take this
         into account.
      
       - It's wasteful if we run Linux on fewer VPs than are present in the
         system. For example if we run a uniprocessor kernel on CPU0 of a
         system with 16 CPUs then there's no point in us configuring CPUs
         1-15.
      
       - The implementation is also lacking in that it expects the range
         0..gic_vpes-1 to represent valid Linux CPU numbers which may not
         always be the case - for example if we run on a system with more VPs
         than the kernel is configured to support.
      
      Fix all of these issues by only configuring the affected interrupts for
      CPUs which are online at the time, and recording the configuration in a
      new struct gic_all_vpes_chip_data for later use by CPUs being brought
      online. We register a CPU hotplug state (reusing
      CPUHP_AP_IRQ_GIC_STARTING which the ARM GIC driver uses, and which seems
      suitably generic for reuse with the MIPS GIC) and execute
      irq_cpu_online() in order to configure the interrupts on the newly
      onlined CPU.
      Signed-off-by: NPaul Burton <paul.burton@mips.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-mips@linux-mips.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      da61fcf9
    • P
      irqchip: mips-gic: Inline gic_local_irq_domain_map() · 63b746b1
      Paul Burton 提交于
      The gic_local_irq_domain_map() function has only one callsite in
      gic_irq_domain_map(), and the split between the two functions makes it
      unclear that they duplicate calculations & checks.
      
      Inline gic_local_irq_domain_map() into gic_irq_domain_map() in order to
      clean this up. Doing this makes the following small issues obvious, and
      the patch tidies them up:
      
       - Both functions used GIC_HWIRQ_TO_LOCAL() to convert a hwirq number to
         a local IRQ number. We now only do this once. Although the compiler
         ought to have optimised this away before anyway, the change leaves us
         with less duplicate code.
      
       - gic_local_irq_domain_map() had a check for invalid local interrupt
         numbers (intr > GIC_LOCAL_INT_FDC). This condition can never occur
         because any hwirq higher than those used for local interrupts is a
         shared interrupt, which gic_irq_domain_map() already handles
         separately. We therefore remove this check.
      
       - The decision of whether to map the interrupt to gic_cpu_pin or
         timer_cpu_pin can be handled within the existing switch statement in
         gic_irq_domain_map(), shortening the code a little.
      
      The change additionally prepares us nicely for the following patch of
      the series which would otherwise need to duplicate the check for whether
      a local interrupt should be percpu_devid or just percpu (ie. the switch
      statement from gic_irq_domain_map()) in gic_local_irq_domain_map().
      Signed-off-by: NPaul Burton <paul.burton@mips.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-mips@linux-mips.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      63b746b1
  3. 26 9月, 2017 2 次提交
    • P
      irqchip/mips-gic: Use effective affinity to unmask · d9f82930
      Paul Burton 提交于
      Commit 7778c4b2 ("irqchip: mips-gic: Use pcpu_masks to avoid reading
      GIC_SH_MASK*") adjusted the way we handle masking interrupts to set &
      clear the interrupt's bit in each pcpu_mask. This allows us to avoid
      needing to read the GIC mask registers and perform a bitwise and of
      their values with the pending & pcpu_masks.
      
      Unfortunately this didn't quite work for IPIs, which were mapped to a
      particular CPU/VP during initialisation but never set the affinity or
      effective_affinity fields of their struct irq_desc. This led to them
      losing their affinity when gic_unmask_irq() was called for them, and
      they'd all become affine to cpu0.
      
      Fix this by:
      
       1) Setting the effective affinity of interrupts in
          gic_shared_irq_domain_map(), which is where we actually map an
          interrupt to a CPU/VP. This ensures that the effective affinity mask
          is always valid, not just after explicitly setting affinity.
      
       2) Using an interrupt's effective affinity when unmasking it, which
          prevents gic_unmask_irq() from unintentionally changing which
          pcpu_mask includes an interrupt.
      
      
      Fixes: 7778c4b2 ("irqchip: mips-gic: Use pcpu_masks to avoid reading GIC_SH_MASK*")
      Signed-off-by: NPaul Burton <paul.burton@imgtec.com>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Link: https://lkml.kernel.org/r/20170922062440.23701-3-paul.burton@imgtec.com
      d9f82930
    • P
      irqchip/mips-gic: Fix shifts to extract register fields · a08588ea
      Paul Burton 提交于
      The MIPS GIC driver is incorrectly using __fls to shift registers,
      intending to shift to the least significant bit of a value based upon
      its mask but instead shifting off all but the value's top bit. It should
      actually be using __ffs to shift to the first, not last, bit of the
      value.
      
      Apparently the system I used when testing commit 3680746a
      ("irqchip: mips-gic: Convert remaining shared reg access to new
      accessors") and commit b2b2e584 ("irqchip: mips-gic: Clean up mti,
      reserved-cpu-vectors handling") managed to work correctly despite this
      issue, but not all systems do...
      
      Fixes: 3680746a ("irqchip: mips-gic: Convert remaining shared reg access to new accessors")
      Fixes: b2b2e584 ("irqchip: mips-gic: Clean up mti, reserved-cpu-vectors handling")
      Signed-off-by: NPaul Burton <paul.burton@imgtec.com>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Link: https://lkml.kernel.org/r/20170922062440.23701-2-paul.burton@imgtec.com
      a08588ea
  4. 20 9月, 2017 1 次提交
    • P
      irqchip.mips-gic: Fix shared interrupt mask writes · 90019f8f
      Paul Burton 提交于
      The write_gic_smask() & write_gic_rmask() functions take a shared
      interrupt number as a parameter, but we're incorrectly providing them a
      bitmask with the shared interrupt's bit set. This effectively means that
      we mask or unmask the shared interrupt 1<<n rather than shared interrupt
      n, and as a result likely drop interrupts.
      Signed-off-by: NPaul Burton <paul.burton@imgtec.com>
      Fixes: 68898c8765f4 ("irqchip: mips-gic: Drop gic_(re)set_mask() functions")
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Ralf Baechle <ralf@linux-mips.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-mips@linux-mips.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      90019f8f
  5. 04 9月, 2017 26 次提交
  6. 30 8月, 2017 1 次提交
    • P
      MIPS: GIC: Introduce asm/mips-gic.h with accessor functions · 582e2b4a
      Paul Burton 提交于
      This patch introduces a new header providing accessor functions for the
      MIPS Global Interrupt Controller (GIC) mirroring those provided for the
      other 2 components of the MIPS Coherent Processing System (CPS) - the
      Coherence Manager (CM) & Cluster Power Controller (CPC).
      
      This header makes use of the new standardised CPS accessor macros where
      possible, but does require some custom accessors for cases where we have
      either a bit or a register per interrupt.
      
      A major advantage of this over the existing
      include/linux/irqchip/mips-gic.h definitions is that code performing
      accesses can become much simpler, for example this:
      
        gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
                        GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
                        (unsigned long)trig << GIC_INTR_BIT(intr));
      
      ...can become simply:
      
        change_gic_trig(intr, trig);
      
      The accessors handle 32 vs 64 bit in the same way as for CM & CPC code,
      which means that GIC code will also not need to worry about the access
      size in most cases. They are also accessible outside of
      drivers/irqchip/irq-mips-gic.c which will allow for simplification in
      the use of the non-interrupt portions of the GIC (eg. counters) which
      currently require the interrupt controller driver to expose helper
      functions for access.
      
      This patch doesn't change any existing code over to use the new
      accessors yet, since a wholesale change would be invasive & difficult to
      review. Instead follow-on patches will convert code piecemeal to use
      this new header. The one change to existing code is to rename gic_base
      to mips_gic_base & make it global, in order to fit in with the naming
      expected by the standardised CPS accessor macros.
      Signed-off-by: NPaul Burton <paul.burton@imgtec.com>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-kernel@vger.kernel.org
      Cc: linux-mips@linux-mips.org
      Patchwork: https://patchwork.linux-mips.org/patch/17020/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
      582e2b4a