Skip to content

Commit b9e763c

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull sparc fixes from David Miller: "Various sparc bug fixes, in particular: 1) TSB hashes have to be flushed before TLB on sparc64, from Dave Kleikamp. 2) LEON timer interrupts can get stuck, from Andreas Larsson. 3) Sparc64 needs to handle lack of address-congruence devicetree property, from Bob Picco" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc: sparc: tsb must be flushed before tlb sparc,leon: Convert to use devm_ioremap_resource sparc64 address-congruence property sparc32, leon: Enable interrupts before going idle to avoid getting stuck sparc32, leon: Remove separate "ticker" timer for SMP sparc: kernel: using strlcpy() instead of strcpy() arch: sparc: prom: looping issue, need additional length check in the outside looping sparc: remove inline marking of EXPORT_SYMBOL functions sparc: Switch to asm-generic/linkage.h
2 parents aa4927b + 23a0113 commit b9e763c

File tree

14 files changed

+58
-67
lines changed

14 files changed

+58
-67
lines changed

arch/sparc/include/asm/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ generic-y += cputime.h
66
generic-y += div64.h
77
generic-y += emergency-restart.h
88
generic-y += exec.h
9+
generic-y += linkage.h
910
generic-y += local64.h
1011
generic-y += mutex.h
1112
generic-y += irq_regs.h

arch/sparc/include/asm/leon.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static inline int sparc_leon3_cpuid(void)
135135

136136
#ifdef CONFIG_SMP
137137
# define LEON3_IRQ_IPI_DEFAULT13
138-
# define LEON3_IRQ_TICKER(leon3_ticker_irq)
138+
# define LEON3_IRQ_TICKER(leon3_gptimer_irq)
139139
# define LEON3_IRQ_CROSS_CALL15
140140
#endif
141141

arch/sparc/include/asm/leon_amba.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct amba_prom_registers {
4747
#define LEON3_GPTIMER_LD 4
4848
#define LEON3_GPTIMER_IRQEN 8
4949
#define LEON3_GPTIMER_SEPIRQ 8
50+
#define LEON3_GPTIMER_TIMERS 0x7
5051

5152
#define LEON23_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */
5253
/* 0 = hold scalar and counter */

arch/sparc/include/asm/linkage.h

Lines changed: 0 additions & 6 deletions
This file was deleted.

arch/sparc/kernel/ds.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,8 @@ void ldom_reboot(const char *boot_command)
843843
unsigned long len;
844844

845845
strcpy(full_boot_str, "boot ");
846-
strcpy(full_boot_str + strlen("boot "), boot_command);
846+
strlcpy(full_boot_str + strlen("boot "), boot_command,
847+
sizeof(full_boot_str + strlen("boot ")));
847848
len = strlen(full_boot_str);
848849

849850
if (reboot_data_supported) {

arch/sparc/kernel/leon_kernel.c

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ static DEFINE_SPINLOCK(leon_irq_lock);
3838

3939
unsigned long leon3_gptimer_irq; /* interrupt controller irq number */
4040
unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */
41-
int leon3_ticker_irq; /* Timer ticker IRQ */
4241
unsigned int sparc_leon_eirq;
4342
#define LEON_IMASK(cpu) (&leon3_irqctrl_regs->mask[cpu])
4443
#define LEON_IACK (&leon3_irqctrl_regs->iclear)
@@ -278,6 +277,9 @@ irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused)
278277

279278
leon_clear_profile_irq(cpu);
280279

280+
if (cpu == boot_cpu_id)
281+
timer_interrupt(irq, NULL);
282+
281283
ce = &per_cpu(sparc32_clockevent, cpu);
282284

283285
irq_enter();
@@ -299,6 +301,7 @@ void __init leon_init_timers(void)
299301
int icsel;
300302
int ampopts;
301303
int err;
304+
u32 config;
302305

303306
sparc_config.get_cycles_offset = leon_cycles_offset;
304307
sparc_config.cs_period = 1000000 / HZ;
@@ -377,23 +380,6 @@ void __init leon_init_timers(void)
377380
LEON3_BYPASS_STORE_PA(
378381
&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
379382

380-
#ifdef CONFIG_SMP
381-
leon3_ticker_irq = leon3_gptimer_irq + 1 + leon3_gptimer_idx;
382-
383-
if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
384-
(1<<LEON3_GPTIMER_SEPIRQ))) {
385-
printk(KERN_ERR "timer not configured with separate irqs\n");
386-
BUG();
387-
}
388-
389-
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val,
390-
0);
391-
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld,
392-
(((1000000/HZ) - 1)));
393-
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
394-
0);
395-
#endif
396-
397383
/*
398384
* The IRQ controller may (if implemented) consist of multiple
399385
* IRQ controllers, each mapped on a 4Kb boundary.
@@ -416,13 +402,6 @@ void __init leon_init_timers(void)
416402
if (eirq != 0)
417403
leon_eirq_setup(eirq);
418404

419-
irq = _leon_build_device_irq(NULL, leon3_gptimer_irq+leon3_gptimer_idx);
420-
err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
421-
if (err) {
422-
printk(KERN_ERR "unable to attach timer IRQ%d\n", irq);
423-
prom_halt();
424-
}
425-
426405
#ifdef CONFIG_SMP
427406
{
428407
unsigned long flags;
@@ -439,30 +418,31 @@ void __init leon_init_timers(void)
439418
}
440419
#endif
441420

442-
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
443-
LEON3_GPTIMER_EN |
444-
LEON3_GPTIMER_RL |
445-
LEON3_GPTIMER_LD |
446-
LEON3_GPTIMER_IRQEN);
421+
config = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config);
422+
if (config & (1 << LEON3_GPTIMER_SEPIRQ))
423+
leon3_gptimer_irq += leon3_gptimer_idx;
424+
else if ((config & LEON3_GPTIMER_TIMERS) > 1)
425+
pr_warn("GPTIMER uses shared irqs, using other timers of the same core will fail.\n");
447426

448427
#ifdef CONFIG_SMP
449428
/* Install per-cpu IRQ handler for broadcasted ticker */
450-
irq = leon_build_device_irq(leon3_ticker_irq, handle_percpu_irq,
429+
irq = leon_build_device_irq(leon3_gptimer_irq, handle_percpu_irq,
451430
"per-cpu", 0);
452431
err = request_irq(irq, leon_percpu_timer_ce_interrupt,
453-
IRQF_PERCPU | IRQF_TIMER, "ticker",
454-
NULL);
432+
IRQF_PERCPU | IRQF_TIMER, "timer", NULL);
433+
#else
434+
irq = _leon_build_device_irq(NULL, leon3_gptimer_irq);
435+
err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
436+
#endif
455437
if (err) {
456-
printk(KERN_ERR "unable to attach ticker IRQ%d\n", irq);
438+
pr_err("Unable to attach timer IRQ%d\n", irq);
457439
prom_halt();
458440
}
459-
460-
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
441+
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
461442
LEON3_GPTIMER_EN |
462443
LEON3_GPTIMER_RL |
463444
LEON3_GPTIMER_LD |
464445
LEON3_GPTIMER_IRQEN);
465-
#endif
466446
return;
467447
bad:
468448
printk(KERN_ERR "No Timer/irqctrl found\n");

