~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/rapidio/rio-access.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * RapidIO configuration space access support
 
3
 *
 
4
 * Copyright 2005 MontaVista Software, Inc.
 
5
 * Matt Porter <mporter@kernel.crashing.org>
 
6
 *
 
7
 * This program is free software; you can redistribute  it and/or modify it
 
8
 * under  the terms of  the GNU General  Public License as published by the
 
9
 * Free Software Foundation;  either version 2 of the  License, or (at your
 
10
 * option) any later version.
 
11
 */
 
12
 
 
13
#include <linux/rio.h>
 
14
#include <linux/module.h>
 
15
 
 
16
/*
 
17
 * These interrupt-safe spinlocks protect all accesses to RIO
 
18
 * configuration space and doorbell access.
 
19
 */
 
20
static DEFINE_SPINLOCK(rio_config_lock);
 
21
static DEFINE_SPINLOCK(rio_doorbell_lock);
 
22
 
 
23
/*
 
24
 *  Wrappers for all RIO configuration access functions.  They just check
 
25
 *  alignment, do locking and call the low-level functions pointed to
 
26
 *  by rio_mport->ops.
 
27
 */
 
28
 
 
29
#define RIO_8_BAD 0
 
30
#define RIO_16_BAD (offset & 1)
 
31
#define RIO_32_BAD (offset & 3)
 
32
 
 
33
/**
 
34
 * RIO_LOP_READ - Generate rio_local_read_config_* functions
 
35
 * @size: Size of configuration space read (8, 16, 32 bits)
 
36
 * @type: C type of value argument
 
37
 * @len: Length of configuration space read (1, 2, 4 bytes)
 
38
 *
 
39
 * Generates rio_local_read_config_* functions used to access
 
40
 * configuration space registers on the local device.
 
41
 */
 
42
#define RIO_LOP_READ(size,type,len) \
 
43
int __rio_local_read_config_##size \
 
44
        (struct rio_mport *mport, u32 offset, type *value)              \
 
