Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
sh
intc
balancing.c
Go to the documentation of this file.
1
/*
2
* Support for hardware-managed IRQ auto-distribution.
3
*
4
* Copyright (C) 2010 Paul Mundt
5
*
6
* This file is subject to the terms and conditions of the GNU General Public
7
* License. See the file "COPYING" in the main directory of this archive
8
* for more details.
9
*/
10
#include "
internals.h
"
11
12
static
unsigned
long
dist_handle[
INTC_NR_IRQS
];
13
14
void
intc_balancing_enable
(
unsigned
int
irq)
15
{
16
struct
intc_desc_int
*
d
= get_intc_desc(irq);
17
unsigned
long
handle
= dist_handle[irq];
18
unsigned
long
addr
;
19
20
if
(irq_balancing_disabled(irq) || !handle)
21
return
;
22
23
addr =
INTC_REG
(d,
_INTC_ADDR_D
(handle), 0);
24
intc_reg_fns
[
_INTC_FN
(handle)](
addr
,
handle
, 1);
25
}
26
27
void
intc_balancing_disable
(
unsigned
int
irq)
28
{
29
struct
intc_desc_int
*
d
= get_intc_desc(irq);
30
unsigned
long
handle
= dist_handle[irq];
31
unsigned
long
addr
;
32
33
if
(irq_balancing_disabled(irq) || !handle)
34
return
;
35
36
addr =
INTC_REG
(d,
_INTC_ADDR_D
(handle), 0);
37
intc_reg_fns
[
_INTC_FN
(handle)](
addr
,
handle
, 0);
38
}
39
40
static
unsigned
int
intc_dist_data(
struct
intc_desc
*
desc
,
41
struct
intc_desc_int
*
d
,
42
intc_enum
enum_id)
43
{
44
struct
intc_mask_reg
*mr = desc->
hw
.mask_regs;
45
unsigned
int
i
,
j
,
fn
,
mode
;
46
unsigned
long
reg_e, reg_d;
47
48
for
(i = 0; mr && enum_id && i < desc->
hw
.nr_mask_regs; i++) {
49
mr = desc->
hw
.mask_regs +
i
;
50
51
/*
52
* Skip this entry if there's no auto-distribution
53
* register associated with it.
54
*/
55
if
(!mr->dist_reg)
56
continue
;
57
58
for
(j = 0; j <
ARRAY_SIZE
(mr->
enum_ids
); j++) {
59
if
(mr->
enum_ids
[j] != enum_id)
60
continue
;
61
62
fn =
REG_FN_MODIFY_BASE
;
63
mode =
MODE_ENABLE_REG
;
64
reg_e = mr->dist_reg;
65
reg_d = mr->dist_reg;
66
67
fn += (mr->
reg_width
>> 3) - 1;
68
return
_INTC_MK
(fn, mode,
69
intc_get_reg
(d, reg_e),
70
intc_get_reg
(d, reg_d),
71
1,
72
(mr->
reg_width
- 1) - j);
73
}
74
}
75
76
/*
77
* It's possible we've gotten here with no distribution options
78
* available for the IRQ in question, so we just skip over those.
79
*/
80
return
0;
81
}
82
83
void
intc_set_dist_handle
(
unsigned
int
irq,
struct
intc_desc
*desc,
84
struct
intc_desc_int
*d,
intc_enum
id
)
85
{
86
unsigned
long
flags
;
87
88
/*
89
* Nothing to do for this IRQ.
90
*/
91
if
(!desc->
hw
.mask_regs)
92
return
;
93
94
raw_spin_lock_irqsave
(&
intc_big_lock
, flags);
95
dist_handle[irq] = intc_dist_data(desc, d,
id
);
96
raw_spin_unlock_irqrestore
(&
intc_big_lock
, flags);
97
}
Generated on Thu Jan 10 2013 14:25:20 for Linux Kernel by
1.8.2