riscv64: drop old patches
authorZoltan HERPAI <wigyori@uid0.hu>
Mon, 15 Oct 2018 14:13:43 +0000 (16:13 +0200)
committerZoltan HERPAI <wigyori@uid0.hu>
Mon, 15 Oct 2018 14:13:43 +0000 (16:13 +0200)
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
target/linux/riscv64/patches/0001-base-fix-order-of-OF-initialization.patch [deleted file]
target/linux/riscv64/patches/0002-dt-bindings-Correct-RISC-V-s-timebase-frequency.patch [deleted file]
target/linux/riscv64/patches/0003-dt-bindings-Add-an-enable-method-to-RISC-V.patch [deleted file]
target/linux/riscv64/patches/0004-RISC-V-Add-early-printk-support-via-the-SBI-console.patch [deleted file]
target/linux/riscv64/patches/0005-RISC-V-simplify-software-interrupt-IPI-code.patch [deleted file]
target/linux/riscv64/patches/0006-RISC-V-remove-INTERRUPT_CAUSE_-defines-from-asm-irq..patch [deleted file]
target/linux/riscv64/patches/0007-irqchip-RISC-V-Local-Interrupt-Controller-Driver.patch [deleted file]
target/linux/riscv64/patches/0008-dt-bindings-interrupt-controller-RISC-V-local-interr.patch [deleted file]
target/linux/riscv64/patches/0009-irqchip-New-RISC-V-PLIC-Driver.patch [deleted file]
target/linux/riscv64/patches/0010-dt-bindings-interrupt-controller-RISC-V-PLIC-documen.patch [deleted file]
target/linux/riscv64/patches/0011-clocksource-new-RISC-V-SBI-timer-driver.patch [deleted file]

