Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
3f371438
Commit
3f371438
authored
Jan 12, 2005
by
Russell King
Browse files
Options
Browse Files
Download
Plain Diff
Merge flint.arm.linux.org.uk:/usr/src/bk/linux-2.6-smp
into flint.arm.linux.org.uk:/usr/src/bk/linux-2.6-rmk
parents
08432e0e
d4118bd6
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
157 additions
and
14 deletions
+157
-14
arch/arm/kernel/irq.c
arch/arm/kernel/irq.c
+126
-3
arch/arm/kernel/smp.c
arch/arm/kernel/smp.c
+10
-10
include/asm-arm/cpu.h
include/asm-arm/cpu.h
+0
-1
include/asm-arm/mach/irq.h
include/asm-arm/mach/irq.h
+14
-0
include/asm-arm/smp.h
include/asm-arm/smp.h
+7
-0
No files found.
arch/arm/kernel/irq.c
View file @
3f371438
...
...
@@ -32,6 +32,7 @@
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/kallsyms.h>
#include <linux/proc_fs.h>
#include <asm/irq.h>
#include <asm/system.h>
...
...
@@ -85,6 +86,23 @@ static struct irqdesc bad_irq_desc = {
.
disable_depth
=
1
,
};
#ifdef CONFIG_SMP
void
synchronize_irq
(
unsigned
int
irq
)
{
struct
irqdesc
*
desc
=
irq_desc
+
irq
;
while
(
desc
->
running
)
barrier
();
}
EXPORT_SYMBOL
(
synchronize_irq
);
#define smp_set_running(desc) do { desc->running = 1; } while (0)
#define smp_clear_running(desc) do { desc->running = 0; } while (0)
#else
#define smp_set_running(desc) do { } while (0)
#define smp_clear_running(desc) do { } while (0)
#endif
/**
* disable_irq_nosync - disable an irq without waiting
* @irq: Interrupt to disable
...
...
@@ -231,6 +249,9 @@ int show_interrupts(struct seq_file *p, void *v)
}
else
if
(
i
==
NR_IRQS
)
{
#ifdef CONFIG_ARCH_ACORN
show_fiq_list
(
p
,
v
);
#endif
#ifdef CONFIG_SMP
show_ipi_list
(
p
);
#endif
seq_printf
(
p
,
"Err: %10lu
\n
"
,
irq_err_count
);
}
...
...
@@ -329,18 +350,22 @@ void
do_simple_IRQ
(
unsigned
int
irq
,
struct
irqdesc
*
desc
,
struct
pt_regs
*
regs
)
{
struct
irqaction
*
action
;
const
int
cpu
=
smp_processor_id
();
const
unsigned
int
cpu
=
smp_processor_id
();
desc
->
triggered
=
1
;
kstat_cpu
(
cpu
).
irqs
[
irq
]
++
;
smp_set_running
(
desc
);
action
=
desc
->
action
;
if
(
action
)
{
int
ret
=
__do_irq
(
irq
,
action
,
regs
);
if
(
ret
!=
IRQ_HANDLED
)
report_bad_irq
(
irq
,
regs
,
desc
,
ret
);
}
smp_clear_running
(
desc
);
}
/*
...
...
@@ -350,7 +375,7 @@ do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
void
do_edge_IRQ
(
unsigned
int
irq
,
struct
irqdesc
*
desc
,
struct
pt_regs
*
regs
)
{
const
int
cpu
=
smp_processor_id
();
const
unsigned
int
cpu
=
smp_processor_id
();
desc
->
triggered
=
1
;
...
...
@@ -414,7 +439,7 @@ void
do_level_IRQ
(
unsigned
int
irq
,
struct
irqdesc
*
desc
,
struct
pt_regs
*
regs
)
{
struct
irqaction
*
action
;
const
int
cpu
=
smp_processor_id
();
const
unsigned
int
cpu
=
smp_processor_id
();
desc
->
triggered
=
1
;
...
...
@@ -426,6 +451,8 @@ do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
if
(
likely
(
!
desc
->
disable_depth
))
{
kstat_cpu
(
cpu
).
irqs
[
irq
]
++
;
smp_set_running
(
desc
);
/*
* Return with this interrupt masked if no action
*/
...
...
@@ -440,6 +467,8 @@ do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
!
check_irq_lock
(
desc
,
irq
,
regs
)))
desc
->
chip
->
unmask
(
irq
);
}
smp_clear_running
(
desc
);
}
}
...
...
@@ -878,8 +907,97 @@ int probe_irq_off(unsigned long irqs)
EXPORT_SYMBOL
(
probe_irq_off
);
#ifdef CONFIG_SMP
static
void
route_irq
(
struct
irqdesc
*
desc
,
unsigned
int
irq
,
unsigned
int
cpu
)
{
pr_debug
(
"IRQ%u: moving from cpu%u to cpu%u
\n
"
,
irq
,
desc
->
cpu
,
cpu
);
spin_lock_irq
(
&
irq_controller_lock
);
desc
->
cpu
=
cpu
;
desc
->
chip
->
set_cpu
(
desc
,
irq
,
cpu
);
spin_unlock_irq
(
&
irq_controller_lock
);
}
#ifdef CONFIG_PROC_FS
static
int
irq_affinity_read_proc
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
irqdesc
*
desc
=
irq_desc
+
((
int
)
data
);
int
len
=
cpumask_scnprintf
(
page
,
count
,
desc
->
affinity
);
if
(
count
-
len
<
2
)
return
-
EINVAL
;
page
[
len
++
]
=
'\n'
;
page
[
len
]
=
'\0'
;
return
len
;
}
static
int
irq_affinity_write_proc
(
struct
file
*
file
,
const
char
__user
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
unsigned
int
irq
=
(
unsigned
int
)
data
;
struct
irqdesc
*
desc
=
irq_desc
+
irq
;
cpumask_t
affinity
,
tmp
;
int
ret
=
-
EIO
;
if
(
!
desc
->
chip
->
set_cpu
)
goto
out
;
ret
=
cpumask_parse
(
buffer
,
count
,
affinity
);
if
(
ret
)
goto
out
;
cpus_and
(
tmp
,
affinity
,
cpu_online_map
);
if
(
cpus_empty
(
tmp
))
{
ret
=
-
EINVAL
;
goto
out
;
}
desc
->
affinity
=
affinity
;
route_irq
(
desc
,
irq
,
first_cpu
(
tmp
));
ret
=
count
;
out:
return
ret
;
}
#endif
#endif
void
__init
init_irq_proc
(
void
)
{
#if defined(CONFIG_SMP) && defined(CONFIG_PROC_FS)
struct
proc_dir_entry
*
dir
;
int
irq
;
dir
=
proc_mkdir
(
"irq"
,
0
);
if
(
!
dir
)
return
;
for
(
irq
=
0
;
irq
<
NR_IRQS
;
irq
++
)
{
struct
proc_dir_entry
*
entry
;
struct
irqdesc
*
desc
;
char
name
[
16
];
desc
=
irq_desc
+
irq
;
memset
(
name
,
0
,
sizeof
(
name
));
snprintf
(
name
,
sizeof
(
name
)
-
1
,
"%u"
,
irq
);
desc
->
procdir
=
proc_mkdir
(
name
,
dir
);
if
(
!
desc
->
procdir
)
continue
;
entry
=
create_proc_entry
(
"smp_affinity"
,
0600
,
desc
->
procdir
);
if
(
entry
)
{
entry
->
nlink
=
1
;
entry
->
data
=
(
void
*
)
irq
;
entry
->
read_proc
=
irq_affinity_read_proc
;
entry
->
write_proc
=
irq_affinity_write_proc
;
}
}
#endif
}
void
__init
init_IRQ
(
void
)
...
...
@@ -888,6 +1006,11 @@ void __init init_IRQ(void)
extern
void
init_dma
(
void
);
int
irq
;
#ifdef CONFIG_SMP
bad_irq_desc
.
affinity
=
CPU_MASK_ALL
;
bad_irq_desc
.
cpu
=
smp_processor_id
();
#endif
for
(
irq
=
0
,
desc
=
irq_desc
;
irq
<
NR_IRQS
;
irq
++
,
desc
++
)
{
*
desc
=
bad_irq_desc
;
INIT_LIST_HEAD
(
&
desc
->
pend
);
...
...
arch/arm/kernel/smp.c
View file @
3f371438
...
...
@@ -17,16 +17,16 @@
#include <linux/profile.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/cpu.h>
#include <linux/smp.h>
#include <linux/seq_file.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
#include <asm/cpu.h>
#include <asm/processor.h>
#include <asm/smp.h>
#include <asm/ptrace.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
/*
* bitmask of present and online CPUs.
...
...
@@ -42,6 +42,7 @@ cpumask_t cpu_online_map;
*/
struct
ipi_data
{
spinlock_t
lock
;
unsigned
long
ipi_count
;
unsigned
long
bits
;
};
...
...
@@ -242,12 +243,12 @@ int smp_call_function(void (*func)(void *info), void *info, int retry,
void
show_ipi_list
(
struct
seq_file
*
p
)
{
int
cpu
;
unsigned
int
cpu
;
seq_p
rintf
(
p
,
"IPI:
"
);
seq_p
uts
(
p
,
"IPI:
"
);
for_each_online_cpu
(
cpu
)
seq_printf
(
p
,
"
%10lu "
,
per_cpu
(
cpu
_data
,
cpu
).
ipi_count
);
seq_printf
(
p
,
"
%10lu"
,
per_cpu
(
ipi
_data
,
cpu
).
ipi_count
);
seq_putc
(
p
,
'\n'
);
}
...
...
@@ -316,12 +317,11 @@ static void ipi_cpu_stop(unsigned int cpu)
void
do_IPI
(
unsigned
int
ipimask
,
struct
pt_regs
*
regs
)
{
unsigned
int
cpu
=
smp_processor_id
();
struct
ipi_data
*
ipi
=
&
per_cpu
(
ipi_data
,
cpu
);
per_cpu
(
cpu_data
,
cpu
).
ipi_count
++
;
ipi
->
ipi_count
++
;
if
(
ipimask
&
(
1
<<
0
))
{
struct
ipi_data
*
ipi
=
&
per_cpu
(
ipi_data
,
cpu
);
for
(;;)
{
unsigned
long
msgs
;
...
...
include/asm-arm/cpu.h
View file @
3f371438
...
...
@@ -17,7 +17,6 @@ struct cpuinfo_arm {
struct
cpu
cpu
;
#ifdef CONFIG_SMP
unsigned
int
loops_per_jiffy
;
unsigned
long
ipi_count
;
#endif
};
...
...
include/asm-arm/mach/irq.h
View file @
3f371438
...
...
@@ -47,6 +47,13 @@ struct irqchip {
* Set wakeup-enable on the selected IRQ
*/
int
(
*
wake
)(
unsigned
int
,
unsigned
int
);
#ifdef CONFIG_SMP
/*
* Route an interrupt to a CPU
*/
void
(
*
set_cpu
)(
struct
irqdesc
*
desc
,
unsigned
int
irq
,
unsigned
int
cpu
);
#endif
};
struct
irqdesc
{
...
...
@@ -67,6 +74,13 @@ struct irqdesc {
unsigned
int
noautoenable
:
1
;
/* don't automatically enable IRQ */
unsigned
int
unused
:
25
;
struct
proc_dir_entry
*
procdir
;
#ifdef CONFIG_SMP
cpumask_t
affinity
;
unsigned
int
cpu
;
#endif
/*
* IRQ lock detection
*/
...
...
include/asm-arm/smp.h
View file @
3f371438
...
...
@@ -32,6 +32,13 @@ extern cpumask_t cpu_present_mask;
*/
#define PROC_CHANGE_PENALTY 15
struct
seq_file
;
/*
* generate IPI list text
*/
extern
void
show_ipi_list
(
struct
seq_file
*
p
);
/*
* Move global data into per-processor storage.
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment