1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * RapidIO configuration space access support
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright 2005 MontaVista Software, Inc.
6*4882a593Smuzhiyun * Matt Porter <mporter@kernel.crashing.org>
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/rio.h>
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/rio_drv.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun /*
15*4882a593Smuzhiyun * Wrappers for all RIO configuration access functions. They just check
16*4882a593Smuzhiyun * alignment and call the low-level functions pointed to by rio_mport->ops.
17*4882a593Smuzhiyun */
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #define RIO_8_BAD 0
20*4882a593Smuzhiyun #define RIO_16_BAD (offset & 1)
21*4882a593Smuzhiyun #define RIO_32_BAD (offset & 3)
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /**
24*4882a593Smuzhiyun * RIO_LOP_READ - Generate rio_local_read_config_* functions
25*4882a593Smuzhiyun * @size: Size of configuration space read (8, 16, 32 bits)
26*4882a593Smuzhiyun * @type: C type of value argument
27*4882a593Smuzhiyun * @len: Length of configuration space read (1, 2, 4 bytes)
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun * Generates rio_local_read_config_* functions used to access
30*4882a593Smuzhiyun * configuration space registers on the local device.
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun #define RIO_LOP_READ(size,type,len) \
33*4882a593Smuzhiyun int __rio_local_read_config_##size \
34*4882a593Smuzhiyun (struct rio_mport *mport, u32 offset, type *value) \
35*4882a593Smuzhiyun { \
36*4882a593Smuzhiyun int res; \
37*4882a593Smuzhiyun u32 data = 0; \
38*4882a593Smuzhiyun if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
39*4882a593Smuzhiyun res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
40*4882a593Smuzhiyun *value = (type)data; \
41*4882a593Smuzhiyun return res; \
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /**
45*4882a593Smuzhiyun * RIO_LOP_WRITE - Generate rio_local_write_config_* functions
46*4882a593Smuzhiyun * @size: Size of configuration space write (8, 16, 32 bits)
47*4882a593Smuzhiyun * @type: C type of value argument
48*4882a593Smuzhiyun * @len: Length of configuration space write (1, 2, 4 bytes)
49*4882a593Smuzhiyun *
50*4882a593Smuzhiyun * Generates rio_local_write_config_* functions used to access
51*4882a593Smuzhiyun * configuration space registers on the local device.
52*4882a593Smuzhiyun */
53*4882a593Smuzhiyun #define RIO_LOP_WRITE(size,type,len) \
54*4882a593Smuzhiyun int __rio_local_write_config_##size \
55*4882a593Smuzhiyun (struct rio_mport *mport, u32 offset, type value) \
56*4882a593Smuzhiyun { \
57*4882a593Smuzhiyun if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
58*4882a593Smuzhiyun return mport->ops->lcwrite(mport, mport->id, offset, len, value);\
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun RIO_LOP_READ(8, u8, 1)
62*4882a593Smuzhiyun RIO_LOP_READ(16, u16, 2)
63*4882a593Smuzhiyun RIO_LOP_READ(32, u32, 4)
64*4882a593Smuzhiyun RIO_LOP_WRITE(8, u8, 1)
65*4882a593Smuzhiyun RIO_LOP_WRITE(16, u16, 2)
66*4882a593Smuzhiyun RIO_LOP_WRITE(32, u32, 4)
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__rio_local_read_config_8);
69*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__rio_local_read_config_16);
70*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__rio_local_read_config_32);
71*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__rio_local_write_config_8);
72*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__rio_local_write_config_16);
73*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__rio_local_write_config_32);
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /**
76*4882a593Smuzhiyun * RIO_OP_READ - Generate rio_mport_read_config_* functions
77*4882a593Smuzhiyun * @size: Size of configuration space read (8, 16, 32 bits)
78*4882a593Smuzhiyun * @type: C type of value argument
79*4882a593Smuzhiyun * @len: Length of configuration space read (1, 2, 4 bytes)
80*4882a593Smuzhiyun *
81*4882a593Smuzhiyun * Generates rio_mport_read_config_* functions used to access
82*4882a593Smuzhiyun * configuration space registers on the local device.
83*4882a593Smuzhiyun */
84*4882a593Smuzhiyun #define RIO_OP_READ(size,type,len) \
85*4882a593Smuzhiyun int rio_mport_read_config_##size \
86*4882a593Smuzhiyun (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \
87*4882a593Smuzhiyun { \
88*4882a593Smuzhiyun int res; \
89*4882a593Smuzhiyun u32 data = 0; \
90*4882a593Smuzhiyun if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
91*4882a593Smuzhiyun res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
92*4882a593Smuzhiyun *value = (type)data; \
93*4882a593Smuzhiyun return res; \
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun /**
97*4882a593Smuzhiyun * RIO_OP_WRITE - Generate rio_mport_write_config_* functions
98*4882a593Smuzhiyun * @size: Size of configuration space write (8, 16, 32 bits)
99*4882a593Smuzhiyun * @type: C type of value argument
100*4882a593Smuzhiyun * @len: Length of configuration space write (1, 2, 4 bytes)
101*4882a593Smuzhiyun *
102*4882a593Smuzhiyun * Generates rio_mport_write_config_* functions used to access
103*4882a593Smuzhiyun * configuration space registers on the local device.
104*4882a593Smuzhiyun */
105*4882a593Smuzhiyun #define RIO_OP_WRITE(size,type,len) \
106*4882a593Smuzhiyun int rio_mport_write_config_##size \
107*4882a593Smuzhiyun (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \
108*4882a593Smuzhiyun { \
109*4882a593Smuzhiyun if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
110*4882a593Smuzhiyun return mport->ops->cwrite(mport, mport->id, destid, hopcount, \
111*4882a593Smuzhiyun offset, len, value); \
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun RIO_OP_READ(8, u8, 1)
115*4882a593Smuzhiyun RIO_OP_READ(16, u16, 2)
116*4882a593Smuzhiyun RIO_OP_READ(32, u32, 4)
117*4882a593Smuzhiyun RIO_OP_WRITE(8, u8, 1)
118*4882a593Smuzhiyun RIO_OP_WRITE(16, u16, 2)
119*4882a593Smuzhiyun RIO_OP_WRITE(32, u32, 4)
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rio_mport_read_config_8);
122*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rio_mport_read_config_16);
123*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rio_mport_read_config_32);
124*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rio_mport_write_config_8);
125*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rio_mport_write_config_16);
126*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun /**
129*4882a593Smuzhiyun * rio_mport_send_doorbell - Send a doorbell message
130*4882a593Smuzhiyun *
131*4882a593Smuzhiyun * @mport: RIO master port
132*4882a593Smuzhiyun * @destid: RIO device destination ID
133*4882a593Smuzhiyun * @data: Doorbell message data
134*4882a593Smuzhiyun *
135*4882a593Smuzhiyun * Send a doorbell message to a RIO device. The doorbell message
136*4882a593Smuzhiyun * has a 16-bit info field provided by the data argument.
137*4882a593Smuzhiyun */
rio_mport_send_doorbell(struct rio_mport * mport,u16 destid,u16 data)138*4882a593Smuzhiyun int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun return mport->ops->dsend(mport, mport->id, destid, data);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
144