diff --git a/target/linux/riscv64/patches/0001-base-fix-order-of-OF-initialization.patch b/target/linux/riscv64/patches/0001-base-fix-order-of-OF-initialization.patch
deleted file mode 100644 (file)
index 024b51e..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From 6de0b16fb7a2cea47e9a75534b4ec59f36998616 Mon Sep 17 00:00:00 2001
-From: "Wesley W. Terpstra" <wesley@sifive.com>
-Date: Fri, 12 May 2017 16:01:18 -0700
-Subject: [PATCH 01/11] base: fix order of OF initialization
-
-This fixes: [    0.010000] cpu cpu0: Error -2 creating of_node link
-... which you get for every CPU on all architectures with a OF cpu/ node.
-
-This affects riscv, nios, etc.
-
-Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
----
- drivers/base/init.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/base/init.c b/drivers/base/init.c
-index dd85b05..908e652 100644
---- a/drivers/base/init.c
-+++ b/drivers/base/init.c
-@@ -30,9 +30,9 @@ void __init driver_init(void)
-       /* These are also core pieces, but must come after the
-        * core core pieces.
-        */
-+      of_core_init();
-       platform_bus_init();
-       cpu_dev_init();
-       memory_dev_init();
-       container_dev_init();
--      of_core_init();
- }
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0002-dt-bindings-Correct-RISC-V-s-timebase-frequency.patch b/target/linux/riscv64/patches/0002-dt-bindings-Correct-RISC-V-s-timebase-frequency.patch
deleted file mode 100644 (file)
index 032738c..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-From 7866ef38a00cd390596a67e19d23d8ffd6058732 Mon Sep 17 00:00:00 2001
-From: Palmer Dabbelt <palmer@sifive.com>
-Date: Tue, 21 Nov 2017 15:29:07 -0800
-Subject: [PATCH 02/11] dt-bindings: Correct RISC-V's timebase-frequency
-
-Someone must have read the device tree specification incorrectly,
-because we were putting timebase-frequency in the wrong place.  This
-corrects the issue, moving it from
-
-/ {
-        cpus {
-                timebase-frequency = X;
-        }
-}
-
-to
-
-/ {
-        cpus {
-                cpu@0 {
-                        timebase-frequency = X;
-                }
-        }
-}
-
-This is great, because the timer's frequency should really be a per-cpu
-quantity on RISC-V systems since there's a timer per CPU.  This should
-lead to some cleanups in our timer driver.
-
-CC: Wesley Terpstra <wesley@sifive.com>
-Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
----
- Documentation/devicetree/bindings/riscv/cpus.txt | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/Documentation/devicetree/bindings/riscv/cpus.txt b/Documentation/devicetree/bindings/riscv/cpus.txt
-index adf7b7a..b0b038d 100644
---- a/Documentation/devicetree/bindings/riscv/cpus.txt
-+++ b/Documentation/devicetree/bindings/riscv/cpus.txt
-@@ -93,9 +93,9 @@ Linux is allowed to run on.
-         cpus {
-                 #address-cells = <1>;
-                 #size-cells = <0>;
--                timebase-frequency = <1000000>;
-                 cpu@0 {
-                         clock-frequency = <1600000000>;
-+                        timebase-frequency = <1000000>;
-                         compatible = "sifive,rocket0", "riscv";
-                         device_type = "cpu";
-                         i-cache-block-size = <64>;
-@@ -113,6 +113,7 @@ Linux is allowed to run on.
-                 };
-                 cpu@1 {
-                         clock-frequency = <1600000000>;
-+                        timebase-frequency = <1000000>;
-                         compatible = "sifive,rocket0", "riscv";
-                         d-cache-block-size = <64>;
-                         d-cache-sets = <64>;
-@@ -145,6 +146,7 @@ Example: Spike ISA Simulator with 1 Hart
- This device tree matches the Spike ISA golden model as run with `spike -p1`.
-         cpus {
-+                timebase-frequency = <1000000>;
-                 cpu@0 {
-                         device_type = "cpu";
-                         reg = <0x00000000>;
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0003-dt-bindings-Add-an-enable-method-to-RISC-V.patch b/target/linux/riscv64/patches/0003-dt-bindings-Add-an-enable-method-to-RISC-V.patch
deleted file mode 100644 (file)
index 8c6e297..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-From fd7aef2aae3b2d250f0c04224b3c85646c2e9c56 Mon Sep 17 00:00:00 2001
-From: Palmer Dabbelt <palmer@sifive.com>
-Date: Mon, 20 Nov 2017 11:26:36 -0800
-Subject: [PATCH 03/11] dt-bindings: Add an enable method to RISC-V
-
-RISC-V doesn't currently specify a mechanism for enabling or disabling
-CPUs.  Instead, we assume that all CPUs are enabled on boot, and if
-someone wants to save power we instead put a CPU to sleep via a WFI
-loop.  Future systems may have an explicit mechanism for putting a CPU
-to sleep, so we're standardizing the device tree entry for when that
-happens.
-
-We're not defining a spin-table based interface to the firmware, as the
-plan is to handle this entirely within the kernel instead.
-
-CC: Mark Rutland <mark.rutland@arm.com>
-Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
----
- Documentation/devicetree/bindings/riscv/cpus.txt | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/Documentation/devicetree/bindings/riscv/cpus.txt b/Documentation/devicetree/bindings/riscv/cpus.txt
-index b0b038d..6aa9cd0 100644
---- a/Documentation/devicetree/bindings/riscv/cpus.txt
-+++ b/Documentation/devicetree/bindings/riscv/cpus.txt
-@@ -82,6 +82,15 @@ described below.
-                 Value type: <string>
-                 Definition: Contains the RISC-V ISA string of this hart.  These
-                             ISA strings are defined by the RISC-V ISA manual.
-+        - cpu-enable-method:
-+                Usage: optional
-+                Value type: <stringlist>
-+                Definition: When absent, default is either "always-disabled"
-+                            "always-enabled", depending on the current state
-+                            of the CPU.
-+                            Must be one of:
-+                                * "always-disabled": This CPU cannot be enabled.
-+                                * "always-enabled": This CPU cannot be disabled.
- Example: SiFive Freedom U540G Development Kit
- ---------------------------------------------
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0004-RISC-V-Add-early-printk-support-via-the-SBI-console.patch b/target/linux/riscv64/patches/0004-RISC-V-Add-early-printk-support-via-the-SBI-console.patch
deleted file mode 100644 (file)
index 5bffed5..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-From 577949829e04d23f58ef4ad5c448689c2ed70a49 Mon Sep 17 00:00:00 2001
-From: Palmer Dabbelt <palmer@dabbelt.com>
-Date: Fri, 8 Dec 2017 15:10:35 -0800
-Subject: [PATCH 04/11] RISC-V: Add early printk support via the SBI console
-
-This code lives entirely within the RISC-V arch code.  I've left it
-within an "#ifdef CONFIG_EARLY_PRINTK" despite always having
-EARLY_PRINTK support on RISC-V just in case someone wants to remove
-it.
-
-Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
----
- arch/riscv/kernel/setup.c | 27 +++++++++++++++++++++++++++
- 1 file changed, 27 insertions(+)
-
-diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
-index f0d2070..2e56af3 100644
---- a/arch/riscv/kernel/setup.c
-+++ b/arch/riscv/kernel/setup.c
-@@ -39,6 +39,27 @@
- #include <asm/tlbflush.h>
- #include <asm/thread_info.h>
-+#ifdef CONFIG_EARLY_PRINTK
-+static void sbi_console_write(struct console *co, const char *buf,
-+                            unsigned int n)
-+{
-+      int i;
-+
-+      for (i = 0; i < n; ++i) {
-+              if (buf[i] == '\n')
-+                      sbi_console_putchar('\r');
-+              sbi_console_putchar(buf[i]);
-+      }
-+}
-+
-+struct console riscv_sbi_early_console_dev __initdata = {
-+      .name   = "early",
-+      .write  = sbi_console_write,
-+      .flags  = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME,
-+      .index  = -1
-+};
-+#endif
-+
- #ifdef CONFIG_DUMMY_CONSOLE
- struct screen_info screen_info = {
-       .orig_video_lines       = 30,
-@@ -195,6 +216,12 @@ static void __init setup_bootmem(void)
- void __init setup_arch(char **cmdline_p)
- {
-+#ifdef CONFIG_EARLY_PRINTK
-+      if (likely(!early_console)) {
-+              early_console = &riscv_sbi_early_console_dev;
-+              register_console(early_console);
-+      }
-+#endif
-       *cmdline_p = boot_command_line;
-       parse_early_param();
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0005-RISC-V-simplify-software-interrupt-IPI-code.patch b/target/linux/riscv64/patches/0005-RISC-V-simplify-software-interrupt-IPI-code.patch
deleted file mode 100644 (file)
index 4c5fce0..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-From b3b48cbc8a19fc3e3abd3ae9b5d271c12a1a0b87 Mon Sep 17 00:00:00 2001
-From: Christoph Hellwig <hch@lst.de>
-Date: Wed, 25 Jul 2018 08:11:13 +0200
-Subject: [PATCH 05/11] RISC-V: simplify software interrupt / IPI code
-
-Rename handle_ipi to riscv_software_interrupt, drop the unused return
-value and provide a stub for the !SMP build.  This allows simplifying
-the upcoming interrupt controller driver by not providing a wrapper
-for it.
-
-Signed-off-by: Christoph Hellwig <hch@lst.de>
----
- arch/riscv/include/asm/smp.h | 13 +++++++++++--
- arch/riscv/kernel/smp.c      |  6 ++----
- 2 files changed, 13 insertions(+), 6 deletions(-)
-
-diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h
-index 85e4220..80ecb95 100644
---- a/arch/riscv/include/asm/smp.h
-+++ b/arch/riscv/include/asm/smp.h
-@@ -44,8 +44,17 @@ void arch_send_call_function_single_ipi(int cpu);
-  */
- #define raw_smp_processor_id() (*((int*)((char*)get_current() + TASK_TI_CPU)))
--/* Interprocessor interrupt handler */
--irqreturn_t handle_ipi(void);
-+/* Software interrupt handler */
-+void riscv_software_interrupt(void);
-+
-+#else /* CONFIG_SMP */
-+
-+/*
-+ * We currently only use software interrupts to pass inter-processor
-+ * interrupts, so if a non-SMP system gets a software interrupt then we
-+ * don't know what to do.
-+ */
-+#define riscv_software_interrupt()    WARN_ON()
- #endif /* CONFIG_SMP */
-diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
-index 6d39624..906fe21 100644
---- a/arch/riscv/kernel/smp.c
-+++ b/arch/riscv/kernel/smp.c
-@@ -45,7 +45,7 @@ int setup_profiling_timer(unsigned int multiplier)
-       return -EINVAL;
- }
--irqreturn_t handle_ipi(void)
-+void riscv_software_interrupt(void)
- {
-       unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits;
-@@ -60,7 +60,7 @@ irqreturn_t handle_ipi(void)
-               ops = xchg(pending_ipis, 0);
-               if (ops == 0)
--                      return IRQ_HANDLED;
-+                      return;
-               if (ops & (1 << IPI_RESCHEDULE))
-                       scheduler_ipi();
-@@ -73,8 +73,6 @@ irqreturn_t handle_ipi(void)
-               /* Order data access and bit testing. */
-               mb();
-       }
--
--      return IRQ_HANDLED;
- }
- static void
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0006-RISC-V-remove-INTERRUPT_CAUSE_-defines-from-asm-irq..patch b/target/linux/riscv64/patches/0006-RISC-V-remove-INTERRUPT_CAUSE_-defines-from-asm-irq..patch
deleted file mode 100644 (file)
index 1f22061..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From 422e21b7ab41a21d7342b01fea7d1c6b91d986d8 Mon Sep 17 00:00:00 2001
-From: Christoph Hellwig <hch@lst.de>
-Date: Wed, 25 Jul 2018 08:23:21 +0200
-Subject: [PATCH 06/11] RISC-V: remove INTERRUPT_CAUSE_* defines from asm/irq.h
-
-These are only of use to the local irq controller driver, so add them in
-that driver implementation instead, which will be submitted soon.
-
-Signed-off-by: Christoph Hellwig <hch@lst.de>
----
- arch/riscv/include/asm/irq.h | 4 ----
- 1 file changed, 4 deletions(-)
-
-diff --git a/arch/riscv/include/asm/irq.h b/arch/riscv/include/asm/irq.h
-index 4dee9d4..93eb75e 100644
---- a/arch/riscv/include/asm/irq.h
-+++ b/arch/riscv/include/asm/irq.h
-@@ -17,10 +17,6 @@
- #define NR_IRQS         0
--#define INTERRUPT_CAUSE_SOFTWARE    1
--#define INTERRUPT_CAUSE_TIMER       5
--#define INTERRUPT_CAUSE_EXTERNAL    9
--
- void riscv_timer_interrupt(void);
- #include <asm-generic/irq.h>
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0007-irqchip-RISC-V-Local-Interrupt-Controller-Driver.patch b/target/linux/riscv64/patches/0007-irqchip-RISC-V-Local-Interrupt-Controller-Driver.patch
deleted file mode 100644 (file)
index 107b6b7..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-From e07e6be7ef8b44155aebac95dde19a39498ebd00 Mon Sep 17 00:00:00 2001
-From: Palmer Dabbelt <palmer@dabbelt.com>
-Date: Tue, 19 Jun 2018 17:34:53 +0200
-Subject: [PATCH 07/11] irqchip: RISC-V Local Interrupt Controller Driver
-
-This patch adds a driver that manages the local interrupts on each
-RISC-V hart, as specifiec by the RISC-V supervisor level ISA manual.
-The local interrupt controller manages software interrupts, timer
-interrupts, and hardware interrupts (which are routed via the
-platform level interrupt controller).  Per-hart local interrupt
-controllers are found on all RISC-V systems.
-
-Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
-[hch: Kconfig simplifications, various cleanups]
-Signed-off-by: Christoph Hellwig <hch@lst.de>
----
- drivers/irqchip/Kconfig          |   4 +
- drivers/irqchip/Makefile         |   1 +
- drivers/irqchip/irq-riscv-intc.c | 197 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 202 insertions(+)
- create mode 100644 drivers/irqchip/irq-riscv-intc.c
-
-diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
-index e9233db..8460fdce 100644
---- a/drivers/irqchip/Kconfig
-+++ b/drivers/irqchip/Kconfig
-@@ -372,3 +372,7 @@ config QCOM_PDC
-         IRQs for Qualcomm Technologies Inc (QTI) mobile chips.
- endmenu
-+
-+config RISCV_INTC
-+      def_bool y
-+      depends on RISCV
-diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
-index 15f268f..74e333c 100644
---- a/drivers/irqchip/Makefile
-+++ b/drivers/irqchip/Makefile
-@@ -87,3 +87,4 @@ obj-$(CONFIG_MESON_IRQ_GPIO)         += irq-meson-gpio.o
- obj-$(CONFIG_GOLDFISH_PIC)            += irq-goldfish-pic.o
- obj-$(CONFIG_NDS32)                   += irq-ativic32.o
- obj-$(CONFIG_QCOM_PDC)                        += qcom-pdc.o
-+obj-$(CONFIG_RISCV_INTC)              += irq-riscv-intc.o
-diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
-new file mode 100644
-index 0000000..883efaa
---- /dev/null
-+++ b/drivers/irqchip/irq-riscv-intc.c
-@@ -0,0 +1,197 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2012 Regents of the University of California
-+ * Copyright (C) 2017 SiFive
-+ */
-+#include <linux/irq.h>
-+#include <linux/irqchip.h>
-+#include <linux/irqdomain.h>
-+#include <linux/interrupt.h>
-+#include <linux/of.h>
-+#include <linux/smp.h>
-+#include <asm/sbi.h>
-+
-+#define NR_RISCV_IRQS (8 * sizeof(uintptr_t))
-+
-+/*
-+ * Possible interrupt causes:
-+ */
-+#define INTERRUPT_CAUSE_SOFTWARE    1
-+#define INTERRUPT_CAUSE_TIMER       5
-+#define INTERRUPT_CAUSE_EXTERNAL    9
-+
-+/*
-+ * The high order bit of the trap cause register is always set for
-+ * interrupts, which allows us to differentiate them from exceptions
-+ * quickly.  The INTERRUPT_CAUSE_* macros don't contain that bit, so we
-+ * need to mask it off.
-+ */
-+#define INTERRUPT_CAUSE_MASK  (1UL << (NR_RISCV_IRQS - 1))
-+
-+struct riscv_irq_data {
-+      struct irq_chip         chip;
-+      struct irq_domain       *domain;
-+      int                     hart;
-+      char                    name[20];
-+};
-+
-+static DEFINE_PER_CPU(struct riscv_irq_data, riscv_irq_data);
-+
-+static void riscv_intc_irq(struct pt_regs *regs)
-+{
-+      struct pt_regs *old_regs = set_irq_regs(regs);
-+      unsigned long cause = csr_read(scause);
-+      struct irq_domain *domain;
-+
-+      WARN_ON((cause & INTERRUPT_CAUSE_MASK) == 0);
-+      cause &= ~INTERRUPT_CAUSE_MASK;
-+
-+      irq_enter();
-+
-+      /*
-+       * There are three classes of interrupt: timer, software, and
-+       * external devices.  We dispatch between them here.  External
-+       * device interrupts use the generic IRQ mechanisms.
-+       */
-+      switch (cause) {
-+      case INTERRUPT_CAUSE_TIMER:
-+              riscv_timer_interrupt();
-+              break;
-+      case INTERRUPT_CAUSE_SOFTWARE:
-+              riscv_software_interrupt();
-+              break;
-+      default:
-+              domain = per_cpu(riscv_irq_data, smp_processor_id()).domain;
-+              generic_handle_irq(irq_find_mapping(domain, cause));
-+              break;
-+      }
-+
-+      irq_exit();
-+      set_irq_regs(old_regs);
-+}
-+
-+static int riscv_irqdomain_map(struct irq_domain *d, unsigned int irq,
-+                             irq_hw_number_t hwirq)
-+{
-+      struct riscv_irq_data *data = d->host_data;
-+
-+      irq_set_chip_and_handler(irq, &data->chip, handle_simple_irq);
-+      irq_set_chip_data(irq, data);
-+      irq_set_noprobe(irq);
-+      irq_set_affinity(irq, cpumask_of(data->hart));
-+      return 0;
-+}
-+
-+static const struct irq_domain_ops riscv_irqdomain_ops = {
-+      .map    = riscv_irqdomain_map,
-+      .xlate  = irq_domain_xlate_onecell,
-+};
-+
-+/*
-+ * On RISC-V systems local interrupts are masked or unmasked by writing the SIE
-+ * (Supervisor Interrupt Enable) CSR.  As CSRs can only be written on the local
-+ * hart, these functions can only be called on the hart that corresponds to the
-+ * IRQ chip.  They are only called internally to this module, so they BUG_ON if
-+ * this condition is violated rather than attempting to handle the error by
-+ * forwarding to the target hart, as that's already expected to have been done.
-+ */
-+static void riscv_irq_mask(struct irq_data *d)
-+{
-+      struct riscv_irq_data *data = irq_data_get_irq_chip_data(d);
-+
-+      BUG_ON(smp_processor_id() != data->hart);
-+      csr_clear(sie, 1 << d->hwirq);
-+}
-+
-+static void riscv_irq_unmask(struct irq_data *d)
-+{
-+      struct riscv_irq_data *data = irq_data_get_irq_chip_data(d);
-+
-+      BUG_ON(smp_processor_id() != data->hart);
-+      csr_set(sie, 1 << d->hwirq);
-+}
-+
-+/* Callbacks for twiddling SIE on another hart. */
-+static void riscv_irq_enable_helper(void *d)
-+{
-+      riscv_irq_unmask(d);
-+}
-+
-+static void riscv_irq_disable_helper(void *d)
-+{
-+      riscv_irq_mask(d);
-+}
-+
-+static void riscv_remote_ctrl(unsigned int cpu, void (*fn)(void *d),
-+                            struct irq_data *data)
-+{
-+      smp_call_function_single(cpu, fn, data, true);
-+}
-+
-+static void riscv_irq_enable(struct irq_data *d)
-+{
-+      struct riscv_irq_data *data = irq_data_get_irq_chip_data(d);
-+
-+      /*
-+       * It's only possible to write SIE on the current hart.  This jumps
-+       * over to the target hart if it's not the current one.  It's invalid
-+       * to write SIE on a hart that's not currently running.
-+       */
-+      if (data->hart == smp_processor_id())
-+              riscv_irq_unmask(d);
-+      else if (cpu_online(data->hart))
-+              riscv_remote_ctrl(data->hart, riscv_irq_enable_helper, d);
-+      else
-+              WARN_ON_ONCE(1);
-+}
-+
-+static void riscv_irq_disable(struct irq_data *d)
-+{
-+      struct riscv_irq_data *data = irq_data_get_irq_chip_data(d);
-+
-+      /*
-+       * It's only possible to write SIE on the current hart.  This jumps
-+       * over to the target hart if it's not the current one.  It's invalid
-+       * to write SIE on a hart that's not currently running.
-+       */
-+      if (data->hart == smp_processor_id())
-+              riscv_irq_mask(d);
-+      else if (cpu_online(data->hart))
-+              riscv_remote_ctrl(data->hart, riscv_irq_disable_helper, d);
-+      else
-+              WARN_ON_ONCE(1);
-+}
-+
-+static int __init riscv_intc_init(struct device_node *node,
-+                                struct device_node *parent)
-+{
-+      struct riscv_irq_data *data;
-+      int hart;
-+
-+      hart = riscv_of_processor_hart(node->parent);
-+      if (hart < 0)
-+              return -EIO;
-+
-+      data = &per_cpu(riscv_irq_data, hart);
-+      snprintf(data->name, sizeof(data->name), "riscv,cpu_intc,%d", hart);
-+      data->hart = hart;
-+      data->chip.name = data->name;
-+      data->chip.irq_mask = riscv_irq_mask;
-+      data->chip.irq_unmask = riscv_irq_unmask;
-+      data->chip.irq_enable = riscv_irq_enable;
-+      data->chip.irq_disable = riscv_irq_disable;
-+      data->domain = irq_domain_add_linear(node, NR_RISCV_IRQS,
-+                      &riscv_irqdomain_ops, data);
-+      if (!data->domain)
-+              goto error_add_linear;
-+
-+      set_handle_irq(&riscv_intc_irq);
-+      pr_info("%s: %lu local interrupts mapped\n", data->name, NR_RISCV_IRQS);
-+      return 0;
-+
-+error_add_linear:
-+      pr_warn("%s: unable to add IRQ domain\n", data->name);
-+      return -ENXIO;
-+}
-+
-+IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0008-dt-bindings-interrupt-controller-RISC-V-local-interr.patch b/target/linux/riscv64/patches/0008-dt-bindings-interrupt-controller-RISC-V-local-interr.patch
deleted file mode 100644 (file)
index 34379e3..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-From 1da2fd31207d1687f5edc6ba8f0402bbecc423f2 Mon Sep 17 00:00:00 2001
-From: Palmer Dabbelt <palmer@dabbelt.com>
-Date: Mon, 26 Jun 2017 22:07:50 -0700
-Subject: [PATCH 08/11] dt-bindings: interrupt-controller: RISC-V local
- interrupt controller docs
-
-This patch adds documentation on the RISC-V local interrupt controller,
-which is a per-hart interrupt controller that manages all interrupts
-entering a RISC-V hart.  This interrupt controller is present on all
-RISC-V systems.
-
-Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
----
- .../interrupt-controller/riscv,cpu-intc.txt        | 41 ++++++++++++++++++++++
- 1 file changed, 41 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt
-
-diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt
-new file mode 100644
-index 0000000..61900e2
---- /dev/null
-+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt
-@@ -0,0 +1,41 @@
-+RISC-V Hart-Level Interrupt Controller (HLIC)
-+---------------------------------------------
-+
-+RISC-V cores include Control Status Registers (CSRs) which are local to each
-+hart and can be read or written by software. Some of these CSRs are used to
-+control local interrupts connected to the core.  Every interrupt is ultimately
-+routed through a hart's HLIC before it interrupts that hart.
-+
-+The RISC-V supervisor ISA manual specifies three interrupt sources that are
-+attached to every HLIC: software interrupts, the timer interrupt, and external
-+interrupts.  Software interrupts are used to send IPIs between cores.  The
-+timer interrupt comes from an architecturally mandated real-time timer that is
-+controller via SBI calls and CSR reads.  External interrupts connect all other
-+device interrupts to the HLIC, which are routed via the platform-level
-+interrupt controller (PLIC).
-+
-+All RISC-V systems that conform to the supervisor ISA specification are
-+required to have a HLIC with these three interrupt sources present.  Since the
-+interrupt map is defined by the ISA it's not listed in the HLIC's device tree
-+entry, though external interrupt controllers (like the PLIC, for example) will
-+need to define how their interrupts map to the relevant HLICs.
-+
-+Required properties:
-+- compatible : "riscv,cpu-intc"
-+- #interrupt-cells : should be <1>
-+- interrupt-controller : Identifies the node as an interrupt controller
-+
-+Furthermore, this interrupt-controller MUST be embedded inside the cpu
-+definition of the hart whose CSRs control these local interrupts.
-+
-+An example device tree entry for a HLIC is show below.
-+
-+      cpu1: cpu@1 {
-+              compatible = "riscv";
-+              ...
-+              cpu1-intc: interrupt-controller {
-+                      #interrupt-cells = <1>;
-+                      compatible = "riscv,cpu-intc";
-+                      interrupt-controller;
-+              };
-+      };
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0009-irqchip-New-RISC-V-PLIC-Driver.patch b/target/linux/riscv64/patches/0009-irqchip-New-RISC-V-PLIC-Driver.patch
deleted file mode 100644 (file)
index 478f987..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-From 8e3e7dfba04d314cfbade03237a3ec16f436b779 Mon Sep 17 00:00:00 2001
-From: Palmer Dabbelt <palmer@dabbelt.com>
-Date: Tue, 19 Jun 2018 18:10:08 +0200
-Subject: [PATCH 09/11] irqchip: New RISC-V PLIC Driver
-
-This patch adds a driver for the Platform Level Interrupt Controller
-(PLIC) specified as part of the RISC-V supervisor level ISA manual.
-The PLIC connects global interrupt sources to the local interrupt
-controller on each hart.
-
-Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
-[hch: various cleanups, fixed typos, added SPDX tag]
-Signed-off-by: Christoph Hellwig <hch@lst.de>
----
- drivers/irqchip/Kconfig          |  13 ++
- drivers/irqchip/Makefile         |   1 +
- drivers/irqchip/irq-riscv-plic.c | 295 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 309 insertions(+)
- create mode 100644 drivers/irqchip/irq-riscv-plic.c
-
-diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
-index 8460fdce..d1afac8 100644
---- a/drivers/irqchip/Kconfig
-+++ b/drivers/irqchip/Kconfig
-@@ -376,3 +376,16 @@ endmenu
- config RISCV_INTC
-       def_bool y
-       depends on RISCV
-+
-+config RISCV_PLIC
-+      bool "Platform-Level Interrupt Controller"
-+      depends on RISCV
-+      default y
-+      help
-+         This enables support for the PLIC chip found in standard RISC-V
-+         systems.  The PLIC controls devices interrupts and connects them to
-+         each core's local interrupt controller.  Aside from timer and
-+         software interrupts, all other interrupt sources (MSI, GPIO, etc)
-+         are subordinate to the PLIC.
-+
-+         If you don't know what to do here, say Y.
-diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
-index 74e333c..7954f4c 100644
---- a/drivers/irqchip/Makefile
-+++ b/drivers/irqchip/Makefile
-@@ -88,3 +88,4 @@ obj-$(CONFIG_GOLDFISH_PIC)           += irq-goldfish-pic.o
- obj-$(CONFIG_NDS32)                   += irq-ativic32.o
- obj-$(CONFIG_QCOM_PDC)                        += qcom-pdc.o
- obj-$(CONFIG_RISCV_INTC)              += irq-riscv-intc.o
-+obj-$(CONFIG_RISCV_PLIC)              += irq-riscv-plic.o
-diff --git a/drivers/irqchip/irq-riscv-plic.c b/drivers/irqchip/irq-riscv-plic.c
-new file mode 100644
-index 0000000..7b80b73
---- /dev/null
-+++ b/drivers/irqchip/irq-riscv-plic.c
-@@ -0,0 +1,295 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2017 SiFive
-+ */
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/irq.h>
-+#include <linux/irqchip.h>
-+#include <linux/irqchip/chained_irq.h>
-+#include <linux/irqdomain.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/platform_device.h>
-+#include <linux/spinlock.h>
-+
-+/*
-+ * From the RISC-V Priviledged Spec v1.10:
-+ *
-+ * Global interrupt sources are assigned small unsigned integer identifiers,
-+ * beginning at the value 1.  An interrupt ID of 0 is reserved to mean "no
-+ * interrupt".  Interrupt identifiers are also used to break ties when two or
-+ * more interrupt sources have the same assigned priority. Smaller values of
-+ * interrupt ID take precedence over larger values of interrupt ID.
-+ *
-+ * While the RISC-V supervisor spec doesn't define the maximum number of
-+ * devices supported by the PLIC, the largest number supported by devices
-+ * marked as 'riscv,plic0' (which is the only device type this driver supports,
-+ * and is the only extant PLIC as of now) is 1024.  As mentioned above, device
-+ * 0 is defined to be non-existent so this device really only supports 1023
-+ * devices.
-+ */
-+#define MAX_DEVICES   1024
-+#define MAX_CONTEXTS  15872
-+
-+struct plic_handler {
-+      bool                    present;
-+      int                     contextid;
-+      struct plic_data        *data;
-+};
-+
-+/*
-+ * PLIC devices are named like 'riscv,plic0,%llx', this is enough space to
-+ * store that name.
-+ */
-+#define PLIC_DATA_NAME_SIZE 30
-+
-+struct plic_data {
-+      struct irq_chip         chip;
-+      struct irq_domain       *domain;
-+      u32                     ndev;
-+      void __iomem            *reg;
-+      int                     handlers;
-+      struct plic_handler     *handler;
-+      char                    name[PLIC_DATA_NAME_SIZE];
-+      spinlock_t              lock;
-+};
-+
-+/*
-+ * Each interrupt source has a priority register associated with it.
-+ * We always hardwire it to one in Linux.
-+ */
-+static inline u32 __iomem *plic_priority(struct plic_data *data, int hwirq)
-+{
-+      return data->reg + hwirq * 0x04;
-+}
-+
-+/*
-+ * Each hart context has a vector of interrupt enable bits associated with it.
-+ * There is one bit for each interrupt source.
-+ */
-+static inline u32 __iomem *plic_enable_vector(struct plic_data *data,
-+              int contextid)
-+{
-+      return data->reg + (1 << 13) + contextid * 0x80;
-+}
-+
-+/*
-+ * Each hart context has a set of control registers associated with it.  Right
-+ * now there's only two: a source priority threshold over which the hart will
-+ * take an interrupt, and a register to claim interrupts.
-+ */
-+#define CONTEXT_THRESHOLD     0
-+#define CONTEXT_CLAIM         4
-+
-+static inline u32 __iomem *plic_hart_data(struct plic_data *data,
-+              int contextid)
-+{
-+      return data->reg + (1 << 21) + contextid * 0x1000;
-+}
-+
-+/* Explicit interrupt masking. */
-+static void plic_disable(struct plic_data *data, int contextid, int hwirq)
-+{
-+      u32 __iomem *reg = plic_enable_vector(data, contextid) + (hwirq / 32);
-+      u32 mask = ~(1 << (hwirq % 32));
-+
-+      spin_lock(&data->lock);
-+      writel(readl(reg) & mask, reg);
-+      spin_unlock(&data->lock);
-+}
-+
-+static void plic_enable(struct plic_data *data, int contextid, int hwirq)
-+{
-+      u32 __iomem *reg = plic_enable_vector(data, contextid) + (hwirq / 32);
-+      u32 bit = 1 << (hwirq % 32);
-+
-+      spin_lock(&data->lock);
-+      writel(readl(reg) | bit, reg);
-+      spin_unlock(&data->lock);
-+}
-+
-+/*
-+ * There is no need to mask/unmask PLIC interrupts
-+ * They are "masked" by reading claim and "unmasked" when writing it back.
-+ */
-+static void plic_irq_mask(struct irq_data *d)
-+{
-+}
-+
-+static void plic_irq_unmask(struct irq_data *d)
-+{
-+}
-+
-+static void plic_irq_enable(struct irq_data *d)
-+{
-+      struct plic_data *data = irq_data_get_irq_chip_data(d);
-+      int i;
-+
-+      writel(1, plic_priority(data, d->hwirq));
-+      for (i = 0; i < data->handlers; ++i)
-+              if (data->handler[i].present)
-+                      plic_enable(data, i, d->hwirq);
-+}
-+
-+static void plic_irq_disable(struct irq_data *d)
-+{
-+      struct plic_data *data = irq_data_get_irq_chip_data(d);
-+      int i;
-+
-+      writel(0, plic_priority(data, d->hwirq));
-+      for (i = 0; i < data->handlers; ++i)
-+              if (data->handler[i].present)
-+                      plic_disable(data, i, d->hwirq);
-+}
-+
-+static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
-+                            irq_hw_number_t hwirq)
-+{
-+      struct plic_data *data = d->host_data;
-+
-+      irq_set_chip_and_handler(irq, &data->chip, handle_simple_irq);
-+      irq_set_chip_data(irq, data);
-+      irq_set_noprobe(irq);
-+      return 0;
-+}
-+
-+static const struct irq_domain_ops plic_irqdomain_ops = {
-+      .map    = plic_irqdomain_map,
-+      .xlate  = irq_domain_xlate_onecell,
-+};
-+
-+/*
-+ * Handling an interrupt is a two-step process: first you claim the interrupt
-+ * by reading the claim register, then you complete the interrupt by writing
-+ * that source ID back to the same claim register.  This automatically enables
-+ * and disables the interrupt, so there's nothing else to do.
-+ */
-+static void plic_chained_handle_irq(struct irq_desc *desc)
-+{
-+      struct plic_handler *handler = irq_desc_get_handler_data(desc);
-+      struct irq_chip *chip = irq_desc_get_chip(desc);
-+      struct irq_domain *domain = handler->data->domain;
-+      void __iomem *ph = plic_hart_data(handler->data, handler->contextid);
-+      u32 what;
-+
-+      chained_irq_enter(chip, desc);
-+      while ((what = readl(ph + CONTEXT_CLAIM))) {
-+              int irq = irq_find_mapping(domain, what);
-+
-+              if (irq > 0)
-+                      generic_handle_irq(irq);
-+              else
-+                      handle_bad_irq(desc);
-+              writel(what, ph + CONTEXT_CLAIM);
-+      }
-+      chained_irq_exit(chip, desc);
-+}
-+
-+static int plic_init(struct device_node *node, struct device_node *parent)
-+{
-+      struct plic_data *data;
-+      struct resource resource;
-+      int i, ok = 0;
-+      int out = -1;
-+
-+      data = kzalloc(sizeof(*data), GFP_KERNEL);
-+      if (WARN_ON(!data))
-+              return -ENOMEM;
-+
-+      spin_lock_init(&data->lock);
-+
-+      data->reg = of_iomap(node, 0);
-+      if (WARN_ON(!data->reg)) {
-+              out = -EIO;
-+              goto free_data;
-+      }
-+
-+      of_property_read_u32(node, "riscv,ndev", &data->ndev);
-+      if (WARN_ON(!data->ndev)) {
-+              out = -EINVAL;
-+              goto free_reg;
-+      }
-+
-+      data->handlers = of_irq_count(node);
-+      if (WARN_ON(!data->handlers)) {
-+              out = -EINVAL;
-+              goto free_reg;
-+      }
-+
-+      data->handler =
-+              kcalloc(data->handlers, sizeof(*data->handler), GFP_KERNEL);
-+      if (WARN_ON(!data->handler)) {
-+              out = -ENOMEM;
-+              goto free_reg;
-+      }
-+
-+      data->domain = irq_domain_add_linear(node, data->ndev + 1,
-+                      &plic_irqdomain_ops, data);
-+      if (WARN_ON(!data->domain)) {
-+              out = -ENOMEM;
-+              goto free_handler;
-+      }
-+
-+      of_address_to_resource(node, 0, &resource);
-+      snprintf(data->name, sizeof(data->name),
-+               "riscv,plic0,%llx", resource.start);
-+      data->chip.name = data->name;
-+      data->chip.irq_mask = plic_irq_mask;
-+      data->chip.irq_unmask = plic_irq_unmask;
-+      data->chip.irq_enable = plic_irq_enable;
-+      data->chip.irq_disable = plic_irq_disable;
-+
-+      for (i = 0; i < data->handlers; ++i) {
-+              struct plic_handler *handler = &data->handler[i];
-+              struct of_phandle_args parent;
-+              int parent_irq, hwirq;
-+
-+              handler->present = false;
-+
-+              if (of_irq_parse_one(node, i, &parent))
-+                      continue;
-+              /* skip context holes */
-+              if (parent.args[0] == -1)
-+                      continue;
-+
-+              /* skip any contexts that lead to inactive harts */
-+              if (of_device_is_compatible(parent.np, "riscv,cpu-intc") &&
-+                  parent.np->parent &&
-+                  riscv_of_processor_hart(parent.np->parent) < 0)
-+                      continue;
-+
-+              parent_irq = irq_create_of_mapping(&parent);
-+              if (!parent_irq)
-+                      continue;
-+
-+              handler->present = true;
-+              handler->contextid = i;
-+              handler->data = data;
-+              /* hwirq prio must be > this to trigger an interrupt */
-+              writel(0, plic_hart_data(data, i) + CONTEXT_THRESHOLD);
-+
-+              for (hwirq = 1; hwirq <= data->ndev; ++hwirq)
-+                      plic_disable(data, i, hwirq);
-+              irq_set_chained_handler_and_data(parent_irq,
-+                              plic_chained_handle_irq, handler);
-+              ++ok;
-+      }
-+
-+      pr_info("%s: mapped %d interrupts to %d/%d handlers\n",
-+              data->name, data->ndev, ok, data->handlers);
-+      WARN_ON(!ok);
-+      return 0;
-+
-+free_handler:
-+      kfree(data->handler);
-+free_reg:
-+      iounmap(data->reg);
-+free_data:
-+      kfree(data);
-+      return out;
-+}
-+
-+IRQCHIP_DECLARE(plic0, "riscv,plic0", plic_init);
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0010-dt-bindings-interrupt-controller-RISC-V-PLIC-documen.patch b/target/linux/riscv64/patches/0010-dt-bindings-interrupt-controller-RISC-V-PLIC-documen.patch
deleted file mode 100644 (file)
index 6a05e9d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-From 634a87822bc9939c99068e72612e3c5df40bff18 Mon Sep 17 00:00:00 2001
-From: Palmer Dabbelt <palmer@dabbelt.com>
-Date: Mon, 26 Jun 2017 22:09:07 -0700
-Subject: [PATCH 10/11] dt-bindings: interrupt-controller: RISC-V PLIC
- documentation
-
-This patch adds documentation for the platform-level interrupt
-controller (PLIC) found in all RISC-V systems.  This interrupt
-controller routes interrupts from all the devices in the system to each
-hart-local interrupt controller.
-
-Note: the DTS bindings for the PLIC aren't set in stone yet, as we might
-want to change how we're specifying holes in the hart list.
-
-Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
----
- .../bindings/interrupt-controller/riscv,plic0.txt  | 55 ++++++++++++++++++++++
- 1 file changed, 55 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,plic0.txt
-
-diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,plic0.txt b/Documentation/devicetree/bindings/interrupt-controller/riscv,plic0.txt
-new file mode 100644
-index 0000000..99cd359
---- /dev/null
-+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,plic0.txt
-@@ -0,0 +1,55 @@
-+RISC-V Platform-Level Interrupt Controller (PLIC)
-+-------------------------------------------------
-+
-+The RISC-V supervisor ISA specification allows for the presence of a
-+platform-level interrupt controller (PLIC).   The PLIC connects all external
-+interrupts in the system to all hart contexts in the system, via the external
-+interrupt source in each hart's hart-local interrupt controller (HLIC).  A hart
-+context is a privilege mode in a hardware execution thread.  For example, in
-+an 4 core system with 2-way SMT, you have 8 harts and probably at least two
-+privilege modes per hart; machine mode and supervisor mode.
-+
-+Each interrupt can be enabled on per-context basis. Any context can claim
-+a pending enabled interrupt and then release it once it has been handled.
-+
-+Each interrupt has a configurable priority. Higher priority interrupts are
-+serviced firs. Each context can specify a priority threshold. Interrupts
-+with priority below this threshold will not cause the PLIC to raise its
-+interrupt line leading to the context.
-+
-+While the PLIC supports both edge-triggered and level-triggered interrupts,
-+interrupt handlers are oblivious to this distinction and therefor it is not
-+specific in the PLIC device-tree binding.
-+
-+While the RISC-V ISA doesn't specify a memory layout for the PLIC, the
-+"riscv,plic0" device is a concrete implementation of the PLIC that contains a
-+specific memory layout.  More details about the memory layout of the
-+"riscv,plic0" device can be found as a comment in the device driver, or as part
-+of the SiFive U5 Coreplex Series Manual (page 22 of the PDF of version 1.0)
-+<https://www.sifive.com/documentation/coreplex/u5-coreplex-series-manual/>
-+
-+Required properties:
-+- compatible : "riscv,plic0"
-+- #address-cells : should be <0>
-+- #interrupt-cells : should be <1>
-+- interrupt-controller : Identifies the node as an interrupt controller
-+- reg : Should contain 1 register range (address and length)
-+- interrupts-extended : Specifies which contexts are connected to the PLIC,
-+  with "-1" specifying that a context is not present.
-+
-+Example:
-+
-+      plic: interrupt-controller@c000000 {
-+              #address-cells = <0>;
-+              #interrupt-cells = <1>;
-+              compatible = "riscv,plic0";
-+              interrupt-controller;
-+              interrupts-extended = <
-+                      &cpu0-intc 11
-+                      &cpu1-intc 11 &cpu1-intc 9
-+                      &cpu2-intc 11 &cpu2-intc 9
-+                      &cpu3-intc 11 &cpu3-intc 9
-+                      &cpu4-intc 11 &cpu4-intc 9>;
-+              reg = <0xc000000 0x4000000>;
-+              riscv,ndev = <10>;
-+      };
--- 
-2.1.4
-
diff --git a/target/linux/riscv64/patches/0011-clocksource-new-RISC-V-SBI-timer-driver.patch b/target/linux/riscv64/patches/0011-clocksource-new-RISC-V-SBI-timer-driver.patch
deleted file mode 100644 (file)
index bcc89d4..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-From 406087706427cdd610ce2dc3fbffa655064944d3 Mon Sep 17 00:00:00 2001
-From: Palmer Dabbelt <palmer@dabbelt.com>
-Date: Tue, 19 Jun 2018 17:36:28 +0200
-Subject: [PATCH 11/11] clocksource: new RISC-V SBI timer driver
-
-The RISC-V ISA defines a per-hart real-time clock and timer, which is
-present on all systems.  The clock is accessed via the 'rdtime'
-pseudo-instruction (which reads a CSR), and the timer is set via an SBI
-call.
-
-Signed-off-by: Dmitriy Cherkasov <dmitriy@oss-tech.org>
-Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
-[hch: remove dead code, add SPDX tags, minor cleanups]
-Signed-off-by: Christoph Hellwig <hch@lst.de>
----
- arch/riscv/include/asm/timer.h    |  7 +++
- arch/riscv/kernel/time.c          |  9 +---
- drivers/clocksource/Kconfig       | 10 ++++
- drivers/clocksource/Makefile      |  1 +
- drivers/clocksource/riscv_timer.c | 97 +++++++++++++++++++++++++++++++++++++++
- 5 files changed, 116 insertions(+), 8 deletions(-)
- create mode 100644 arch/riscv/include/asm/timer.h
- create mode 100644 drivers/clocksource/riscv_timer.c
-
-diff --git a/arch/riscv/include/asm/timer.h b/arch/riscv/include/asm/timer.h
-new file mode 100644
-index 0000000..ae20dd9
---- /dev/null
-+++ b/arch/riscv/include/asm/timer.h
-@@ -0,0 +1,7 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef _ASM_RISCV_TIMER_H
-+#define _ASM_RISCV_TIMER_H
-+
-+DECLARE_PER_CPU(struct clock_event_device, riscv_clock_event);
-+
-+#endif /* _ASM_RISCV_TIMER_H */
-diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c
-index 2463fcc..bba28fc 100644
---- a/arch/riscv/kernel/time.c
-+++ b/arch/riscv/kernel/time.c
-@@ -16,19 +16,13 @@
- #include <linux/clockchips.h>
- #include <linux/delay.h>
--#ifdef CONFIG_RISCV_TIMER
--#include <linux/timer_riscv.h>
--#endif
--
- #include <asm/sbi.h>
-+#include <asm/timer.h>
- unsigned long riscv_timebase;
--DECLARE_PER_CPU(struct clock_event_device, riscv_clock_event);
--
- void riscv_timer_interrupt(void)
- {
--#ifdef CONFIG_RISCV_TIMER
-       /*
-        * FIXME: This needs to be cleaned up along with the rest of the IRQ
-        * handling cleanup.  See irq.c for more details.
-@@ -36,7 +30,6 @@ void riscv_timer_interrupt(void)
-       struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event);
-       evdev->event_handler(evdev);
--#endif
- }
- void __init init_clockevent(void)
-diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
-index dec0dd8..a57083e 100644
---- a/drivers/clocksource/Kconfig
-+++ b/drivers/clocksource/Kconfig
-@@ -609,4 +609,14 @@ config ATCPIT100_TIMER
-       help
-         This option enables support for the Andestech ATCPIT100 timers.
-+config RISCV_TIMER
-+      bool "Timer for the RISC-V platform"
-+      depends on RISCV || COMPILE_TEST
-+      select TIMER_PROBE
-+      select TIMER_OF
-+      help
-+        This enables the per-hart timer built into all RISC-V systems, which
-+        is accessed via both the SBI and the rdcycle instruction.  This is
-+        required for all RISC-V systems.
-+
- endmenu
-diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
-index 00caf37..ded31f7 100644
---- a/drivers/clocksource/Makefile
-+++ b/drivers/clocksource/Makefile
-@@ -78,3 +78,4 @@ obj-$(CONFIG_H8300_TPU)                      += h8300_tpu.o
- obj-$(CONFIG_CLKSRC_ST_LPC)           += clksrc_st_lpc.o
- obj-$(CONFIG_X86_NUMACHIP)            += numachip.o
- obj-$(CONFIG_ATCPIT100_TIMER)         += timer-atcpit100.o
-+obj-$(CONFIG_RISCV_TIMER)             += riscv_timer.o
-diff --git a/drivers/clocksource/riscv_timer.c b/drivers/clocksource/riscv_timer.c
-new file mode 100644
-index 0000000..48196b2
---- /dev/null
-+++ b/drivers/clocksource/riscv_timer.c
-@@ -0,0 +1,97 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2012 Regents of the University of California
-+ * Copyright (C) 2017 SiFive
-+ */
-+#include <linux/clocksource.h>
-+#include <linux/clockchips.h>
-+#include <linux/delay.h>
-+#include <asm/sbi.h>
-+#include <asm/timer.h>
-+
-+#define MINDELTA 100
-+#define MAXDELTA 0x7fffffff
-+
-+/*
-+ * All RISC-V systems have a timer attached to every hart.  These timers can be
-+ * read by the 'rdcycle' pseudo instruction, and can use the SBI to setup
-+ * events.  In order to abstract the architecture-specific timer reading and
-+ * setting functions away from the clock event insertion code, we provide
-+ * function pointers to the clockevent subsystem that perform two basic
-+ * operations: rdtime() reads the timer on the current CPU, and
-+ * next_event(delta) sets the next timer event to 'delta' cycles in the future.
-+ * As the timers are inherently a per-cpu resource, these callbacks perform
-+ * operations on the current hart.  There is guaranteed to be exactly one timer
-+ * per hart on all RISC-V systems.
-+ */
-+//DECLARE_PER_CPU(struct clocksource, riscv_clocksource);
-+
-+static int next_event(unsigned long delta, struct clock_event_device *ce)
-+{
-+      /*
-+       * time_init() allocates a timer for each CPU.  Since we're writing the
-+       * timer comparison register here we can't allow the timers to cross
-+       * harts.
-+       */
-+      BUG_ON(ce != this_cpu_ptr(&riscv_clock_event));
-+      sbi_set_timer(get_cycles64() + delta);
-+      return 0;
-+}
-+
-+DEFINE_PER_CPU(struct clock_event_device, riscv_clock_event) = {
-+      .name                   = "riscv_timer_clockevent",
-+      .features               = CLOCK_EVT_FEAT_ONESHOT,
-+      .rating                 = 100,
-+      .set_next_event         = next_event,
-+};
-+
-+/*
-+ * It is guarnteed that all the timers across all the harts are synchronized
-+ * within one tick of each other, so while this could technically go
-+ * backwards when hopping between CPUs, practically it won't happen.
-+ */
-+static unsigned long long rdtime(struct clocksource *cs)
-+{
-+      return get_cycles64();
-+}
-+
-+DEFINE_PER_CPU(struct clocksource, riscv_clocksource) = {
-+      .name           = "riscv_clocksource",
-+      .rating         = 300,
-+      .mask           = CLOCKSOURCE_MASK(BITS_PER_LONG),
-+      .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-+      .read           = rdtime,
-+};
-+
-+static int hart_of_timer(struct device_node *dev)
-+{
-+      u32 hart;
-+
-+      if (!dev)
-+              return -1;
-+      if (!of_device_is_compatible(dev, "riscv"))
-+              return -1;
-+      if (of_property_read_u32(dev, "reg", &hart))
-+              return -1;
-+
-+      return hart;
-+}
-+
-+static int timer_riscv_init_dt(struct device_node *n)
-+{
-+      int cpu_id = hart_of_timer(n);
-+      struct clock_event_device *ce = per_cpu_ptr(&riscv_clock_event, cpu_id);
-+      struct clocksource *cs = per_cpu_ptr(&riscv_clocksource, cpu_id);
-+
-+      if (cpu_id == smp_processor_id()) {
-+              clocksource_register_hz(cs, riscv_timebase);
-+
-+              ce->cpumask = cpumask_of(cpu_id);
-+              clockevents_config_and_register(ce, riscv_timebase,
-+                              MINDELTA, MAXDELTA);
-+      }
-+
-+      return 0;
-+}
-+
-+TIMER_OF_DECLARE(riscv_timer, "riscv", timer_riscv_init_dt);
--- 
-2.1.4
-