diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-03 19:55:55 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-03 19:55:55 -0400 |
| commit | 807249d3ada1ff28a47c4054ca4edd479421b671 (patch) | |
| tree | a9051ff7b4c31670ac89bb037c90d5baf90d449d /drivers/clocksource | |
| parent | ff474e8ca8547d09cb82ebab56d4c96f9eea01ce (diff) | |
| parent | 2db97045aa40da4312f7321845bc52b136c8603a (diff) | |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"This is the main pull request for 4.3 for MIPS. Here's the summary:
Three fixes that didn't make 4.2-stable:
- a -Os build might compile the kernel using the MIPS16 instruction
set but the R2 optimized inline functions in <uapi/asm/swab.h> are
implemented using 32-bit wide instructions which is invalid.
- a build error in pgtable-bits.h for a particular kernel
configuration.
- accessing registers of the CM GCR might have been compiled to use
64 bit accesses but these registers are onl 32 bit wide.
And also a few new bits:
- move the ATH79 GPIO driver to drivers/gpio
- the definition of IRQCHIP_DECLARE has moved to linux/irqchip.h,
change ATH79 accordingly.
- fix definition of pgprot_writecombine
- add an implementation of dma_map_ops.mmap
- fix alignment of quiet build output for vmlinuz link
- BCM47xx: Use kmemdup rather than duplicating its implementation
- Netlogic: Fix 0x0x prefixes of constants.
- merge Bjorn Helgaas' series to remove most of the weak keywords
from function declarations.
- CP0 and CP1 registers are best considered treated as unsigned
values to avoid large values from becoming negative values.
- improve support for the MIPS GIC timer.
- enable common clock framework for Malta and SEAD3.
- a number of improvments and fixes to dump_tlb().
- document the MIPS TLB dump functionality in Magic SysRq.
- Cavium Octeon CN68XX improvments.
- NetLogic improvments.
- irq: Use access helper irq_data_get_affinity_mask.
- handle MSA unaligned accesses.
- a number of R6-related math-emu fixes.
- support for I6400.
- improvments to MSA support.
- add uprobes support.
- move from deprecated __initcall to arch_initcall.
- remove finish_arch_switch().
- IRQ cleanups by Thomas Gleixner.
- migrate to new 'set-state' interface.
- random small cleanups"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (148 commits)
MIPS: UAPI: Fix unrecognized opcode WSBH/DSBH/DSHD when using MIPS16.
MIPS: Fix alignment of quiet build output for vmlinuz link
MIPS: math-emu: Remove unused handle_dsemul function declaration
MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction
MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction
MIPS: math-emu: Add support for the MIPS R6 CLASS FPU instruction
MIPS: math-emu: Add support for the MIPS R6 RINT FPU instruction
MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction
MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction
MIPS: math-emu: Add support for the MIPS R6 SELNEZ FPU instruction
MIPS: math-emu: Add support for the MIPS R6 SELEQZ FPU instruction
MIPS: math-emu: Add support for the CMP.condn.fmt R6 instruction
MIPS: inst.h: Add new MIPS R6 FPU opcodes
MIPS: Octeon: Fix management port MII address on Kontron S1901
MIPS: BCM47xx: Use kmemdup rather than duplicating its implementation
STAGING: Octeon: Use common helpers for determining interface and port
MIPS: Octeon: Support interfaces 4 and 5
MIPS: Octeon: Set up 1:1 mapping between CN68XX PKO queues and ports
MIPS: Octeon: Initialize CN68XX PKO
STAGING: Octeon: Support CN68XX style WQE
...
Diffstat (limited to 'drivers/clocksource')
| -rw-r--r-- | drivers/clocksource/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/clocksource/Makefile | 1 | ||||
| -rw-r--r-- | drivers/clocksource/mips-gic-timer.c | 65 | ||||
| -rw-r--r-- | drivers/clocksource/time-pistachio.c | 217 |
4 files changed, 278 insertions, 9 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index c03f04d82c6a..552c9b134cc5 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
| @@ -111,6 +111,10 @@ config CLKSRC_LPC32XX | |||
| 111 | select CLKSRC_MMIO | 111 | select CLKSRC_MMIO |
| 112 | select CLKSRC_OF | 112 | select CLKSRC_OF |
| 113 | 113 | ||
| 114 | config CLKSRC_PISTACHIO | ||
| 115 | bool | ||
| 116 | select CLKSRC_OF | ||
| 117 | |||
| 114 | config CLKSRC_STM32 | 118 | config CLKSRC_STM32 |
| 115 | bool "Clocksource for STM32 SoCs" if !ARCH_STM32 | 119 | bool "Clocksource for STM32 SoCs" if !ARCH_STM32 |
| 116 | depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST) | 120 | depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST) |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index f228354961ca..066337e24737 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
| @@ -44,6 +44,7 @@ obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o | |||
| 44 | obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o | 44 | obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o |
| 45 | obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o | 45 | obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o |
| 46 | obj-$(CONFIG_MTK_TIMER) += mtk_timer.o | 46 | obj-$(CONFIG_MTK_TIMER) += mtk_timer.o |
| 47 | obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o | ||
| 47 | 48 | ||
| 48 | obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o | 49 | obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o |
| 49 | obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o | 50 | obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o |
diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index c3810b61c815..02a1945e5093 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c | |||
| @@ -72,6 +72,13 @@ static void gic_clockevent_cpu_exit(struct clock_event_device *cd) | |||
| 72 | disable_percpu_irq(gic_timer_irq); | 72 | disable_percpu_irq(gic_timer_irq); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static void gic_update_frequency(void *data) | ||
| 76 | { | ||
| 77 | unsigned long rate = (unsigned long)data; | ||
| 78 | |||
| 79 | clockevents_update_freq(this_cpu_ptr(&gic_clockevent_device), rate); | ||
| 80 | } | ||
| 81 | |||
| 75 | static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, | 82 | static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, |
| 76 | void *data) | 83 | void *data) |
| 77 | { | 84 | { |
| @@ -87,18 +94,40 @@ static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, | |||
| 87 | return NOTIFY_OK; | 94 | return NOTIFY_OK; |
| 88 | } | 95 | } |
| 89 | 96 | ||
| 97 | static int gic_clk_notifier(struct notifier_block *nb, unsigned long action, | ||
| 98 | void *data) | ||
| 99 | { | ||
| 100 | struct clk_notifier_data *cnd = data; | ||
| 101 | |||
| 102 | if (action == POST_RATE_CHANGE) | ||
| 103 | on_each_cpu(gic_update_frequency, (void *)cnd->new_rate, 1); | ||
| 104 | |||
| 105 | return NOTIFY_OK; | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 90 | static struct notifier_block gic_cpu_nb = { | 109 | static struct notifier_block gic_cpu_nb = { |
| 91 | .notifier_call = gic_cpu_notifier, | 110 | .notifier_call = gic_cpu_notifier, |
| 92 | }; | 111 | }; |
| 93 | 112 | ||
| 113 | static struct notifier_block gic_clk_nb = { | ||
| 114 | .notifier_call = gic_clk_notifier, | ||
| 115 | }; | ||
| 116 | |||
| 94 | static int gic_clockevent_init(void) | 117 | static int gic_clockevent_init(void) |
| 95 | { | 118 | { |
| 119 | int ret; | ||
| 120 | |||
| 96 | if (!cpu_has_counter || !gic_frequency) | 121 | if (!cpu_has_counter || !gic_frequency) |
| 97 | return -ENXIO; | 122 | return -ENXIO; |
| 98 | 123 | ||
| 99 | setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction); | 124 | ret = setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction); |
| 125 | if (ret < 0) | ||
| 126 | return ret; | ||
| 100 | 127 | ||
| 101 | register_cpu_notifier(&gic_cpu_nb); | 128 | ret = register_cpu_notifier(&gic_cpu_nb); |
| 129 | if (ret < 0) | ||
| 130 | pr_warn("GIC: Unable to register CPU notifier\n"); | ||
| 102 | 131 | ||
| 103 | gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device)); | 132 | gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device)); |
| 104 | 133 | ||
| @@ -118,18 +147,17 @@ static struct clocksource gic_clocksource = { | |||
| 118 | 147 | ||
| 119 | static void __init __gic_clocksource_init(void) | 148 | static void __init __gic_clocksource_init(void) |
| 120 | { | 149 | { |
| 150 | int ret; | ||
| 151 | |||
| 121 | /* Set clocksource mask. */ | 152 | /* Set clocksource mask. */ |
| 122 | gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); | 153 | gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); |
| 123 | 154 | ||
| 124 | /* Calculate a somewhat reasonable rating value. */ | 155 | /* Calculate a somewhat reasonable rating value. */ |
| 125 | gic_clocksource.rating = 200 + gic_frequency / 10000000; | 156 | gic_clocksource.rating = 200 + gic_frequency / 10000000; |
| 126 | 157 | ||
| 127 | clocksource_register_hz(&gic_clocksource, gic_frequency); | 158 | ret = clocksource_register_hz(&gic_clocksource, gic_frequency); |
| 128 | 159 | if (ret < 0) | |
| 129 | gic_clockevent_init(); | 160 | pr_warn("GIC: Unable to register clocksource\n"); |
| 130 | |||
| 131 | /* And finally start the counter */ | ||
| 132 | gic_start_count(); | ||
| 133 | } | 161 | } |
| 134 | 162 | ||
| 135 | void __init gic_clocksource_init(unsigned int frequency) | 163 | void __init gic_clocksource_init(unsigned int frequency) |
| @@ -139,11 +167,16 @@ void __init gic_clocksource_init(unsigned int frequency) | |||
| 139 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); | 167 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); |
| 140 | 168 | ||
| 141 | __gic_clocksource_init(); | 169 | __gic_clocksource_init(); |
| 170 | gic_clockevent_init(); | ||
| 171 | |||
| 172 | /* And finally start the counter */ | ||
| 173 | gic_start_count(); | ||
| 142 | } | 174 | } |
| 143 | 175 | ||
| 144 | static void __init gic_clocksource_of_init(struct device_node *node) | 176 | static void __init gic_clocksource_of_init(struct device_node *node) |
| 145 | { | 177 | { |
| 146 | struct clk *clk; | 178 | struct clk *clk; |
| 179 | int ret; | ||
| 147 | 180 | ||
| 148 | if (WARN_ON(!gic_present || !node->parent || | 181 | if (WARN_ON(!gic_present || !node->parent || |
| 149 | !of_device_is_compatible(node->parent, "mti,gic"))) | 182 | !of_device_is_compatible(node->parent, "mti,gic"))) |
| @@ -151,8 +184,13 @@ static void __init gic_clocksource_of_init(struct device_node *node) | |||
| 151 | 184 | ||
| 152 | clk = of_clk_get(node, 0); | 185 | clk = of_clk_get(node, 0); |
| 153 | if (!IS_ERR(clk)) { | 186 | if (!IS_ERR(clk)) { |
| 187 | if (clk_prepare_enable(clk) < 0) { | ||
| 188 | pr_err("GIC failed to enable clock\n"); | ||
| 189 | clk_put(clk); | ||
| 190 | return; | ||
| 191 | } | ||
| 192 | |||
| 154 | gic_frequency = clk_get_rate(clk); | 193 | gic_frequency = clk_get_rate(clk); |
| 155 | clk_put(clk); | ||
| 156 | } else if (of_property_read_u32(node, "clock-frequency", | 194 | } else if (of_property_read_u32(node, "clock-frequency", |
| 157 | &gic_frequency)) { | 195 | &gic_frequency)) { |
| 158 | pr_err("GIC frequency not specified.\n"); | 196 | pr_err("GIC frequency not specified.\n"); |
| @@ -165,6 +203,15 @@ static void __init gic_clocksource_of_init(struct device_node *node) | |||
| 165 | } | 203 | } |
| 166 | 204 | ||
| 167 | __gic_clocksource_init(); | 205 | __gic_clocksource_init(); |
| 206 | |||
| 207 | ret = gic_clockevent_init(); | ||
| 208 | if (!ret && !IS_ERR(clk)) { | ||
| 209 | if (clk_notifier_register(clk, &gic_clk_nb) < 0) | ||
| 210 | pr_warn("GIC: Unable to register clock notifier\n"); | ||
| 211 | } | ||
| 212 | |||
| 213 | /* And finally start the counter */ | ||
| 214 | gic_start_count(); | ||
| 168 | } | 215 | } |
| 169 | CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer", | 216 | CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer", |
| 170 | gic_clocksource_of_init); | 217 | gic_clocksource_of_init); |
