summaryrefslogtreecommitdiff
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/include/asm/Kbuild1
-rw-r--r--arch/sparc/include/asm/leon.h2
-rw-r--r--arch/sparc/include/asm/leon_amba.h1
-rw-r--r--arch/sparc/include/asm/linkage.h6
-rw-r--r--arch/sparc/kernel/ds.c3
-rw-r--r--arch/sparc/kernel/leon_kernel.c54
-rw-r--r--arch/sparc/kernel/leon_pci_grpci1.c8
-rw-r--r--arch/sparc/kernel/leon_pmc.c7
-rw-r--r--arch/sparc/kernel/prom_common.c5
-rw-r--r--arch/sparc/kernel/setup_32.c2
-rw-r--r--arch/sparc/kernel/setup_64.c2
-rw-r--r--arch/sparc/mm/init_64.c9
-rw-r--r--arch/sparc/mm/tlb.c2
-rw-r--r--arch/sparc/prom/bootstr_32.c12
-rw-r--r--arch/sparc/prom/tree_64.c16
15 files changed, 61 insertions, 69 deletions
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index ff18e3cfb6b1..7e4a97fbded4 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -6,6 +6,7 @@ generic-y += cputime.h
generic-y += div64.h
generic-y += emergency-restart.h
generic-y += exec.h
+generic-y += linkage.h
generic-y += local64.h
generic-y += mutex.h
generic-y += irq_regs.h
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h
index 15a716934e4d..b836e9297f2a 100644
--- a/arch/sparc/include/asm/leon.h
+++ b/arch/sparc/include/asm/leon.h
@@ -135,7 +135,7 @@ static inline int sparc_leon3_cpuid(void)
#ifdef CONFIG_SMP
# define LEON3_IRQ_IPI_DEFAULT 13
-# define LEON3_IRQ_TICKER (leon3_ticker_irq)
+# define LEON3_IRQ_TICKER (leon3_gptimer_irq)
# define LEON3_IRQ_CROSS_CALL 15
#endif
diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h
index f3034eddf468..24ec48c3ff90 100644
--- a/arch/sparc/include/asm/leon_amba.h
+++ b/arch/sparc/include/asm/leon_amba.h
@@ -47,6 +47,7 @@ struct amba_prom_registers {
#define LEON3_GPTIMER_LD 4
#define LEON3_GPTIMER_IRQEN 8
#define LEON3_GPTIMER_SEPIRQ 8
+#define LEON3_GPTIMER_TIMERS 0x7
#define LEON23_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */
/* 0 = hold scalar and counter */
diff --git a/arch/sparc/include/asm/linkage.h b/arch/sparc/include/asm/linkage.h
deleted file mode 100644
index 291c2d01c44f..000000000000
--- a/arch/sparc/include/asm/linkage.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_LINKAGE_H
-#define __ASM_LINKAGE_H
-
-/* Nothing to see here... */
-
-#endif
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index 75bb608c423e..5ef48dab5636 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -843,7 +843,8 @@ void ldom_reboot(const char *boot_command)
unsigned long len;
strcpy(full_boot_str, "boot ");
- strcpy(full_boot_str + strlen("boot "), boot_command);
+ strlcpy(full_boot_str + strlen("boot "), boot_command,
+ sizeof(full_boot_str + strlen("boot ")));
len = strlen(full_boot_str);
if (reboot_data_supported) {
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 7c0231dabe44..b7c68976cbc7 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -38,7 +38,6 @@ static DEFINE_SPINLOCK(leon_irq_lock);
unsigned long leon3_gptimer_irq; /* interrupt controller irq number */
unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */
-int leon3_ticker_irq; /* Timer ticker IRQ */
unsigned int sparc_leon_eirq;
#define LEON_IMASK(cpu) (&leon3_irqctrl_regs->mask[cpu])
#define LEON_IACK (&leon3_irqctrl_regs->iclear)
@@ -278,6 +277,9 @@ irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused)
leon_clear_profile_irq(cpu);
+ if (cpu == boot_cpu_id)
+ timer_interrupt(irq, NULL);
+
ce = &per_cpu(sparc32_clockevent, cpu);
irq_enter();
@@ -299,6 +301,7 @@ void __init leon_init_timers(void)
int icsel;
int ampopts;
int err;
+ u32 config;
sparc_config.get_cycles_offset = leon_cycles_offset;
sparc_config.cs_period = 1000000 / HZ;
@@ -377,23 +380,6 @@ void __init leon_init_timers(void)
LEON3_BYPASS_STORE_PA(
&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
-#ifdef CONFIG_SMP
- leon3_ticker_irq = leon3_gptimer_irq + 1 + leon3_gptimer_idx;
-
- if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
- (1<<LEON3_GPTIMER_SEPIRQ))) {
- printk(KERN_ERR "timer not configured with separate irqs\n");
- BUG();
- }
-
- LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val,
- 0);
- LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld,
- (((1000000/HZ) - 1)));
- LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
- 0);
-#endif
-
/*
* The IRQ controller may (if implemented) consist of multiple
* IRQ controllers, each mapped on a 4Kb boundary.
@@ -416,13 +402,6 @@ void __init leon_init_timers(void)
if (eirq != 0)
leon_eirq_setup(eirq);
- irq = _leon_build_device_irq(NULL, leon3_gptimer_irq+leon3_gptimer_idx);
- err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
- if (err) {
- printk(KERN_ERR "unable to attach timer IRQ%d\n", irq);
- prom_halt();
- }
-
#ifdef CONFIG_SMP
{
unsigned long flags;
@@ -439,30 +418,31 @@ void __init leon_init_timers(void)
}
#endif
- LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
- LEON3_GPTIMER_EN |
- LEON3_GPTIMER_RL |
- LEON3_GPTIMER_LD |
- LEON3_GPTIMER_IRQEN);
+ config = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config);
+ if (config & (1 << LEON3_GPTIMER_SEPIRQ))
+ leon3_gptimer_irq += leon3_gptimer_idx;
+ else if ((config & LEON3_GPTIMER_TIMERS) > 1)
+ pr_warn("GPTIMER uses shared irqs, using other timers of the same core will fail.\n");
#ifdef CONFIG_SMP
/* Install per-cpu IRQ handler for broadcasted ticker */
- irq = leon_build_device_irq(leon3_ticker_irq, handle_percpu_irq,
+ irq = leon_build_device_irq(leon3_gptimer_irq, handle_percpu_irq,
"per-cpu", 0);
err = request_irq(irq, leon_percpu_timer_ce_interrupt,
- IRQF_PERCPU | IRQF_TIMER, "ticker",
- NULL);
+ IRQF_PERCPU | IRQF_TIMER, "timer", NULL);
+#else
+ irq = _leon_build_device_irq(NULL, leon3_gptimer_irq);
+ err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
+#endif
if (err) {
- printk(KERN_ERR "unable to attach ticker IRQ%d\n", irq);
+ pr_err("Unable to attach timer IRQ%d\n", irq);
prom_halt();
}
-
- LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
+ LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
LEON3_GPTIMER_EN |
LEON3_GPTIMER_RL |
LEON3_GPTIMER_LD |
LEON3_GPTIMER_IRQEN);
-#endif
return;
bad:
printk(KERN_ERR "No Timer/irqctrl found\n");
diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c
index 7739a54315e2..6df26e37f879 100644
--- a/arch/sparc/kernel/leon_pci_grpci1.c
+++ b/arch/sparc/kernel/leon_pci_grpci1.c
@@ -536,11 +536,9 @@ static int grpci1_of_probe(struct platform_device *ofdev)
/* find device register base address */
res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
- regs = devm_request_and_ioremap(&ofdev->dev, res);
- if (!regs) {
- dev_err(&ofdev->dev, "io-regs mapping failed\n");
- return -EADDRNOTAVAIL;
- }
+ regs = devm_ioremap_resource(&ofdev->dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
/*
* check that we're in Host Slot and that we can act as a Host Bridge
diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c
index bdf53d9a8d46..b0b3967a2dd2 100644
--- a/arch/sparc/kernel/leon_pmc.c
+++ b/arch/sparc/kernel/leon_pmc.c
@@ -47,6 +47,10 @@ void pmc_leon_idle_fixup(void)
* MMU does not get a TLB miss here by using the MMU BYPASS ASI.
*/
register unsigned int address = (unsigned int)leon3_irqctrl_regs;
+
+ /* Interrupts need to be enabled to not hang the CPU */
+ local_irq_enable();
+
__asm__ __volatile__ (
"wr %%g0, %%asr19\n"
"lda [%0] %1, %%g0\n"
@@ -60,6 +64,9 @@ void pmc_leon_idle_fixup(void)
*/
void pmc_leon_idle(void)
{
+ /* Interrupts need to be enabled to not hang the CPU */
+ local_irq_enable();
+
/* For systems without power-down, this will be no-op */
__asm__ __volatile__ ("wr %g0, %asr19\n\t");
}
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 9f20566b0773..79cc0d1a477d 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -54,6 +54,7 @@ EXPORT_SYMBOL(of_set_property_mutex);
int of_set_property(struct device_node *dp, const char *name, void *val, int len)
{
struct property **prevp;
+ unsigned long flags;
void *new_val;
int err;
@@ -64,7 +65,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
err = -ENODEV;
mutex_lock(&of_set_property_mutex);
- raw_spin_lock(&devtree_lock);
+ raw_spin_lock_irqsave(&devtree_lock, flags);
prevp = &dp->properties;
while (*prevp) {
struct property *prop = *prevp;
@@ -91,7 +92,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
}
prevp = &(*prevp)->next;
}
- raw_spin_unlock(&devtree_lock);
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
mutex_unlock(&of_set_property_mutex);
/* XXX Upate procfs if necessary... */
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index 38bf80a22f02..1434526970a6 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p)
/* Initialize PROM console and command line. */
*cmdline_p = prom_getbootargs();
- strcpy(boot_command_line, *cmdline_p);
+ strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
parse_early_param();
boot_flags_init(*cmdline_p);
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 88a127b9c69e..13785547e435 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -555,7 +555,7 @@ void __init setup_arch(char **cmdline_p)
{
/* Initialize PROM console and command line. */
*cmdline_p = prom_getbootargs();
- strcpy(boot_command_line, *cmdline_p);
+ strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
parse_early_param();
boot_flags_init(*cmdline_p);
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index a7171997adfd..04fd55a6e461 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1098,7 +1098,14 @@ static int __init grab_mblocks(struct mdesc_handle *md)
m->size = *val;
val = mdesc_get_property(md, node,
"address-congruence-offset", NULL);
- m->offset = *val;
+
+ /* The address-congruence-offset property is optional.
+ * Explicity zero it be identifty this.
+ */
+ if (val)
+ m->offset = *val;
+ else
+ m->offset = 0UL;
numadbg("MBLOCK[%d]: base[%llx] size[%llx] offset[%llx]\n",
count - 1, m->base, m->size, m->offset);
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index 83d89bcb44af..37e7bc4c95b3 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -85,8 +85,8 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
}
if (!tb->active) {
- global_flush_tlb_page(mm, vaddr);
flush_tsb_user_page(mm, vaddr);
+ global_flush_tlb_page(mm, vaddr);
goto out;
}
diff --git a/arch/sparc/prom/bootstr_32.c b/arch/sparc/prom/bootstr_32.c
index f5ec32e0d419..d2b49d2365e7 100644
--- a/arch/sparc/prom/bootstr_32.c
+++ b/arch/sparc/prom/bootstr_32.c
@@ -23,23 +23,25 @@ prom_getbootargs(void)
return barg_buf;
}
- switch(prom_vers) {
+ switch (prom_vers) {
case PROM_V0:
cp = barg_buf;
/* Start from 1 and go over fd(0,0,0)kernel */
- for(iter = 1; iter < 8; iter++) {
+ for (iter = 1; iter < 8; iter++) {
arg = (*(romvec->pv_v0bootargs))->argv[iter];
if (arg == NULL)
break;
- while(*arg != 0) {
+ while (*arg != 0) {
/* Leave place for space and null. */
- if(cp >= barg_buf + BARG_LEN-2){
+ if (cp >= barg_buf + BARG_LEN - 2)
/* We might issue a warning here. */
break;
- }
*cp++ = *arg++;
}
*cp++ = ' ';
+ if (cp >= barg_buf + BARG_LEN - 1)
+ /* We might issue a warning here. */
+ break;
}
*cp = 0;
break;
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c
index 92204c3800b5..bd1b2a3ac34e 100644
--- a/arch/sparc/prom/tree_64.c
+++ b/arch/sparc/prom/tree_64.c
@@ -39,7 +39,7 @@ inline phandle __prom_getchild(phandle node)
return prom_node_to_node("child", node);
}
-inline phandle prom_getchild(phandle node)
+phandle prom_getchild(phandle node)
{
phandle cnode;
@@ -72,7 +72,7 @@ inline phandle __prom_getsibling(phandle node)
return prom_node_to_node(prom_peer_name, node);
}
-inline phandle prom_getsibling(phandle node)
+phandle prom_getsibling(phandle node)
{
phandle sibnode;
@@ -89,7 +89,7 @@ EXPORT_SYMBOL(prom_getsibling);
/* Return the length in bytes of property 'prop' at node 'node'.
* Return -1 on error.
*/
-inline int prom_getproplen(phandle node, const char *prop)
+int prom_getproplen(phandle node, const char *prop)
{
unsigned long args[6];
@@ -113,8 +113,8 @@ EXPORT_SYMBOL(prom_getproplen);
* 'buffer' which has a size of 'bufsize'. If the acquisition
* was successful the length will be returned, else -1 is returned.
*/
-inline int prom_getproperty(phandle node, const char *prop,
- char *buffer, int bufsize)
+int prom_getproperty(phandle node, const char *prop,
+ char *buffer, int bufsize)
{
unsigned long args[8];
int plen;
@@ -141,7 +141,7 @@ EXPORT_SYMBOL(prom_getproperty);
/* Acquire an integer property and return its value. Returns -1
* on failure.
*/
-inline int prom_getint(phandle node, const char *prop)
+int prom_getint(phandle node, const char *prop)
{
int intprop;
@@ -235,7 +235,7 @@ static const char *prom_nextprop_name = "nextprop";
/* Return the first property type for node 'node'.
* buffer should be at least 32B in length
*/
-inline char *prom_firstprop(phandle node, char *buffer)
+char *prom_firstprop(phandle node, char *buffer)
{
unsigned long args[7];
@@ -261,7 +261,7 @@ EXPORT_SYMBOL(prom_firstprop);
* at node 'node' . Returns NULL string if no more
* property types for this node.
*/
-inline char *prom_nextprop(phandle node, const char *oprop, char *buffer)
+char *prom_nextprop(phandle node, const char *oprop, char *buffer)
{
unsigned long args[7];
char buf[32];