45
{                                                                       \
 
46
        int res;                                                        \
 
47
        unsigned long flags;                                            \
 
48
        u32 data = 0;                                                   \
 
49
        if (RIO_##size##_BAD) return RIO_BAD_SIZE;                      \
 
50
        spin_lock_irqsave(&rio_config_lock, flags);                     \
 
51
        res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
 
52
        *value = (type)data;                                            \
 
53
        spin_unlock_irqrestore(&rio_config_lock, flags);                \
 
54
        return res;                                                     \
 
55
}
 
56
 
 
57
/**
 
58
 * RIO_LOP_WRITE - Generate rio_local_write_config_* functions
 
59
 * @size: Size of configuration space write (8, 16, 32 bits)
 
60
 * @type: C type of value argument
 
61
 * @len: Length of configuration space write (1, 2, 4 bytes)
 
62
 *
 
63
 * Generates rio_local_write_config_* functions used to access
 
64
 * configuration space registers on the local device.
 
65
 */
 
66
#define RIO_LOP_WRITE(size,type,len) \
 
67
int __rio_local_write_config_##size \
 
68
        (struct rio_mport *mport, u32 offset, type value)               \
 
69
{                                                                       \
 
70
        int res;                                                        \
 
71
        unsigned long flags;                                            \
 
72
        if (RIO_##size##_BAD) return RIO_BAD_SIZE;                      \
 
73
        spin_lock_irqsave(&rio_config_lock, flags);                     \
 
74
        res = mport->ops->lcwrite(mport, mport->id, offset, len, value);\
 
75
        spin_unlock_irqrestore(&rio_config_lock, flags);                \
 
76
        return res;                                                     \
 
77
}
 
78
 
 
79
RIO_LOP_READ(8, u8, 1)
 
80
RIO_LOP_READ(16, u16, 2)
 
81
RIO_LOP_READ(32, u32, 4)
 
82
RIO_LOP_WRITE(8, u8, 1)
 
83
RIO_LOP_WRITE(16, u16, 2)
 
84
RIO_LOP_WRITE(32, u32, 4)
 
85
 
 
86
EXPORT_SYMBOL_GPL(__rio_local_read_config_8);
 
87
EXPORT_SYMBOL_GPL(__rio_local_read_config_16);
 
88
EXPORT_SYMBOL_GPL(__rio_local_read_config_32);
 
89
EXPORT_SYMBOL_GPL(__rio_local_write_config_8);
 
90
EXPORT_SYMBOL_GPL(__rio_local_write_config_16);
 
91
EXPORT_SYMBOL_GPL(__rio_local_write_config_32);
 
92
 
 
93
/**
 
94
 * RIO_OP_READ - Generate rio_mport_read_config_* functions
 
95
 * @size: Size of configuration space read (8, 16, 32 bits)
 
96
 * @type: C type of value argument
 
97
 * @len: Length of configuration space read (1, 2, 4 bytes)
 
98
 *
 
99
 * Generates rio_mport_read_config_* functions used to access
 
100
 * configuration space registers on the local device.
 
101
 */
 
102
#define RIO_OP_READ(size,type,len) \
 
103
int rio_mport_read_config_##size \
 
104
        (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value)     \
 
105
{                                                                       \
 
106
        int res;                                                        \
 
107
        unsigned long flags;                                            \
 
108
        u32 data = 0;                                                   \
 
109
        if (RIO_##size##_BAD) return RIO_BAD_SIZE;                      \
 
110
        spin_lock_irqsave(&rio_config_lock, flags);                     \
 
111
        res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
 
112
        *value = (type)data;                                            \
 
113
        spin_unlock_irqrestore(&rio_config_lock, flags);                \
 
114
        return res;                                                     \
 
115
}
 
116
 
 
117
/**
 
118
 * RIO_OP_WRITE - Generate rio_mport_write_config_* functions
 
119
 * @size: Size of configuration space write (8, 16, 32 bits)
 
120
 * @type: C type of value argument
 
121
 * @len: Length of configuration space write (1, 2, 4 bytes)
 
122
 *
 
123
 * Generates rio_mport_write_config_* functions used to access
 
124
 * configuration space registers on the local device.
 
125
 */
 
126
#define RIO_OP_WRITE(size,type,len) \
 
127
int rio_mport_write_config_##size \
 
128
        (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value)      \
 
129
{                                                                       \
 
130
        int res;                                                        \
 
131
        unsigned long flags;                                            \
 
132
        if (RIO_##size##_BAD) return RIO_BAD_SIZE;                      \
 
133
        spin_lock_irqsave(&rio_config_lock, flags);                     \
 
134
        res = mport->ops->cwrite(mport, mport->id, destid, hopcount, offset, len, value); \
 
135
        spin_unlock_irqrestore(&rio_config_lock, flags);                \
 
136
        return res;                                                     \
 
137
}
 
138
 
 
139
RIO_OP_READ(8, u8, 1)
 
140
RIO_OP_READ(16, u16, 2)
 
141
RIO_OP_READ(32, u32, 4)
 
142
RIO_OP_WRITE(8, u8, 1)
 
143
RIO_OP_WRITE(16, u16, 2)
 
144
RIO_OP_WRITE(32, u32, 4)
 
145
 
 
146
EXPORT_SYMBOL_GPL(rio_mport_read_config_8);
 
147
EXPORT_SYMBOL_GPL(rio_mport_read_config_16);
 
148
EXPORT_SYMBOL_GPL(rio_mport_read_config_32);
 
149
EXPORT_SYMBOL_GPL(rio_mport_write_config_8);
 
150
EXPORT_SYMBOL_GPL(rio_mport_write_config_16);
 
151
EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
 
152
 
 
153
/**
 
154
 * rio_mport_send_doorbell - Send a doorbell message
 
155
 *
 
156
 * @mport: RIO master port
 
157
 * @destid: RIO device destination ID
 
158
 * @data: Doorbell message data
 
159
 *
 
160
 * Send a doorbell message to a RIO device. The doorbell message
 
161
 * has a 16-bit info field provided by the data argument.
 
162
 */
 
163
int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
 
164
{
 
165
        int res;
 
166
        unsigned long flags;
 
167
 
 
168
        spin_lock_irqsave(&rio_doorbell_lock, flags);
 
169
        res = mport->ops->dsend(mport, mport->id, destid, data);
 
170
        spin_unlock_irqrestore(&rio_doorbell_lock, flags);
 
171
 
 
172
        return res;
 
173
}
 
174
 
 
175
EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);