From 98022940c2431025be3c95e50035d762c40f539d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 21 Feb 2011 13:58:10 +0000 Subject: ARM: tegra: update GPIO chained IRQ handler to use entry/exit functions This patch updates the Tegra gpio chained IRQ handler to use the chained IRQ enter/exit functions in order to function correctly on primary controllers with different methods of flow control. This is required for the GIC to move to fasteoi interrupt handling. Acked-by: Colin Cross Signed-off-by: Will Deacon --- arch/arm/mach-tegra/gpio.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c index 65a1aba6823d..919d63837736 100644 --- a/arch/arm/mach-tegra/gpio.c +++ b/arch/arm/mach-tegra/gpio.c @@ -24,6 +24,8 @@ #include #include +#include + #include #include @@ -221,8 +223,9 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) int port; int pin; int unmasked = 0; + struct irq_chip *chip = irq_desc_get_chip(desc); - desc->irq_data.chip->irq_ack(&desc->irq_data); + chained_irq_enter(chip, desc); bank = irq_get_handler_data(irq); @@ -241,7 +244,7 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) */ if (lvl & (0x100 << pin)) { unmasked = 1; - desc->irq_data.chip->irq_unmask(&desc->irq_data); + chained_irq_exit(chip, desc); } generic_handle_irq(gpio_to_irq(gpio + pin)); @@ -249,7 +252,7 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) } if (!unmasked) - desc->irq_data.chip->irq_unmask(&desc->irq_data); + chained_irq_exit(chip, desc); } -- cgit v1.2.3 From 938fa349fbc16880feae4b65e56691ca12ede9ab Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Sun, 1 May 2011 14:10:10 -0700 Subject: ARM: tegra: irq: convert to gic arch extensions Replace the ugly hack that inserts legacy irq controller calls into the irq call paths by reading and replacing the gic irq chip with the new gic arch extensions. Signed-off-by: Colin Cross --- arch/arm/mach-tegra/irq.c | 54 ++++++++++++++--------------------------------- 1 file changed, 16 insertions(+), 38 deletions(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 4330d8995b27..567b75c4c67b 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 2010 Google, Inc. + * Copyright (C) 2011 Google, Inc. * * Author: - * Colin Cross + * Colin Cross * * Copyright (C) 2010, NVIDIA Corporation * @@ -46,10 +46,6 @@ static u32 tegra_lp0_wake_enb; static u32 tegra_lp0_wake_level; static u32 tegra_lp0_wake_level_any; -static void (*tegra_gic_mask_irq)(struct irq_data *d); -static void (*tegra_gic_unmask_irq)(struct irq_data *d); -static void (*tegra_gic_ack_irq)(struct irq_data *d); - /* ensures that sufficient time is passed for a register write to * serialize into the 32KHz domain */ static void pmc_32kwritel(u32 val, unsigned long offs) @@ -103,58 +99,40 @@ void tegra_set_lp0_wake_pads(u32 wake_enb, u32 wake_level, u32 wake_any) static void tegra_mask(struct irq_data *d) { - tegra_gic_mask_irq(d); - tegra_legacy_mask_irq(d->irq); + if (d->irq >= 32) + tegra_legacy_mask_irq(d->irq); } static void tegra_unmask(struct irq_data *d) { - tegra_gic_unmask_irq(d); - tegra_legacy_unmask_irq(d->irq); + if (d->irq >= 32) + tegra_legacy_unmask_irq(d->irq); } static void tegra_ack(struct irq_data *d) { - tegra_legacy_force_irq_clr(d->irq); - tegra_gic_ack_irq(d); + if (d->irq >= 32) + tegra_legacy_force_irq_clr(d->irq); } static int tegra_retrigger(struct irq_data *d) { + if (d->irq < 32) + return 0; + tegra_legacy_force_irq_set(d->irq); return 1; } -static struct irq_chip tegra_irq = { - .name = "PPI", - .irq_ack = tegra_ack, - .irq_mask = tegra_mask, - .irq_unmask = tegra_unmask, - .irq_retrigger = tegra_retrigger, -}; - void __init tegra_init_irq(void) { - struct irq_chip *gic; - unsigned int i; - int irq; - tegra_init_legacy_irq(); + gic_arch_extn.irq_ack = tegra_ack; + gic_arch_extn.irq_mask = tegra_mask; + gic_arch_extn.irq_unmask = tegra_unmask; + gic_arch_extn.irq_retrigger = tegra_retrigger; + gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); - - gic = irq_get_chip(29); - tegra_gic_unmask_irq = gic->irq_unmask; - tegra_gic_mask_irq = gic->irq_mask; - tegra_gic_ack_irq = gic->irq_ack; -#ifdef CONFIG_SMP - tegra_irq.irq_set_affinity = gic->irq_set_affinity; -#endif - - for (i = 0; i < INT_MAIN_NR; i++) { - irq = INT_PRI_BASE + i; - irq_set_chip_and_handler(irq, &tegra_irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } } -- cgit v1.2.3 From 4dda2d384bc69de260647c3b419967734a4de496 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Sun, 1 May 2011 14:10:11 -0700 Subject: ARM: tegra: irq: Remove PM support Tegra PM irq support is being improved, remove it for now until the rest of the platform gets PM support. Signed-off-by: Colin Cross --- arch/arm/mach-tegra/include/mach/legacy_irq.h | 3 -- arch/arm/mach-tegra/irq.c | 66 ----------------------- arch/arm/mach-tegra/legacy_irq.c | 77 --------------------------- 3 files changed, 146 deletions(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/include/mach/legacy_irq.h b/arch/arm/mach-tegra/include/mach/legacy_irq.h index d898c0e3d905..4c1f53543744 100644 --- a/arch/arm/mach-tegra/include/mach/legacy_irq.h +++ b/arch/arm/mach-tegra/include/mach/legacy_irq.h @@ -27,9 +27,6 @@ int tegra_legacy_force_irq_status(unsigned int irq); void tegra_legacy_select_fiq(unsigned int irq, bool fiq); unsigned long tegra_legacy_vfiq(int nr); unsigned long tegra_legacy_class(int nr); -int tegra_legacy_irq_set_wake(int irq, int enable); -void tegra_legacy_irq_set_lp1_wake_mask(void); -void tegra_legacy_irq_restore_mask(void); void tegra_init_legacy_irq(void); #endif diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 567b75c4c67b..4fa7a37ea5e4 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -28,75 +28,9 @@ #include #include -#include #include "board.h" -#define PMC_CTRL 0x0 -#define PMC_CTRL_LATCH_WAKEUPS (1 << 5) -#define PMC_WAKE_MASK 0xc -#define PMC_WAKE_LEVEL 0x10 -#define PMC_WAKE_STATUS 0x14 -#define PMC_SW_WAKE_STATUS 0x18 -#define PMC_DPD_SAMPLE 0x20 - -static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); - -static u32 tegra_lp0_wake_enb; -static u32 tegra_lp0_wake_level; -static u32 tegra_lp0_wake_level_any; - -/* ensures that sufficient time is passed for a register write to - * serialize into the 32KHz domain */ -static void pmc_32kwritel(u32 val, unsigned long offs) -{ - writel(val, pmc + offs); - udelay(130); -} - -int tegra_set_lp1_wake(int irq, int enable) -{ - return tegra_legacy_irq_set_wake(irq, enable); -} - -void tegra_set_lp0_wake_pads(u32 wake_enb, u32 wake_level, u32 wake_any) -{ - u32 temp; - u32 status; - u32 lvl; - - wake_level &= wake_enb; - wake_any &= wake_enb; - - wake_level |= (tegra_lp0_wake_level & tegra_lp0_wake_enb); - wake_any |= (tegra_lp0_wake_level_any & tegra_lp0_wake_enb); - - wake_enb |= tegra_lp0_wake_enb; - - pmc_32kwritel(0, PMC_SW_WAKE_STATUS); - temp = readl(pmc + PMC_CTRL); - temp |= PMC_CTRL_LATCH_WAKEUPS; - pmc_32kwritel(temp, PMC_CTRL); - temp &= ~PMC_CTRL_LATCH_WAKEUPS; - pmc_32kwritel(temp, PMC_CTRL); - status = readl(pmc + PMC_SW_WAKE_STATUS); - lvl = readl(pmc + PMC_WAKE_LEVEL); - - /* flip the wakeup trigger for any-edge triggered pads - * which are currently asserting as wakeups */ - lvl ^= status; - lvl &= wake_any; - - wake_level |= lvl; - - writel(wake_level, pmc + PMC_WAKE_LEVEL); - /* Enable DPD sample to trigger sampling pads data and direction - * in which pad will be driven during lp0 mode*/ - writel(0x1, pmc + PMC_DPD_SAMPLE); - - writel(wake_enb, pmc + PMC_WAKE_MASK); -} - static void tegra_mask(struct irq_data *d) { if (d->irq >= 32) diff --git a/arch/arm/mach-tegra/legacy_irq.c b/arch/arm/mach-tegra/legacy_irq.c index 38eb719a4f53..cb316699ffad 100644 --- a/arch/arm/mach-tegra/legacy_irq.c +++ b/arch/arm/mach-tegra/legacy_irq.c @@ -49,9 +49,6 @@ static void __iomem *ictlr_reg_base[] = { IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), }; -static u32 tegra_legacy_wake_mask[4]; -static u32 tegra_legacy_saved_mask[4]; - /* When going into deep sleep, the CPU is powered down, taking the GIC with it In order to wake, the wake interrupts need to be enabled in the legacy interrupt controller. */ @@ -129,40 +126,6 @@ unsigned long tegra_legacy_class(int nr) return readl(base + ICTLR_CPU_IEP_CLASS); } -int tegra_legacy_irq_set_wake(int irq, int enable) -{ - irq -= 32; - if (enable) - tegra_legacy_wake_mask[irq >> 5] |= 1 << (irq & 31); - else - tegra_legacy_wake_mask[irq >> 5] &= ~(1 << (irq & 31)); - - return 0; -} - -void tegra_legacy_irq_set_lp1_wake_mask(void) -{ - void __iomem *base; - int i; - - for (i = 0; i < NUM_ICTLRS; i++) { - base = ictlr_reg_base[i]; - tegra_legacy_saved_mask[i] = readl(base + ICTLR_CPU_IER); - writel(tegra_legacy_wake_mask[i], base + ICTLR_CPU_IER); - } -} - -void tegra_legacy_irq_restore_mask(void) -{ - void __iomem *base; - int i; - - for (i = 0; i < NUM_ICTLRS; i++) { - base = ictlr_reg_base[i]; - writel(tegra_legacy_saved_mask[i], base + ICTLR_CPU_IER); - } -} - void tegra_init_legacy_irq(void) { int i; @@ -173,43 +136,3 @@ void tegra_init_legacy_irq(void) writel(0, ictlr + ICTLR_CPU_IEP_CLASS); } } - -#ifdef CONFIG_PM -static u32 cop_ier[NUM_ICTLRS]; -static u32 cpu_ier[NUM_ICTLRS]; -static u32 cpu_iep[NUM_ICTLRS]; - -void tegra_irq_suspend(void) -{ - unsigned long flags; - int i; - - local_irq_save(flags); - for (i = 0; i < NUM_ICTLRS; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - cpu_ier[i] = readl(ictlr + ICTLR_CPU_IER); - cpu_iep[i] = readl(ictlr + ICTLR_CPU_IEP_CLASS); - cop_ier[i] = readl(ictlr + ICTLR_COP_IER); - writel(~0, ictlr + ICTLR_COP_IER_CLR); - } - local_irq_restore(flags); -} - -void tegra_irq_resume(void) -{ - unsigned long flags; - int i; - - local_irq_save(flags); - for (i = 0; i < NUM_ICTLRS; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - writel(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS); - writel(~0ul, ictlr + ICTLR_CPU_IER_CLR); - writel(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET); - writel(0, ictlr + ICTLR_COP_IEP_CLASS); - writel(~0ul, ictlr + ICTLR_COP_IER_CLR); - writel(cop_ier[i], ictlr + ICTLR_COP_IER_SET); - } - local_irq_restore(flags); -} -#endif -- cgit v1.2.3 From d1d8c666683cdbef18329ff8f3743ddaca8842ee Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Sun, 1 May 2011 15:26:51 -0700 Subject: ARM: tegra: irq: Move legacy_irq.c into irq.c Now that irq.c is just an interface layer between the gic and legacy_irq.c, move the contents of legacy_irq.c into irq.c. Signed-off-by: Colin Cross --- arch/arm/mach-tegra/Makefile | 2 +- arch/arm/mach-tegra/include/mach/legacy_irq.h | 32 ------ arch/arm/mach-tegra/irq.c | 77 +++++++++++--- arch/arm/mach-tegra/legacy_irq.c | 138 -------------------------- 4 files changed, 66 insertions(+), 183 deletions(-) delete mode 100644 arch/arm/mach-tegra/include/mach/legacy_irq.h delete mode 100644 arch/arm/mach-tegra/legacy_irq.c (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 1afe05038c27..823c703e573c 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -1,7 +1,7 @@ obj-y += common.o obj-y += devices.o obj-y += io.o -obj-y += irq.o legacy_irq.o +obj-y += irq.o obj-y += clock.o obj-y += timer.o obj-y += gpio.o diff --git a/arch/arm/mach-tegra/include/mach/legacy_irq.h b/arch/arm/mach-tegra/include/mach/legacy_irq.h deleted file mode 100644 index 4c1f53543744..000000000000 --- a/arch/arm/mach-tegra/include/mach/legacy_irq.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/legacy_irq.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H -#define _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H - -void tegra_legacy_mask_irq(unsigned int irq); -void tegra_legacy_unmask_irq(unsigned int irq); -void tegra_legacy_select_fiq(unsigned int irq, bool fiq); -void tegra_legacy_force_irq_set(unsigned int irq); -void tegra_legacy_force_irq_clr(unsigned int irq); -int tegra_legacy_force_irq_status(unsigned int irq); -void tegra_legacy_select_fiq(unsigned int irq, bool fiq); -unsigned long tegra_legacy_vfiq(int nr); -unsigned long tegra_legacy_class(int nr); -void tegra_init_legacy_irq(void); - -#endif diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 4fa7a37ea5e4..da1749108c7d 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -18,8 +18,6 @@ */ #include -#include -#include #include #include #include @@ -27,40 +25,95 @@ #include #include -#include #include "board.h" +#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE) +#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE) +#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ) + +#define ICTLR_CPU_IEP_VFIQ 0x08 +#define ICTLR_CPU_IEP_FIR 0x14 +#define ICTLR_CPU_IEP_FIR_SET 0x18 +#define ICTLR_CPU_IEP_FIR_CLR 0x1c + +#define ICTLR_CPU_IER 0x20 +#define ICTLR_CPU_IER_SET 0x24 +#define ICTLR_CPU_IER_CLR 0x28 +#define ICTLR_CPU_IEP_CLASS 0x2C + +#define ICTLR_COP_IER 0x30 +#define ICTLR_COP_IER_SET 0x34 +#define ICTLR_COP_IER_CLR 0x38 +#define ICTLR_COP_IEP_CLASS 0x3c + +#define NUM_ICTLRS 4 +#define FIRST_LEGACY_IRQ 32 + +static void __iomem *ictlr_reg_base[] = { + IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), + IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), + IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), + IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), +}; + +static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) +{ + void __iomem *base; + u32 mask; + + BUG_ON(irq < FIRST_LEGACY_IRQ || + irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32); + + base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32]; + mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); + + __raw_writel(mask, base + reg); +} + static void tegra_mask(struct irq_data *d) { - if (d->irq >= 32) - tegra_legacy_mask_irq(d->irq); + if (d->irq < FIRST_LEGACY_IRQ) + return; + + tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_CLR); } static void tegra_unmask(struct irq_data *d) { - if (d->irq >= 32) - tegra_legacy_unmask_irq(d->irq); + if (d->irq < FIRST_LEGACY_IRQ) + return; + + tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_SET); } static void tegra_ack(struct irq_data *d) { - if (d->irq >= 32) - tegra_legacy_force_irq_clr(d->irq); + if (d->irq < FIRST_LEGACY_IRQ) + return; + + tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR); } static int tegra_retrigger(struct irq_data *d) { - if (d->irq < 32) + if (d->irq < FIRST_LEGACY_IRQ) return 0; - tegra_legacy_force_irq_set(d->irq); + tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_SET); + return 1; } void __init tegra_init_irq(void) { - tegra_init_legacy_irq(); + int i; + + for (i = 0; i < NUM_ICTLRS; i++) { + void __iomem *ictlr = ictlr_reg_base[i]; + writel(~0, ictlr + ICTLR_CPU_IER_CLR); + writel(0, ictlr + ICTLR_CPU_IEP_CLASS); + } gic_arch_extn.irq_ack = tegra_ack; gic_arch_extn.irq_mask = tegra_mask; diff --git a/arch/arm/mach-tegra/legacy_irq.c b/arch/arm/mach-tegra/legacy_irq.c deleted file mode 100644 index cb316699ffad..000000000000 --- a/arch/arm/mach-tegra/legacy_irq.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * arch/arm/mach-tegra/legacy_irq.c - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE) -#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE) -#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ) - -#define ICTLR_CPU_IEP_VFIQ 0x08 -#define ICTLR_CPU_IEP_FIR 0x14 -#define ICTLR_CPU_IEP_FIR_SET 0x18 -#define ICTLR_CPU_IEP_FIR_CLR 0x1c - -#define ICTLR_CPU_IER 0x20 -#define ICTLR_CPU_IER_SET 0x24 -#define ICTLR_CPU_IER_CLR 0x28 -#define ICTLR_CPU_IEP_CLASS 0x2C - -#define ICTLR_COP_IER 0x30 -#define ICTLR_COP_IER_SET 0x34 -#define ICTLR_COP_IER_CLR 0x38 -#define ICTLR_COP_IEP_CLASS 0x3c - -#define NUM_ICTLRS 4 - -static void __iomem *ictlr_reg_base[] = { - IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), -}; - -/* When going into deep sleep, the CPU is powered down, taking the GIC with it - In order to wake, the wake interrupts need to be enabled in the legacy - interrupt controller. */ -void tegra_legacy_unmask_irq(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(1 << (irq & 31), base + ICTLR_CPU_IER_SET); -} - -void tegra_legacy_mask_irq(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(1 << (irq & 31), base + ICTLR_CPU_IER_CLR); -} - -void tegra_legacy_force_irq_set(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_SET); -} - -void tegra_legacy_force_irq_clr(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_CLR); -} - -int tegra_legacy_force_irq_status(unsigned int irq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - return !!(readl(base + ICTLR_CPU_IEP_FIR) & (1 << (irq & 31))); -} - -void tegra_legacy_select_fiq(unsigned int irq, bool fiq) -{ - void __iomem *base; - pr_debug("%s: %d\n", __func__, irq); - - irq -= 32; - base = ictlr_reg_base[irq>>5]; - writel(fiq << (irq & 31), base + ICTLR_CPU_IEP_CLASS); -} - -unsigned long tegra_legacy_vfiq(int nr) -{ - void __iomem *base; - base = ictlr_reg_base[nr]; - return readl(base + ICTLR_CPU_IEP_VFIQ); -} - -unsigned long tegra_legacy_class(int nr) -{ - void __iomem *base; - base = ictlr_reg_base[nr]; - return readl(base + ICTLR_CPU_IEP_CLASS); -} - -void tegra_init_legacy_irq(void) -{ - int i; - - for (i = 0; i < NUM_ICTLRS; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - writel(~0, ictlr + ICTLR_CPU_IER_CLR); - writel(0, ictlr + ICTLR_CPU_IEP_CLASS); - } -} -- cgit v1.2.3 From 4bd66cfde5c3b6eced0da483c6357ae46d3adbb5 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Sun, 1 May 2011 15:27:34 -0700 Subject: ARM: tegra: irq: Add tegra_eoi Implement irq_eoi to allow the GIC irq chip flow controller to be changed to fasteoi. Signed-off-by: Colin Cross --- arch/arm/mach-tegra/irq.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index da1749108c7d..4956c3cea731 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -95,6 +95,14 @@ static void tegra_ack(struct irq_data *d) tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR); } +static void tegra_eoi(struct irq_data *d) +{ + if (d->irq < FIRST_LEGACY_IRQ) + return; + + tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR); +} + static int tegra_retrigger(struct irq_data *d) { if (d->irq < FIRST_LEGACY_IRQ) @@ -116,6 +124,7 @@ void __init tegra_init_irq(void) } gic_arch_extn.irq_ack = tegra_ack; + gic_arch_extn.irq_eoi = tegra_eoi; gic_arch_extn.irq_mask = tegra_mask; gic_arch_extn.irq_unmask = tegra_unmask; gic_arch_extn.irq_retrigger = tegra_retrigger; -- cgit v1.2.3 From 0f7b332f9777819a39a3b325690379a7efef89d1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 3 Apr 2011 13:01:30 +0100 Subject: ARM: consolidate SMP cross call implementation Rather than having each platform class provide a mach/smp.h header for smp_cross_call(), arrange for them to register the function with the core ARM SMP code instead. Signed-off-by: Russell King --- arch/arm/include/asm/smp.h | 6 ++---- arch/arm/kernel/smp.c | 7 +++++++ arch/arm/mach-exynos4/include/mach/smp.h | 19 ------------------- arch/arm/mach-exynos4/platsmp.c | 5 ++++- arch/arm/mach-msm/include/mach/smp.h | 23 ----------------------- arch/arm/mach-msm/platsmp.c | 4 +++- arch/arm/mach-omap2/omap-smp.c | 5 ++++- arch/arm/mach-realview/include/mach/smp.h | 14 -------------- arch/arm/mach-realview/platsmp.c | 3 +++ arch/arm/mach-shmobile/include/mach/smp.h | 16 ---------------- arch/arm/mach-shmobile/platsmp.c | 3 +++ arch/arm/mach-tegra/include/mach/smp.h | 14 -------------- arch/arm/mach-tegra/platsmp.c | 3 +++ arch/arm/mach-ux500/include/mach/smp.h | 24 ------------------------ arch/arm/mach-ux500/platsmp.c | 5 ++++- arch/arm/mach-vexpress/ct-ca9x4.c | 2 ++ arch/arm/mach-vexpress/include/mach/smp.h | 13 ------------- arch/arm/plat-omap/include/plat/smp.h | 30 ------------------------------ arch/arm/plat-versatile/platsmp.c | 3 ++- 19 files changed, 37 insertions(+), 162 deletions(-) delete mode 100644 arch/arm/mach-exynos4/include/mach/smp.h delete mode 100644 arch/arm/mach-msm/include/mach/smp.h delete mode 100644 arch/arm/mach-realview/include/mach/smp.h delete mode 100644 arch/arm/mach-shmobile/include/mach/smp.h delete mode 100644 arch/arm/mach-tegra/include/mach/smp.h delete mode 100644 arch/arm/mach-ux500/include/mach/smp.h delete mode 100644 arch/arm/mach-vexpress/include/mach/smp.h delete mode 100644 arch/arm/plat-omap/include/plat/smp.h (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index 96ed521f2408..a87664f54f93 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -14,8 +14,6 @@ #include #include -#include - #ifndef CONFIG_SMP # error " included in non-SMP build" #endif @@ -47,9 +45,9 @@ extern void smp_init_cpus(void); /* - * Raise an IPI cross call on CPUs in callmap. + * Provide a function to raise an IPI cross call on CPUs in callmap. */ -extern void smp_cross_call(const struct cpumask *mask, int ipi); +extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int)); /* * Boot a secondary CPU, and assign it the specified idle task. diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 8fe05ad932e4..a0ad0540761f 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -376,6 +376,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } } +static void (*smp_cross_call)(const struct cpumask *, unsigned int); + +void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) +{ + smp_cross_call = fn; +} + void arch_send_call_function_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_CALL_FUNC); diff --git a/arch/arm/mach-exynos4/include/mach/smp.h b/arch/arm/mach-exynos4/include/mach/smp.h deleted file mode 100644 index a463dcebcfd3..000000000000 --- a/arch/arm/mach-exynos4/include/mach/smp.h +++ /dev/null @@ -1,19 +0,0 @@ -/* linux/arch/arm/mach-exynos4/include/mach/smp.h - * - * Cloned from arch/arm/mach-realview/include/mach/smp.h -*/ - -#ifndef ASM_ARCH_SMP_H -#define ASM_ARCH_SMP_H __FILE__ - -#include - -/* - * We use IRQ1 as the IPI - */ -static inline void smp_cross_call(const struct cpumask *mask, int ipi) -{ - gic_raise_softirq(mask, ipi); -} - -#endif diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c index 6d35878ec1aa..c5e65a02be8d 100644 --- a/arch/arm/mach-exynos4/platsmp.c +++ b/arch/arm/mach-exynos4/platsmp.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -104,7 +105,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) * the boot monitor to read the system wide flags register, * and branch to the address found there. */ - smp_cross_call(cpumask_of(cpu), 1); + gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { @@ -147,6 +148,8 @@ void __init smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); } void __init platform_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-msm/include/mach/smp.h b/arch/arm/mach-msm/include/mach/smp.h deleted file mode 100644 index 3c01000ecc80..000000000000 --- a/arch/arm/mach-msm/include/mach/smp.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_ARCH_MSM_SMP_H -#define __ASM_ARCH_MSM_SMP_H - -#include - -static inline void smp_cross_call(const struct cpumask *mask, int ipi) -{ - gic_raise_softirq(mask, ipi); -} - -#endif diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index 0f427bc94447..2034098cf015 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c @@ -119,7 +119,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) * the boot monitor to read the system wide flags register, * and branch to the address found there. */ - smp_cross_call(cpumask_of(cpu), 1); + gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { @@ -151,6 +151,8 @@ void __init smp_init_cpus(void) for (i = 0; i < NR_CPUS; i++) set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); } void __init platform_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index b66cfe8bc464..ecfe93c4b585 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -63,7 +64,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) omap_modify_auxcoreboot0(0x200, 0xfffffdff); flush_cache_all(); smp_wmb(); - smp_cross_call(cpumask_of(cpu), 1); + gic_raise_softirq(cpumask_of(cpu), 1); /* * Now the secondary core is starting up let it run its @@ -118,6 +119,8 @@ void __init smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); } void __init platform_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h deleted file mode 100644 index c8221b38ee7c..000000000000 --- a/arch/arm/mach-realview/include/mach/smp.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef ASMARM_ARCH_SMP_H -#define ASMARM_ARCH_SMP_H - -#include - -/* - * We use IRQ1 as the IPI - */ -static inline void smp_cross_call(const struct cpumask *mask, int ipi) -{ - gic_raise_softirq(mask, ipi); -} - -#endif diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index 23919229e12d..963bf0d8119a 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -61,6 +62,8 @@ void __init smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); } void __init platform_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-shmobile/include/mach/smp.h b/arch/arm/mach-shmobile/include/mach/smp.h deleted file mode 100644 index 50db94e927ad..000000000000 --- a/arch/arm/mach-shmobile/include/mach/smp.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __MACH_SMP_H -#define __MACH_SMP_H - -#include - -/* - * We use IRQ1 as the IPI - */ -static inline void smp_cross_call(const struct cpumask *mask, int ipi) -{ -#if defined(CONFIG_ARM_GIC) - gic_raise_softirq(mask, ipi); -#endif -} - -#endif diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index 65e879bab4dc..f3888feb1c68 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,8 @@ void __init smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); } void __init platform_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h deleted file mode 100644 index c8221b38ee7c..000000000000 --- a/arch/arm/mach-tegra/include/mach/smp.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef ASMARM_ARCH_SMP_H -#define ASMARM_ARCH_SMP_H - -#include - -/* - * We use IRQ1 as the IPI - */ -static inline void smp_cross_call(const struct cpumask *mask, int ipi) -{ - gic_raise_softirq(mask, ipi); -} - -#endif diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index ec1f68924edf..b8ae3c978dee 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -122,6 +123,8 @@ void __init smp_init_cpus(void) for (i = 0; i < ncores; i++) cpu_set(i, cpu_possible_map); + + set_smp_cross_call(gic_raise_softirq); } void __init platform_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h deleted file mode 100644 index ca2b15b1b3b1..000000000000 --- a/arch/arm/mach-ux500/include/mach/smp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is based ARM realview platform. - * Copyright (C) ARM Limited. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ -#ifndef ASMARM_ARCH_SMP_H -#define ASMARM_ARCH_SMP_H - -#include - -/* This is required to wakeup the secondary core */ -extern void u8500_secondary_startup(void); - -/* - * We use IRQ1 as the IPI - */ -static inline void smp_cross_call(const struct cpumask *mask, int ipi) -{ - gic_raise_softirq(mask, ipi); -} -#endif diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 4fff4d408417..4e338466839e 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -94,7 +95,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) */ write_pen_release(cpu); - smp_cross_call(cpumask_of(cpu), 1); + gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { @@ -162,6 +163,8 @@ void __init smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); } void __init platform_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index ebc22e759325..9dc1c697fd2a 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -210,6 +210,8 @@ static void ct_ca9x4_init_cpu_map(void) for (i = 0; i < ncores; ++i) set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); } static void ct_ca9x4_smp_enable(unsigned int max_cpus) diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h deleted file mode 100644 index 4c05e4a9713a..000000000000 --- a/arch/arm/mach-vexpress/include/mach/smp.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __MACH_SMP_H -#define __MACH_SMP_H - -#include - -/* - * We use IRQ1 as the IPI - */ -static inline void smp_cross_call(const struct cpumask *mask, int ipi) -{ - gic_raise_softirq(mask, ipi); -} -#endif diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h deleted file mode 100644 index 416e9d579fde..000000000000 --- a/arch/arm/plat-omap/include/plat/smp.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * OMAP4 machine specific smp.h - * - * Copyright (C) 2009 Texas Instruments, Inc. - * - * Author: - * Santosh Shilimkar - * - * Interface functions needed for the SMP. This file is based on arm - * realview smp platform. - * Copyright (c) 2003 ARM Limited. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef OMAP_ARCH_SMP_H -#define OMAP_ARCH_SMP_H - -#include - -/* - * We use Soft IRQ1 as the IPI - */ -static inline void smp_cross_call(const struct cpumask *mask, int ipi) -{ - gic_raise_softirq(mask, ipi); -} - -#endif diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c index ba3d471d4bcf..51ecfea09b27 100644 --- a/arch/arm/plat-versatile/platsmp.c +++ b/arch/arm/plat-versatile/platsmp.c @@ -16,6 +16,7 @@ #include #include +#include /* * control for which core is the next to come out of the secondary @@ -83,7 +84,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) * the boot monitor to read the system wide flags register, * and branch to the address found there. */ - smp_cross_call(cpumask_of(cpu), 1); + gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { -- cgit v1.2.3 From 234b6ceddb4fc2a4bc5b9a7670f070f6e69e0868 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 8 May 2011 14:09:47 +0100 Subject: clocksource: convert ARM 32-bit up counting clocksources Convert ixp4xx, lpc32xx, mxc, netx, pxa, sa1100, tcc8k, tegra and u300 to use the generic mmio clocksource recently introduced. Cc: Imre Kaloz Cc: Krzysztof Halasa Acked-by: Eric Miao Acked-by: "Hans J. Koch" Acked-by: Colin Cross Cc: Erik Gilling Cc: Olof Johansson Acked-by: Linus Walleij Acked-by: Sascha Hauer Signed-off-by: Russell King --- arch/arm/Kconfig | 9 +++++++++ arch/arm/mach-ixp4xx/common.c | 16 ++-------------- arch/arm/mach-lpc32xx/timer.c | 17 +++-------------- arch/arm/mach-netx/time.c | 16 ++-------------- arch/arm/mach-pxa/time.c | 17 ++--------------- arch/arm/mach-sa1100/time.c | 16 ++-------------- arch/arm/mach-tcc8k/time.c | 16 ++-------------- arch/arm/mach-tegra/timer.c | 16 ++-------------- arch/arm/mach-u300/timer.c | 18 +++--------------- arch/arm/plat-mxc/time.c | 38 +++++++------------------------------- 10 files changed, 34 insertions(+), 145 deletions(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 377a7a595b08..9aa551497034 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -366,6 +366,7 @@ config ARCH_MXC select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select CLKSRC_MMIO select HAVE_SCHED_CLOCK help Support for Freescale MXC/iMX-based family of processors @@ -390,6 +391,7 @@ config ARCH_STMP3XXX config ARCH_NETX bool "Hilscher NetX based" + select CLKSRC_MMIO select CPU_ARM926T select ARM_VIC select GENERIC_CLOCKEVENTS @@ -457,6 +459,7 @@ config ARCH_IXP2000 config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU + select CLKSRC_MMIO select CPU_XSCALE select GENERIC_GPIO select GENERIC_CLOCKEVENTS @@ -497,6 +500,7 @@ config ARCH_LOKI config ARCH_LPC32XX bool "NXP LPC32XX" + select CLKSRC_MMIO select CPU_ARM926T select ARCH_REQUIRE_GPIOLIB select HAVE_IDE @@ -592,6 +596,7 @@ config ARCH_NUC93X config ARCH_TEGRA bool "NVIDIA Tegra" select CLKDEV_LOOKUP + select CLKSRC_MMIO select GENERIC_TIME select GENERIC_CLOCKEVENTS select GENERIC_GPIO @@ -617,6 +622,7 @@ config ARCH_PXA select ARCH_MTD_XIP select ARCH_HAS_CPUFREQ select CLKDEV_LOOKUP + select CLKSRC_MMIO select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS select HAVE_SCHED_CLOCK @@ -667,6 +673,7 @@ config ARCH_RPC config ARCH_SA1100 bool "SA1100-based" + select CLKSRC_MMIO select CPU_SA1100 select ISA select ARCH_SPARSEMEM_ENABLE @@ -803,6 +810,7 @@ config ARCH_SHARK config ARCH_TCC_926 bool "Telechips TCC ARM926-based systems" + select CLKSRC_MMIO select CPU_ARM926T select HAVE_CLK select CLKDEV_LOOKUP @@ -813,6 +821,7 @@ config ARCH_TCC_926 config ARCH_U300 bool "ST-Ericsson U300 Series" depends on MMU + select CLKSRC_MMIO select CPU_ARM926T select HAVE_SCHED_CLOCK select HAVE_TCM diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index ed19bc314318..74ed81a3cb1a 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -419,26 +419,14 @@ static void notrace ixp4xx_update_sched_clock(void) /* * clocksource */ -static cycle_t ixp4xx_get_cycles(struct clocksource *cs) -{ - return *IXP4XX_OSTS; -} - -static struct clocksource clocksource_ixp4xx = { - .name = "OSTS", - .rating = 200, - .read = ixp4xx_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; EXPORT_SYMBOL(ixp4xx_timer_freq); static void __init ixp4xx_clocksource_init(void) { init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq); - clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq); + clocksource_mmio_init(&IXP4XX_OSTS, "OSTS", ixp4xx_timer_freq, 200, 32, + clocksource_mmio_readl_up); } /* diff --git a/arch/arm/mach-lpc32xx/timer.c b/arch/arm/mach-lpc32xx/timer.c index 6162ac308c20..b42c909bbeeb 100644 --- a/arch/arm/mach-lpc32xx/timer.c +++ b/arch/arm/mach-lpc32xx/timer.c @@ -31,19 +31,6 @@ #include #include "common.h" -static cycle_t lpc32xx_clksrc_read(struct clocksource *cs) -{ - return (cycle_t)__raw_readl(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE)); -} - -static struct clocksource lpc32xx_clksrc = { - .name = "lpc32xx_clksrc", - .rating = 300, - .read = lpc32xx_clksrc_read, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - static int lpc32xx_clkevt_next_event(unsigned long delta, struct clock_event_device *dev) { @@ -170,7 +157,9 @@ static void __init lpc32xx_timer_init(void) __raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE)); __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN, LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); - clocksource_register_hz(&lpc32xx_clksrc, clkrate); + + clocksource_mmio_init(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE), + "lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up); } struct sys_timer lpc32xx_timer = { diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c index f12f22d09b6c..e24c141ba489 100644 --- a/arch/arm/mach-netx/time.c +++ b/arch/arm/mach-netx/time.c @@ -104,19 +104,6 @@ static struct irqaction netx_timer_irq = { .handler = netx_timer_interrupt, }; -cycle_t netx_get_cycles(struct clocksource *cs) -{ - return readl(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE)); -} - -static struct clocksource clocksource_netx = { - .name = "netx_timer", - .rating = 200, - .read = netx_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - /* * Set up timer interrupt */ @@ -150,7 +137,8 @@ static void __init netx_timer_init(void) writel(NETX_GPIO_COUNTER_CTRL_RUN, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE)); - clocksource_register_hz(&clocksource_netx, CLOCK_TICK_RATE); + clocksource_mmio_init(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE), + "netx_timer", CLOCK_TICK_RATE, 200, 32, clocksource_mmio_readl_up); netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, netx_clockevent.shift); diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 428da3ff33a5..de684701449c 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -105,19 +105,6 @@ static struct clock_event_device ckevt_pxa_osmr0 = { .set_mode = pxa_osmr0_set_mode, }; -static cycle_t pxa_read_oscr(struct clocksource *cs) -{ - return OSCR; -} - -static struct clocksource cksrc_pxa_oscr0 = { - .name = "oscr0", - .rating = 200, - .read = pxa_read_oscr, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - static struct irqaction pxa_ost0_irq = { .name = "ost0", .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, @@ -134,7 +121,6 @@ static void __init pxa_timer_init(void) init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate); - clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4); clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4); ckevt_pxa_osmr0.max_delta_ns = clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); @@ -144,7 +130,8 @@ static void __init pxa_timer_init(void) setup_irq(IRQ_OST0, &pxa_ost0_irq); - clocksource_register_hz(&cksrc_pxa_oscr0, clock_tick_rate); + clocksource_mmio_init(&OSCR, "oscr0", clock_tick_rate, 200, 32, + clocksource_mmio_readl_up); clockevents_register_device(&ckevt_pxa_osmr0); } diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index 51c05292d145..fa6602491d54 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c @@ -97,19 +97,6 @@ static struct clock_event_device ckevt_sa1100_osmr0 = { .set_mode = sa1100_osmr0_set_mode, }; -static cycle_t sa1100_read_oscr(struct clocksource *s) -{ - return OSCR; -} - -static struct clocksource cksrc_sa1100_oscr = { - .name = "oscr", - .rating = 200, - .read = sa1100_read_oscr, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - static struct irqaction sa1100_timer_irq = { .name = "ost0", .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, @@ -134,7 +121,8 @@ static void __init sa1100_timer_init(void) setup_irq(IRQ_OST0, &sa1100_timer_irq); - clocksource_register_hz(&cksrc_sa1100_oscr, CLOCK_TICK_RATE); + clocksource_mmio_init(&OSCR, "oscr", CLOCK_TICK_RATE, 200, 32, + clocksource_mmio_readl_up); clockevents_register_device(&ckevt_sa1100_osmr0); } diff --git a/arch/arm/mach-tcc8k/time.c b/arch/arm/mach-tcc8k/time.c index e0a8d609afe1..a96babe83771 100644 --- a/arch/arm/mach-tcc8k/time.c +++ b/arch/arm/mach-tcc8k/time.c @@ -25,19 +25,6 @@ static void __iomem *timer_base; -static cycle_t tcc_get_cycles(struct clocksource *cs) -{ - return __raw_readl(timer_base + TC32MCNT_OFFS); -} - -static struct clocksource clocksource_tcc = { - .name = "tcc_tc32", - .rating = 200, - .read = tcc_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - static int tcc_set_next_event(unsigned long evt, struct clock_event_device *unused) { @@ -102,7 +89,8 @@ static int __init tcc_clockevent_init(struct clk *clock) { unsigned int c = clk_get_rate(clock); - clocksource_register_hz(&clocksource_tcc, c); + clocksource_mmio_init(timer_base + TC32MCNT_OFFS, "tcc_tc32", c, + 200, 32, clocksource_mmio_readl_up); clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC, clockevent_tcc.shift); diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c index 0fcb1eb4214d..90350420c4e9 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/arch/arm/mach-tegra/timer.c @@ -98,11 +98,6 @@ static void tegra_timer_set_mode(enum clock_event_mode mode, } } -static cycle_t tegra_clocksource_read(struct clocksource *cs) -{ - return timer_readl(TIMERUS_CNTR_1US); -} - static struct clock_event_device tegra_clockevent = { .name = "timer0", .rating = 300, @@ -111,14 +106,6 @@ static struct clock_event_device tegra_clockevent = { .set_mode = tegra_timer_set_mode, }; -static struct clocksource tegra_clocksource = { - .name = "timer_us", - .rating = 300, - .read = tegra_clocksource_read, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - static DEFINE_CLOCK_DATA(cd); /* @@ -234,7 +221,8 @@ static void __init tegra_init_timer(void) init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32, 1000000, SC_MULT, SC_SHIFT); - if (clocksource_register_hz(&tegra_clocksource, 1000000)) { + if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US, + "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) { printk(KERN_ERR "Failed to register clocksource\n"); BUG(); } diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c index 3ec58bd2d6e4..891cf44591e0 100644 --- a/arch/arm/mach-u300/timer.c +++ b/arch/arm/mach-u300/timer.c @@ -333,20 +333,6 @@ static struct irqaction u300_timer_irq = { .handler = u300_timer_interrupt, }; -/* Use general purpose timer 2 as clock source */ -static cycle_t u300_get_cycles(struct clocksource *cs) -{ - return (cycles_t) readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); -} - -static struct clocksource clocksource_u300_1mhz = { - .name = "GPT2", - .rating = 300, /* Reasonably fast and accurate clock source */ - .read = u300_get_cycles, - .mask = CLOCKSOURCE_MASK(32), /* 32 bits */ - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - /* * Override the global weak sched_clock symbol with this * local implementation which uses the clocksource to get some @@ -422,7 +408,9 @@ static void __init u300_timer_init(void) writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); - if (clocksource_register_hz(&clocksource_u300_1mhz, rate)) + /* Use general purpose timer 2 as clock source */ + if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC, + "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) printk(KERN_ERR "timer: failed to initialize clock " "source %s\n", clocksource_u300_1mhz.name); diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 2237ff8b434f..e4ac94a86832 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -106,56 +106,32 @@ static void gpt_irq_acknowledge(void) __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT); } -static cycle_t dummy_get_cycles(struct clocksource *cs) -{ - return 0; -} - -static cycle_t mx1_2_get_cycles(struct clocksource *cs) -{ - return __raw_readl(timer_base + MX1_2_TCN); -} - -static cycle_t v2_get_cycles(struct clocksource *cs) -{ - return __raw_readl(timer_base + V2_TCN); -} - -static struct clocksource clocksource_mxc = { - .name = "mxc_timer1", - .rating = 200, - .read = dummy_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; +static void __iomem *sched_clock_reg; static DEFINE_CLOCK_DATA(cd); unsigned long long notrace sched_clock(void) { - cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); + cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; return cyc_to_sched_clock(&cd, cyc, (u32)~0); } static void notrace mxc_update_sched_clock(void) { - cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); + cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; update_sched_clock(&cd, cyc, (u32)~0); } static int __init mxc_clocksource_init(struct clk *timer_clk) { unsigned int c = clk_get_rate(timer_clk); + void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN); - if (timer_is_v2()) - clocksource_mxc.read = v2_get_cycles; - else - clocksource_mxc.read = mx1_2_get_cycles; + sched_clock_reg = reg; init_sched_clock(&cd, mxc_update_sched_clock, 32, c); - clocksource_register_hz(&clocksource_mxc, c); - - return 0; + return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32, + clocksource_mmio_readl_up); } /* clock event */ -- cgit v1.2.3