arch/sparc/kernel/leon_pci_grpci1.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -536,11 +536,9 @@ static int grpci1_of_probe(struct platform_device *ofdev)
536536

537537
/* find device register base address */
538538
res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
539-
regs = devm_request_and_ioremap(&ofdev->dev, res);
540-
if (!regs) {
541-
dev_err(&ofdev->dev, "io-regs mapping failed\n");
542-
return -EADDRNOTAVAIL;
543-
}
539+
regs = devm_ioremap_resource(&ofdev->dev, res);
540+
if (IS_ERR(regs))
541+
return PTR_ERR(regs);
544542

545543
/*
546544
* check that we're in Host Slot and that we can act as a Host Bridge

arch/sparc/kernel/leon_pmc.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ void pmc_leon_idle_fixup(void)
4747
* MMU does not get a TLB miss here by using the MMU BYPASS ASI.
4848
*/
4949
register unsigned int address = (unsigned int)leon3_irqctrl_regs;
50+
51+
/* Interrupts need to be enabled to not hang the CPU */
52+
local_irq_enable();
53+
5054
__asm__ __volatile__ (
5155
"wr %%g0, %%asr19\n"
5256
"lda [%0] %1, %%g0\n"
@@ -60,6 +64,9 @@ void pmc_leon_idle_fixup(void)
6064
*/
6165
void pmc_leon_idle(void)
6266
{
67+
/* Interrupts need to be enabled to not hang the CPU */
68+
local_irq_enable();
69+
6370
/* For systems without power-down, this will be no-op */
6471
__asm__ __volatile__ ("wr %g0, %asr19\n\t");
6572
}

arch/sparc/kernel/setup_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p)
304304

305305
/* Initialize PROM console and command line. */
306306
*cmdline_p = prom_getbootargs();
307-
strcpy(boot_command_line, *cmdline_p);
307+
strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
308308
parse_early_param();
309309

310310
boot_flags_init(*cmdline_p);

arch/sparc/kernel/setup_64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ void __init setup_arch(char **cmdline_p)
555555
{
556556
/* Initialize PROM console and command line. */
557557
*cmdline_p = prom_getbootargs();
558-
strcpy(boot_command_line, *cmdline_p);
558+
strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
559559
parse_early_param();
560560

561561
boot_flags_init(*cmdline_p);

0 commit comments

Comments
 (0)