* [PATCH V8 0/6] C-SKY(csky) Linux Kernel Port
@ 2018-09-20 5:39 Guo Ren
2018-09-20 5:39 ` [PATCH V8 1/6] csky/dma: bugfix dma_sync_for_cpu/device Guo Ren
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Guo Ren @ 2018-09-20 5:39 UTC (permalink / raw)
To: tglx, jason, marc.zyngier, robh+dt, mark.rutland, arnd, robh, sfr
Cc: linux-kernel, devicetree, linux-arch, c-sky_gcc_upstream,
gnu-csky, green.hu, Guo Ren
Because I've sent to Stephen Roth with the linux-4.19-rc3 git-tree for
linux-next, I shouldn't rebase any more.
https://github.com/c-sky/csky-linux.git#linux-next
This patchset include mptimer and mpintc drivers and fixup:
- Fixup smp IPI's problems found by Marc Zyngier
- Add irq-csky-mpintc.c patch in this patchset
- Add mptimer.c patch in this patchset
- Fixup dma_sync_for_cpu/device in dma-mapping.c
Guo Ren (6):
csky/dma: bugfix dma_sync_for_cpu/device
csky: remove irq_mapping from smp.c
irqchip: add C-SKY SMP interrupt controller
dt-bindings: interrupt-controller: C-SKY SMP intc
clocksource: add C-SKY SMP timer
dt-bindings: timer: C-SKY Multi-processor timer
.../bindings/interrupt-controller/csky,mpintc.txt | 40 +++++
.../devicetree/bindings/timer/csky,mptimer.txt | 46 +++++
arch/csky/include/asm/smp.h | 4 +-
arch/csky/kernel/smp.c | 27 ++-
arch/csky/mm/dma-mapping.c | 5 +-
drivers/clocksource/Kconfig | 8 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/csky_mptimer.c | 178 +++++++++++++++++++
drivers/irqchip/Kconfig | 8 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-csky-mpintc.c | 195 +++++++++++++++++++++
include/linux/cpuhotplug.h | 1 +
12 files changed, 503 insertions(+), 11 deletions(-)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt
create mode 100644 Documentation/devicetree/bindings/timer/csky,mptimer.txt
create mode 100644 drivers/clocksource/csky_mptimer.c
create mode 100644 drivers/irqchip/irq-csky-mpintc.c
--
2.7.4
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH V8 1/6] csky/dma: bugfix dma_sync_for_cpu/device
2018-09-20 5:39 [PATCH V8 0/6] C-SKY(csky) Linux Kernel Port Guo Ren
@ 2018-09-20 5:39 ` Guo Ren
2018-09-20 5:39 ` [PATCH V8 2/6] csky: remove irq_mapping from smp.c Guo Ren
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Guo Ren @ 2018-09-20 5:39 UTC (permalink / raw)
To: tglx, jason, marc.zyngier, robh+dt, mark.rutland, arnd, robh, sfr
Cc: linux-kernel, devicetree, linux-arch, c-sky_gcc_upstream,
gnu-csky, green.hu, Guo Ren
ref: https://lkml.org/lkml/2018/5/18/1068
map for_cpu for_device unmap
TO_DEV writeback none writeback none
TO_CPU invalidate invalidate* invalidate invalidate*
BIDIR writeback invalidate writeback invalidate
Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
arch/csky/mm/dma-mapping.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/csky/mm/dma-mapping.c b/arch/csky/mm/dma-mapping.c
index 16c2087..30a2041 100644
--- a/arch/csky/mm/dma-mapping.c
+++ b/arch/csky/mm/dma-mapping.c
@@ -217,7 +217,8 @@ void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
break;
case DMA_FROM_DEVICE:
case DMA_BIDIRECTIONAL:
- BUG();
+ dma_wbinv_range(vaddr + offset, vaddr + offset + size);
+ break;
default:
BUG();
}
@@ -240,7 +241,7 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
switch (dir) {
case DMA_TO_DEVICE:
- BUG();
+ break;
case DMA_FROM_DEVICE:
case DMA_BIDIRECTIONAL:
dma_wbinv_range(vaddr + offset, vaddr + offset + size);
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V8 2/6] csky: remove irq_mapping from smp.c
2018-09-20 5:39 [PATCH V8 0/6] C-SKY(csky) Linux Kernel Port Guo Ren
2018-09-20 5:39 ` [PATCH V8 1/6] csky/dma: bugfix dma_sync_for_cpu/device Guo Ren
@ 2018-09-20 5:39 ` Guo Ren
2018-09-20 5:39 ` [PATCH V8 3/6] irqchip: add C-SKY SMP interrupt controller Guo Ren
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Guo Ren @ 2018-09-20 5:39 UTC (permalink / raw)
To: tglx, jason, marc.zyngier, robh+dt, mark.rutland, arnd, robh, sfr
Cc: linux-kernel, devicetree, linux-arch, c-sky_gcc_upstream,
gnu-csky, green.hu, Guo Ren
- Add irq_mapping return check
- Move IPI_IRQ into irq-driver
- remove irq_mapping from smp.c to irq-driver
- Add set_ipi_irq_mapping api to irq-driver
- update asm/smp.h
Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
arch/csky/include/asm/smp.h | 4 +++-
arch/csky/kernel/smp.c | 27 +++++++++++++++++++--------
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/arch/csky/include/asm/smp.h b/arch/csky/include/asm/smp.h
index 9a53abf..f3e4f24 100644
--- a/arch/csky/include/asm/smp.h
+++ b/arch/csky/include/asm/smp.h
@@ -17,7 +17,9 @@ void arch_send_call_function_ipi_mask(struct cpumask *mask);
void arch_send_call_function_single_ipi(int cpu);
-void __init set_send_ipi(void (*func)(const unsigned long *, unsigned long));
+void __init set_send_ipi(void (*func)(const unsigned long *));
+
+void __init set_ipi_irq_mapping(int (*func)(void));
#define raw_smp_processor_id() (current_thread_info()->cpu)
diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c
index 522c73f..14877e2 100644
--- a/arch/csky/kernel/smp.c
+++ b/arch/csky/kernel/smp.c
@@ -20,8 +20,6 @@
#include <asm/mmu_context.h>
#include <asm/pgalloc.h>
-#define IPI_IRQ 15
-
static struct {
unsigned long bits ____cacheline_aligned;
} ipi_data[NR_CPUS] __cacheline_aligned;
@@ -56,9 +54,9 @@ static irqreturn_t handle_ipi(int irq, void *dev)
return IRQ_HANDLED;
}
-static void (*send_arch_ipi)(const unsigned long *mask, unsigned long irq) = NULL;
+static void (*send_arch_ipi)(const unsigned long *mask) = NULL;
-void __init set_send_ipi(void (*func)(const unsigned long *, unsigned long))
+void __init set_send_ipi(void (*func)(const unsigned long *))
{
if (send_arch_ipi)
return;
@@ -75,7 +73,7 @@ send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)
set_bit(operation, &ipi_data[i].bits);
smp_mb();
- send_arch_ipi(cpumask_bits(to_whom), IPI_IRQ);
+ send_arch_ipi(cpumask_bits(to_whom));
}
void arch_send_call_function_ipi_mask(struct cpumask *mask)
@@ -115,19 +113,32 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
}
static int ipi_dummy_dev;
+static int ipi_irq;
void __init enable_smp_ipi(void)
{
- enable_percpu_irq(IPI_IRQ, 0);
+ enable_percpu_irq(ipi_irq, 0);
+}
+
+static int (*arch_ipi_irq_mapping)(void) = NULL;
+
+void __init set_ipi_irq_mapping(int (*func)(void))
+{
+ if (arch_ipi_irq_mapping)
+ return;
+
+ arch_ipi_irq_mapping = func;
}
void __init setup_smp_ipi(void)
{
int rc;
- irq_create_mapping(NULL, IPI_IRQ);
+ ipi_irq = arch_ipi_irq_mapping();
+ if (ipi_irq == 0)
+ panic("%s IRQ mapping failed\n", __func__);
- rc = request_percpu_irq(IPI_IRQ, handle_ipi, "IPI Interrupt", &ipi_dummy_dev);
+ rc = request_percpu_irq(ipi_irq, handle_ipi, "IPI Interrupt", &ipi_dummy_dev);
if (rc)
panic("%s IRQ request failed\n", __func__);
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V8 3/6] irqchip: add C-SKY SMP interrupt controller
2018-09-20 5:39 [PATCH V8 0/6] C-SKY(csky) Linux Kernel Port Guo Ren
2018-09-20 5:39 ` [PATCH V8 1/6] csky/dma: bugfix dma_sync_for_cpu/device Guo Ren
2018-09-20 5:39 ` [PATCH V8 2/6] csky: remove irq_mapping from smp.c Guo Ren
@ 2018-09-20 5:39 ` Guo Ren
2018-09-20 5:39 ` [PATCH V8 4/6] dt-bindings: interrupt-controller: C-SKY SMP intc Guo Ren
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Guo Ren @ 2018-09-20 5:39 UTC (permalink / raw)
To: tglx, jason, marc.zyngier, robh+dt, mark.rutland, arnd, robh, sfr
Cc: linux-kernel, devicetree, linux-arch, c-sky_gcc_upstream,
gnu-csky, green.hu, Guo Ren
- Irq-csky-mpintc is C-SKY smp system interrupt controller and it
could support 16 soft irqs, 16 private irqs, and 992 max common
irqs.
Changelog:
- Move IPI_IRQ into the driver
- Remove irq_set_default_host() and use set_ipi_irq_mapping()
- Change name with upstream feed-back
- Change irq map, reserve soft_irq & private_irq space
- Add License and Copyright
- Support set_affinity for irq balance in SMP
Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
drivers/irqchip/Kconfig | 8 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-csky-mpintc.c | 195 ++++++++++++++++++++++++++++++++++++++
3 files changed, 204 insertions(+)
create mode 100644 drivers/irqchip/irq-csky-mpintc.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 383e7b7..92e1c20 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -371,6 +371,14 @@ config QCOM_PDC
Power Domain Controller driver to manage and configure wakeup
IRQs for Qualcomm Technologies Inc (QTI) mobile chips.
+config CSKY_MPINTC
+ bool "C-SKY Multi Processor Interrupt Controller"
+ depends on CSKY
+ help
+ Say yes here to enable C-SKY SMP interrupt controller driver used
+ for C-SKY SMP system. In fact it's not mmio map and it use ld/st
+ to visit the controller's register inside CPU.
+
endmenu
config SIFIVE_PLIC
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index fbd1ec8..6b739ea 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -87,4 +87,5 @@ 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_CSKY_MPINTC) += irq-csky-mpintc.o
obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
diff --git a/drivers/irqchip/irq-csky-mpintc.c b/drivers/irqchip/irq-csky-mpintc.c
new file mode 100644
index 0000000..2b424d27
--- /dev/null
+++ b/drivers/irqchip/irq-csky-mpintc.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/traps.h>
+#include <asm/reg_ops.h>
+#include <asm/smp.h>
+
+static struct irq_domain *root_domain;
+static void __iomem *INTCG_base;
+static void __iomem *INTCL_base;
+
+#define IPI_IRQ 15
+#define INTC_IRQS 256
+#define COMM_IRQ_BASE 32
+
+#define INTCG_SIZE 0x8000
+#define INTCL_SIZE 0x1000
+#define INTC_SIZE INTCL_SIZE*nr_cpu_ids + INTCG_SIZE
+
+#define INTCG_ICTLR 0x0
+#define INTCG_CICFGR 0x100
+#define INTCG_CIDSTR 0x1000
+
+#define INTCL_PICTLR 0x0
+#define INTCL_SIGR 0x60
+#define INTCL_HPPIR 0x68
+#define INTCL_RDYIR 0x6c
+#define INTCL_SENR 0xa0
+#define INTCL_CENR 0xa4
+#define INTCL_CACR 0xb4
+
+static DEFINE_PER_CPU(void __iomem *, intcl_reg);
+
+static void csky_mpintc_handler(struct pt_regs *regs)
+{
+ void __iomem *reg_base = this_cpu_read(intcl_reg);
+
+ do {
+ handle_domain_irq(root_domain,
+ readl_relaxed(reg_base + INTCL_RDYIR),
+ regs);
+ } while (readl_relaxed(reg_base + INTCL_HPPIR) & BIT(31));
+}
+
+static void csky_mpintc_enable(struct irq_data *d)
+{
+ void __iomem *reg_base = this_cpu_read(intcl_reg);
+
+ writel_relaxed(d->hwirq, reg_base + INTCL_SENR);
+}
+
+static void csky_mpintc_disable(struct irq_data *d)
+{
+ void __iomem *reg_base = this_cpu_read(intcl_reg);
+
+ writel_relaxed(d->hwirq, reg_base + INTCL_CENR);
+}
+
+static void csky_mpintc_eoi(struct irq_data *d)
+{
+ void __iomem *reg_base = this_cpu_read(intcl_reg);
+
+ writel_relaxed(d->hwirq, reg_base + INTCL_CACR);
+}
+
+#ifdef CONFIG_SMP
+static int csky_irq_set_affinity(struct irq_data *d,
+ const struct cpumask *mask_val,
+ bool force)
+{
+ unsigned int cpu;
+ unsigned int offset = 4 * (d->hwirq - COMM_IRQ_BASE);
+
+ if (!force)
+ cpu = cpumask_any_and(mask_val, cpu_online_mask);
+ else
+ cpu = cpumask_first(mask_val);
+
+ if (cpu >= nr_cpu_ids)
+ return -EINVAL;
+
+ /* Enable interrupt destination */
+ cpu |= BIT(31);
+
+ writel_relaxed(cpu, INTCG_base + INTCG_CIDSTR + offset);
+
+ irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
+ return IRQ_SET_MASK_OK_DONE;
+}
+#endif
+
+static struct irq_chip csky_irq_chip = {
+ .name = "C-SKY SMP Intc",
+ .irq_eoi = csky_mpintc_eoi,
+ .irq_enable = csky_mpintc_enable,
+ .irq_disable = csky_mpintc_disable,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = csky_irq_set_affinity,
+#endif
+};
+
+static int csky_irqdomain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ if(hwirq < COMM_IRQ_BASE) {
+ irq_set_percpu_devid(irq);
+ irq_set_chip_and_handler(irq, &csky_irq_chip, handle_percpu_irq);
+ } else {
+ irq_set_chip_and_handler(irq, &csky_irq_chip, handle_fasteoi_irq);
+ }
+
+ return 0;
+}
+
+static const struct irq_domain_ops csky_irqdomain_ops = {
+ .map = csky_irqdomain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+#ifdef CONFIG_SMP
+static void csky_mpintc_send_ipi(const unsigned long *mask)
+{
+ void __iomem *reg_base = this_cpu_read(intcl_reg);
+
+ /*
+ * INTCL_SIGR[3:0] INTID
+ * INTCL_SIGR[8:15] CPUMASK
+ */
+ writel_relaxed((*mask) << 8 | IPI_IRQ, reg_base + INTCL_SIGR);
+}
+
+static int csky_mpintc_ipi_irq_mapping(void)
+{
+ return irq_create_mapping(root_domain, IPI_IRQ);
+}
+#endif
+
+/* C-SKY multi processor interrupt controller */
+static int __init
+csky_mpintc_init(struct device_node *node, struct device_node *parent)
+{
+ unsigned int cpu, nr_irq;
+ int ret;
+
+ if (parent)
+ return 0;
+
+ ret = of_property_read_u32(node, "csky,num-irqs", &nr_irq);
+ if (ret < 0)
+ nr_irq = INTC_IRQS;
+
+ if (INTCG_base == NULL) {
+ INTCG_base = ioremap(mfcr("cr<31, 14>"), INTC_SIZE);
+ if (INTCG_base == NULL)
+ return -EIO;
+
+ INTCL_base = INTCG_base + INTCG_SIZE;
+
+ writel_relaxed(BIT(0), INTCG_base + INTCG_ICTLR);
+ }
+
+ root_domain = irq_domain_add_linear(node, nr_irq, &csky_irqdomain_ops,
+ NULL);
+ if (!root_domain)
+ return -ENXIO;
+
+ /* for every cpu */
+ for_each_present_cpu(cpu) {
+ per_cpu(intcl_reg, cpu) = INTCL_base + (INTCL_SIZE * cpu);
+ writel_relaxed(BIT(0), per_cpu(intcl_reg, cpu) + INTCL_PICTLR);
+ }
+
+ set_handle_irq(&csky_mpintc_handler);
+
+#ifdef CONFIG_SMP
+ set_send_ipi(&csky_mpintc_send_ipi);
+
+ set_ipi_irq_mapping(&csky_mpintc_ipi_irq_mapping);
+#endif
+
+ return 0;
+}
+IRQCHIP_DECLARE(csky_mpintc, "csky,mpintc", csky_mpintc_init);
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V8 4/6] dt-bindings: interrupt-controller: C-SKY SMP intc
2018-09-20 5:39 [PATCH V8 0/6] C-SKY(csky) Linux Kernel Port Guo Ren
` (2 preceding siblings ...)
2018-09-20 5:39 ` [PATCH V8 3/6] irqchip: add C-SKY SMP interrupt controller Guo Ren
@ 2018-09-20 5:39 ` Guo Ren
2018-09-20 5:39 ` [PATCH V8 5/6] clocksource: add C-SKY SMP timer Guo Ren
2018-09-20 5:39 ` [PATCH V8 6/6] dt-bindings: timer: C-SKY Multi-processor timer Guo Ren
5 siblings, 0 replies; 8+ messages in thread
From: Guo Ren @ 2018-09-20 5:39 UTC (permalink / raw)
To: tglx, jason, marc.zyngier, robh+dt, mark.rutland, arnd, robh, sfr
Cc: linux-kernel, devicetree, linux-arch, c-sky_gcc_upstream,
gnu-csky, green.hu, Guo Ren
- Dt-bindings doc about C-SKY Multi-processors interrupt controller.
Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
.../bindings/interrupt-controller/csky,mpintc.txt | 40 ++++++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt
diff --git a/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt b/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt
new file mode 100644
index 0000000..9cdad74
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt
@@ -0,0 +1,40 @@
+===========================================
+C-SKY Multi-processors Interrupt Controller
+===========================================
+
+C-SKY Multi-processors Interrupt Controller is designed for ck807/ck810/ck860
+SMP soc, and it also could be used in non-SMP system.
+
+Interrupt number definition:
+
+ 0-15 : software irq, and we use 15 as our IPI_IRQ.
+ 16-31 : private irq, and we use 16 as the co-processor timer.
+ 31-1024: common irq for soc ip.
+
+=============================
+intc node bindings definition
+=============================
+
+ Description: Describes SMP interrupt controller
+
+ PROPERTIES
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: must be "csky,mpintc"
+ - interrupt-cells
+ Usage: required
+ Value type: <u32>
+ Definition: must be <1>
+ - interrupt-controller:
+ Usage: required
+
+Examples:
+---------
+
+ intc: interrupt-controller {
+ compatible = "csky,mpintc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V8 5/6] clocksource: add C-SKY SMP timer
2018-09-20 5:39 [PATCH V8 0/6] C-SKY(csky) Linux Kernel Port Guo Ren
` (3 preceding siblings ...)
2018-09-20 5:39 ` [PATCH V8 4/6] dt-bindings: interrupt-controller: C-SKY SMP intc Guo Ren
@ 2018-09-20 5:39 ` Guo Ren
2018-09-20 5:54 ` Guo Ren
2018-09-20 5:39 ` [PATCH V8 6/6] dt-bindings: timer: C-SKY Multi-processor timer Guo Ren
5 siblings, 1 reply; 8+ messages in thread
From: Guo Ren @ 2018-09-20 5:39 UTC (permalink / raw)
To: tglx, jason, marc.zyngier, robh+dt, mark.rutland, arnd, robh, sfr
Cc: linux-kernel, devicetree, linux-arch, c-sky_gcc_upstream,
gnu-csky, green.hu, Guo Ren
This timer is used by SMP system and use mfcr/mtcr instruction
to access the regs.
Changelog:
- Add CPUHP_AP_CSKY_TIMER_STARTING in cpuhotplug.h
- Support csky mp timer alpha version.
- Just use low-counter with 32bit width as clocksource.
- Coding convention with upstream feed-back.
Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
drivers/clocksource/Kconfig | 8 ++
drivers/clocksource/Makefile | 1 +
drivers/clocksource/csky_mptimer.c | 178 +++++++++++++++++++++++++++++++++++++
include/linux/cpuhotplug.h | 1 +
4 files changed, 188 insertions(+)
create mode 100644 drivers/clocksource/csky_mptimer.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a11f4ba..51286be 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -609,6 +609,14 @@ config ATCPIT100_TIMER
help
This option enables support for the Andestech ATCPIT100 timers.
+config CSKY_MPTIMER
+ bool "C-SKY Multi Processor Timer"
+ depends on CSKY
+ select TIMER_OF
+ help
+ Say yes here to enable C-SKY SMP timer driver used for C-SKY SMP
+ system.
+
config RISCV_TIMER
bool "Timer for the RISC-V platform"
depends on RISCV
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index db51b24..848c676 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -79,3 +79,4 @@ 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
+obj-$(CONFIG_CSKY_MPTIMER) += csky_mptimer.o
diff --git a/drivers/clocksource/csky_mptimer.c b/drivers/clocksource/csky_mptimer.c
new file mode 100644
index 0000000..c6d5db1
--- /dev/null
+++ b/drivers/clocksource/csky_mptimer.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched_clock.h>
+#include <linux/cpu.h>
+#include <asm/reg_ops.h>
+
+#include "timer-of.h"
+
+#define PTIM_CCVR "cr<3, 14>"
+#define PTIM_CTLR "cr<0, 14>"
+#define PTIM_LVR "cr<6, 14>"
+#define PTIM_TSR "cr<1, 14>"
+
+static int csky_mptimer_set_next_event(unsigned long delta, struct clock_event_device *ce)
+{
+ mtcr(PTIM_LVR, delta);
+
+ return 0;
+}
+
+static int csky_mptimer_shutdown(struct clock_event_device *ce)
+{
+ mtcr(PTIM_CTLR, 0);
+
+ return 0;
+}
+
+static int csky_mptimer_oneshot(struct clock_event_device *ce)
+{
+ mtcr(PTIM_CTLR, 1);
+
+ return 0;
+}
+
+static int csky_mptimer_oneshot_stopped(struct clock_event_device *ce)
+{
+ mtcr(PTIM_CTLR, 0);
+
+ return 0;
+}
+
+static DEFINE_PER_CPU(struct timer_of, csky_to) = {
+ .flags = TIMER_OF_CLOCK,
+ .clkevt = {
+ .rating = 300,
+ .features = CLOCK_EVT_FEAT_PERCPU |
+ CLOCK_EVT_FEAT_ONESHOT,
+ .set_state_shutdown = csky_mptimer_shutdown,
+ .set_state_oneshot = csky_mptimer_oneshot,
+ .set_state_oneshot_stopped = csky_mptimer_oneshot_stopped,
+ .set_next_event = csky_mptimer_set_next_event,
+ },
+ .of_irq = {
+ .flags = IRQF_TIMER,
+ .percpu = 1,
+ },
+};
+
+static irqreturn_t timer_interrupt(int irq, void *dev)
+{
+ struct timer_of *to = this_cpu_ptr(&csky_to);
+
+ mtcr(PTIM_TSR, 0);
+
+ to->clkevt.event_handler(&to->clkevt);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * clock event for percpu
+ */
+static int csky_mptimer_starting_cpu(unsigned int cpu)
+{
+ struct timer_of *to = per_cpu_ptr(&csky_to, cpu);
+
+ to->clkevt.cpumask = cpumask_of(cpu);
+
+ clockevents_config_and_register(&to->clkevt, timer_of_rate(to), 2, ULONG_MAX);
+
+ enable_percpu_irq(timer_of_irq(to), 0);
+
+ return 0;
+}
+
+static int csky_mptimer_dying_cpu(unsigned int cpu)
+{
+ struct timer_of *to = per_cpu_ptr(&csky_to, cpu);
+
+ disable_percpu_irq(timer_of_irq(to));
+
+ return 0;
+}
+
+/*
+ * clock source
+ */
+static u64 sched_clock_read(void)
+{
+ return (u64) mfcr(PTIM_CCVR);
+}
+
+static u64 clksrc_read(struct clocksource *c)
+{
+ return (u64) mfcr(PTIM_CCVR);
+}
+
+struct clocksource csky_clocksource = {
+ .name = "csky",
+ .rating = 400,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .read = clksrc_read,
+};
+
+#define CPUHP_AP_CSKY_TIMER_STARTING CPUHP_AP_RISCV_TIMER_STARTING
+
+static int __init csky_mptimer_init(struct device_node *np)
+{
+ int ret, cpu;
+ struct timer_of *to;
+ int rate = 0;
+ int irq = 0;
+
+ /*
+ * Csky_mptimer is designed for C-SKY SMP multi-processors and
+ * every core has it's own private irq and regs for clkevt and
+ * clksrc.
+ *
+ * The regs is accessed by cpu instruction: mfcr/mtcr instead of
+ * mmio map style. So we needn't mmio-address in dts, but we still
+ * need to give clk and irq number.
+ *
+ * We use private irq for the mptimer and irq number is the same
+ * for every core. So we use request_percpu_irq() in timer_of_init.
+ */
+
+ for_each_possible_cpu(cpu) {
+ to = per_cpu_ptr(&csky_to, cpu);
+
+ if (cpu == 0) {
+ to->flags |= TIMER_OF_IRQ;
+ to->of_irq.handler = timer_interrupt;
+
+ ret = timer_of_init(np, to);
+ if (ret)
+ return ret;
+
+ rate = timer_of_rate(to);
+ irq = to->of_irq.irq;
+ } else {
+ ret = timer_of_init(np, to);
+ if (ret)
+ return ret;
+
+ to->of_clk.rate = rate;
+ to->of_irq.irq = irq;
+ }
+ }
+
+ ret = cpuhp_setup_state(CPUHP_AP_CSKY_TIMER_STARTING,
+ "clockevents/csky/timer:starting",
+ csky_mptimer_starting_cpu,
+ csky_mptimer_dying_cpu);
+ if (ret) {
+ pr_err("%s: Failed to cpuhp_setup_state.\n", __func__);
+ return ret;
+ }
+
+ clocksource_register_hz(&csky_clocksource, rate);
+ sched_clock_register(sched_clock_read, 32, rate);
+
+ return 0;
+}
+TIMER_OF_DECLARE(csky_mptimer, "csky,mptimer", csky_mptimer_init);
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index caf40ad..e0cd2ba 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -126,6 +126,7 @@ enum cpuhp_state {
CPUHP_AP_MIPS_GIC_TIMER_STARTING,
CPUHP_AP_ARC_TIMER_STARTING,
CPUHP_AP_RISCV_TIMER_STARTING,
+ CPUHP_AP_CSKY_TIMER_STARTING,
CPUHP_AP_KVM_STARTING,
CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
CPUHP_AP_KVM_ARM_VGIC_STARTING,
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH V8 6/6] dt-bindings: timer: C-SKY Multi-processor timer
2018-09-20 5:39 [PATCH V8 0/6] C-SKY(csky) Linux Kernel Port Guo Ren
` (4 preceding siblings ...)
2018-09-20 5:39 ` [PATCH V8 5/6] clocksource: add C-SKY SMP timer Guo Ren
@ 2018-09-20 5:39 ` Guo Ren
5 siblings, 0 replies; 8+ messages in thread
From: Guo Ren @ 2018-09-20 5:39 UTC (permalink / raw)
To: tglx, jason, marc.zyngier, robh+dt, mark.rutland, arnd, robh, sfr
Cc: linux-kernel, devicetree, linux-arch, c-sky_gcc_upstream,
gnu-csky, green.hu, Guo Ren
- Dt-bingdings doc for C-SKY SMP system setting.
Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
.../devicetree/bindings/timer/csky,mptimer.txt | 46 ++++++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 Documentation/devicetree/bindings/timer/csky,mptimer.txt
diff --git a/Documentation/devicetree/bindings/timer/csky,mptimer.txt b/Documentation/devicetree/bindings/timer/csky,mptimer.txt
new file mode 100644
index 0000000..1e7e31d
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/csky,mptimer.txt
@@ -0,0 +1,46 @@
+============================
+C-SKY Multi-processors Timer
+============================
+
+C-SKY multi-processors timer is designed for C-SKY SMP system and the
+regs is accessed by cpu co-processor 4 registers with mtcr/mfcr.
+
+ - PTIM_CTLR "cr<0, 14>" Control reg to start reset timer.
+ - PTIM_TSR "cr<1, 14>" Interrupt cleanup status reg.
+ - PTIM_CCVR "cr<3, 14>" Current counter value reg.
+ - PTIM_LVR "cr<6, 14>" Window value reg to triger next event.
+
+==============================
+timer node bindings definition
+==============================
+
+ Description: Describes SMP timer
+
+ PROPERTIES
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: must be "csky,mptimer"
+ - clocks
+ Usage: required
+ Value type: <node>
+ Definition: must be input clk node
+ - interrupts
+ Usage: required
+ Value type: <u32>
+ Definition: must be timer irq num defined by soc
+ - interrupt-parent:
+ Usage: required
+ Value type: <node>
+ Definition: must be interrupt controller node
+
+Examples:
+---------
+
+ timer: timer {
+ compatible = "csky,mptimer";
+ clocks = <&dummy_apb_clk>;
+ interrupts = <16>;
+ interrupt-parent = <&intc>;
+ };
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH V8 5/6] clocksource: add C-SKY SMP timer
2018-09-20 5:39 ` [PATCH V8 5/6] clocksource: add C-SKY SMP timer Guo Ren
@ 2018-09-20 5:54 ` Guo Ren
0 siblings, 0 replies; 8+ messages in thread
From: Guo Ren @ 2018-09-20 5:54 UTC (permalink / raw)
To: tglx, jason, marc.zyngier, robh+dt, mark.rutland, arnd, robh, sfr
Cc: linux-kernel, devicetree, linux-arch, c-sky_gcc_upstream,
gnu-csky, green.hu
On Thu, Sep 20, 2018 at 01:39:31PM +0800, Guo Ren wrote:
> +struct clocksource csky_clocksource = {
> + .name = "csky",
> + .rating = 400,
> + .mask = CLOCKSOURCE_MASK(32),
> + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
> + .read = clksrc_read,
> +};
> +
> +#define CPUHP_AP_CSKY_TIMER_STARTING CPUHP_AP_RISCV_TIMER_STARTING
My fault, forget delete the line above.
Guo Ren
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-09-20 5:55 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-20 5:39 [PATCH V8 0/6] C-SKY(csky) Linux Kernel Port Guo Ren
2018-09-20 5:39 ` [PATCH V8 1/6] csky/dma: bugfix dma_sync_for_cpu/device Guo Ren
2018-09-20 5:39 ` [PATCH V8 2/6] csky: remove irq_mapping from smp.c Guo Ren
2018-09-20 5:39 ` [PATCH V8 3/6] irqchip: add C-SKY SMP interrupt controller Guo Ren
2018-09-20 5:39 ` [PATCH V8 4/6] dt-bindings: interrupt-controller: C-SKY SMP intc Guo Ren
2018-09-20 5:39 ` [PATCH V8 5/6] clocksource: add C-SKY SMP timer Guo Ren
2018-09-20 5:54 ` Guo Ren
2018-09-20 5:39 ` [PATCH V8 6/6] dt-bindings: timer: C-SKY Multi-processor timer Guo Ren
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.