aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-06-06 01:18:03 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-07 12:10:07 -0400
commite8d548d549688d335236f7f6f8bcee141a207ff8 (patch)
tree6adc569824995e4e8e6cf21ed1428a89da9a8118 /drivers
parentad6f2a8bc53b7cc104f481a648ce357528cc08eb (diff)
usb: renesas_usbhs: fifo became independent from pipe.
Current renesas_usbhs has PIO data transfer mode which controls CFIFO. And it was implemented in pipe.c. But, fifo control method needs more flexible implementation to support DMAEngine. This patch create fifo.c, and it became independent from pipe.c. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/renesas_usbhs/Makefile2
-rw-r--r--drivers/usb/renesas_usbhs/common.h1
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c211
-rw-r--r--drivers/usb/renesas_usbhs/fifo.h30
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c16
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c252
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h29
7 files changed, 290 insertions, 251 deletions
diff --git a/drivers/usb/renesas_usbhs/Makefile b/drivers/usb/renesas_usbhs/Makefile
index b8798ad16278..ce08345fa15a 100644
--- a/drivers/usb/renesas_usbhs/Makefile
+++ b/drivers/usb/renesas_usbhs/Makefile
@@ -4,6 +4,6 @@
4 4
5obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o 5obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o
6 6
7renesas_usbhs-y := common.o mod.o pipe.o 7renesas_usbhs-y := common.o mod.o pipe.o fifo.o
8 8
9renesas_usbhs-$(CONFIG_USB_RENESAS_USBHS_UDC) += mod_gadget.o 9renesas_usbhs-$(CONFIG_USB_RENESAS_USBHS_UDC) += mod_gadget.o
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h
index 0aadcb402764..24f756024bed 100644
--- a/drivers/usb/renesas_usbhs/common.h
+++ b/drivers/usb/renesas_usbhs/common.h
@@ -24,6 +24,7 @@ struct usbhs_priv;
24 24
25#include "./mod.h" 25#include "./mod.h"
26#include "./pipe.h" 26#include "./pipe.h"
27#include "./fifo.h"
27 28
28/* 29/*
29 * 30 *
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
new file mode 100644
index 000000000000..3fd3adf90541
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -0,0 +1,211 @@
1/*
2 * Renesas USB driver
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 */
17#include <linux/delay.h>
18#include <linux/io.h>
19#include "./common.h"
20#include "./pipe.h"
21
22/*
23 * FIFO ctrl
24 */
25static void usbhsf_send_terminator(struct usbhs_pipe *pipe)
26{
27 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
28
29 usbhs_bset(priv, CFIFOCTR, BVAL, BVAL);
30}
31
32static int usbhsf_fifo_barrier(struct usbhs_priv *priv)
33{
34 int timeout = 1024;
35
36 do {
37 /* The FIFO port is accessible */
38 if (usbhs_read(priv, CFIFOCTR) & FRDY)
39 return 0;
40
41 udelay(10);
42 } while (timeout--);
43
44 return -EBUSY;
45}
46
47static void usbhsf_fifo_clear(struct usbhs_pipe *pipe)
48{
49 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
50
51 if (!usbhs_pipe_is_dcp(pipe))
52 usbhsf_fifo_barrier(priv);
53
54 usbhs_write(priv, CFIFOCTR, BCLR);
55}
56
57static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv)
58{
59 return usbhs_read(priv, CFIFOCTR) & DTLN_MASK;
60}
61
62static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write)
63{
64 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
65 struct device *dev = usbhs_priv_to_dev(priv);
66 int timeout = 1024;
67 u16 mask = ((1 << 5) | 0xF); /* mask of ISEL | CURPIPE */
68 u16 base = usbhs_pipe_number(pipe); /* CURPIPE */
69
70 if (usbhs_pipe_is_dcp(pipe))
71 base |= (1 == write) << 5; /* ISEL */
72
73 /* "base" will be used below */
74 usbhs_write(priv, CFIFOSEL, base | MBW_32);
75
76 /* check ISEL and CURPIPE value */
77 while (timeout--) {
78 if (base == (mask & usbhs_read(priv, CFIFOSEL)))
79 return 0;
80 udelay(10);
81 }
82
83 dev_err(dev, "fifo select error\n");
84
85 return -EIO;
86}
87
88/*
89 * PIO fifo functions
90 */
91int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe)
92{
93 return usbhsf_fifo_select(pipe, 1);
94}
95
96int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
97{
98 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
99 void __iomem *addr = priv->base + CFIFO;
100 int maxp = usbhs_pipe_get_maxpacket(pipe);
101 int total_len;
102 int i, ret;
103
104 ret = usbhs_pipe_is_accessible(pipe);
105 if (ret < 0)
106 return ret;
107
108 ret = usbhsf_fifo_select(pipe, 1);
109 if (ret < 0)
110 return ret;
111
112 ret = usbhsf_fifo_barrier(priv);
113 if (ret < 0)
114 return ret;
115
116 len = min(len, maxp);
117 total_len = len;
118
119 /*
120 * FIXME
121 *
122 * 32-bit access only
123 */
124 if (len >= 4 &&
125 !((unsigned long)buf & 0x03)) {
126 iowrite32_rep(addr, buf, len / 4);
127 len %= 4;
128 buf += total_len - len;
129 }
130
131 /* the rest operation */
132 for (i = 0; i < len; i++)
133 iowrite8(buf[i], addr + (0x03 - (i & 0x03)));
134
135 if (total_len < maxp)
136 usbhsf_send_terminator(pipe);
137
138 return total_len;
139}
140
141int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
142{
143 int ret;
144
145 /*
146 * select pipe and enable it to prepare packet receive
147 */
148 ret = usbhsf_fifo_select(pipe, 0);
149 if (ret < 0)
150 return ret;
151
152 usbhs_pipe_enable(pipe);
153
154 return ret;
155}
156
157int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
158{
159 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
160 void __iomem *addr = priv->base + CFIFO;
161 int rcv_len;
162 int i, ret;
163 int total_len;
164 u32 data = 0;
165
166 ret = usbhsf_fifo_select(pipe, 0);
167 if (ret < 0)
168 return ret;
169
170 ret = usbhsf_fifo_barrier(priv);
171 if (ret < 0)
172 return ret;
173
174 rcv_len = usbhsf_fifo_rcv_len(priv);
175
176 /*
177 * Buffer clear if Zero-Length packet
178 *
179 * see
180 * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
181 */
182 if (0 == rcv_len) {
183 usbhsf_fifo_clear(pipe);
184 return 0;
185 }
186
187 len = min(rcv_len, len);
188 total_len = len;
189
190 /*
191 * FIXME
192 *
193 * 32-bit access only
194 */
195 if (len >= 4 &&
196 !((unsigned long)buf & 0x03)) {
197 ioread32_rep(addr, buf, len / 4);
198 len %= 4;
199 buf += rcv_len - len;
200 }
201
202 /* the rest operation */
203 for (i = 0; i < len; i++) {
204 if (!(i & 0x03))
205 data = ioread32(addr);
206
207 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
208 }
209
210 return total_len;
211}
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h
new file mode 100644
index 000000000000..75a7c1577ad3
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/fifo.h
@@ -0,0 +1,30 @@
1/*
2 * Renesas USB driver
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 */
17#ifndef RENESAS_USB_FIFO_H
18#define RENESAS_USB_FIFO_H
19
20#include "common.h"
21
22/*
23 * fifo
24 */
25int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len);
26int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len);
27int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe);
28int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe);
29
30#endif /* RENESAS_USB_FIFO_H */
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 206cfabc9286..128c8da8db85 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -376,7 +376,7 @@ static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep,
376 * - after callback_update, 376 * - after callback_update,
377 * - before queue_pop / stage_end 377 * - before queue_pop / stage_end
378 */ 378 */
379 usbhs_fifo_enable(pipe); 379 usbhs_pipe_enable(pipe);
380 380
381 /* 381 /*
382 * all data were sent ? 382 * all data were sent ?
@@ -454,7 +454,7 @@ static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep,
454 int disable = 0; 454 int disable = 0;
455 455
456 uep->handler->irq_mask(uep, disable); 456 uep->handler->irq_mask(uep, disable);
457 usbhs_fifo_disable(pipe); 457 usbhs_pipe_disable(pipe);
458 usbhsg_queue_pop(uep, ureq, 0); 458 usbhsg_queue_pop(uep, ureq, 0);
459 } 459 }
460 460
@@ -546,9 +546,9 @@ static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv,
546 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 546 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
547 547
548 if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) { 548 if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) {
549 usbhs_fifo_disable(pipe); 549 usbhs_pipe_disable(pipe);
550 usbhs_pipe_clear_sequence(pipe); 550 usbhs_pipe_clear_sequence(pipe);
551 usbhs_fifo_enable(pipe); 551 usbhs_pipe_enable(pipe);
552 } 552 }
553 553
554 usbhsg_recip_handler_std_control_done(priv, uep, ctrl); 554 usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
@@ -695,7 +695,7 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv,
695 ret = gpriv->driver->setup(&gpriv->gadget, &ctrl); 695 ret = gpriv->driver->setup(&gpriv->gadget, &ctrl);
696 696
697 if (ret < 0) 697 if (ret < 0)
698 usbhs_fifo_stall(pipe); 698 usbhs_pipe_stall(pipe);
699 699
700 return ret; 700 return ret;
701} 701}
@@ -803,7 +803,7 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep)
803 ********* assume under spin lock ********* 803 ********* assume under spin lock *********
804 */ 804 */
805 805
806 usbhs_fifo_disable(pipe); 806 usbhs_pipe_disable(pipe);
807 807
808 /* 808 /*
809 * disable pipe irq 809 * disable pipe irq
@@ -1016,9 +1016,9 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge)
1016 halt, usbhs_pipe_number(pipe)); 1016 halt, usbhs_pipe_number(pipe));
1017 1017
1018 if (halt) 1018 if (halt)
1019 usbhs_fifo_stall(pipe); 1019 usbhs_pipe_stall(pipe);
1020 else 1020 else
1021 usbhs_fifo_disable(pipe); 1021 usbhs_pipe_disable(pipe);
1022 1022
1023 if (halt && wedge) 1023 if (halt && wedge)
1024 usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE); 1024 usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE);
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 80fc4add6af2..75e9e3cbc0e5 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -15,7 +15,6 @@
15 * 15 *
16 */ 16 */
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/io.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include "./common.h" 19#include "./common.h"
21#include "./pipe.h" 20#include "./pipe.h"
@@ -23,13 +22,8 @@
23/* 22/*
24 * macros 23 * macros
25 */ 24 */
26#define usbhsp_priv_to_pipeinfo(pr) (&(pr)->pipe_info)
27#define usbhsp_pipe_to_priv(p) ((p)->priv)
28
29#define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2) 25#define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2)
30 26
31#define usbhsp_is_dcp(p) ((p)->priv->pipe_info.pipe == (p))
32
33#define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f) 27#define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f)
34#define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f) 28#define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f)
35#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f) 29#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f)
@@ -77,10 +71,10 @@ void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
77 */ 71 */
78static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val) 72static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
79{ 73{
80 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 74 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
81 int offset = usbhsp_addr_offset(pipe); 75 int offset = usbhsp_addr_offset(pipe);
82 76
83 if (usbhsp_is_dcp(pipe)) 77 if (usbhs_pipe_is_dcp(pipe))
84 usbhs_bset(priv, DCPCTR, mask, val); 78 usbhs_bset(priv, DCPCTR, mask, val);
85 else 79 else
86 usbhs_bset(priv, PIPEnCTR + offset, mask, val); 80 usbhs_bset(priv, PIPEnCTR + offset, mask, val);
@@ -88,10 +82,10 @@ static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
88 82
89static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe) 83static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe)
90{ 84{
91 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 85 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
92 int offset = usbhsp_addr_offset(pipe); 86 int offset = usbhsp_addr_offset(pipe);
93 87
94 if (usbhsp_is_dcp(pipe)) 88 if (usbhs_pipe_is_dcp(pipe))
95 return usbhs_read(priv, DCPCTR); 89 return usbhs_read(priv, DCPCTR);
96 else 90 else
97 return usbhs_read(priv, PIPEnCTR + offset); 91 return usbhs_read(priv, PIPEnCTR + offset);
@@ -104,9 +98,9 @@ static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
104 u16 dcp_reg, u16 pipe_reg, 98 u16 dcp_reg, u16 pipe_reg,
105 u16 mask, u16 val) 99 u16 mask, u16 val)
106{ 100{
107 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 101 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
108 102
109 if (usbhsp_is_dcp(pipe)) 103 if (usbhs_pipe_is_dcp(pipe))
110 usbhs_bset(priv, dcp_reg, mask, val); 104 usbhs_bset(priv, dcp_reg, mask, val);
111 else 105 else
112 usbhs_bset(priv, pipe_reg, mask, val); 106 usbhs_bset(priv, pipe_reg, mask, val);
@@ -115,9 +109,9 @@ static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
115static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe, 109static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe,
116 u16 dcp_reg, u16 pipe_reg) 110 u16 dcp_reg, u16 pipe_reg)
117{ 111{
118 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 112 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
119 113
120 if (usbhsp_is_dcp(pipe)) 114 if (usbhs_pipe_is_dcp(pipe))
121 return usbhs_read(priv, dcp_reg); 115 return usbhs_read(priv, dcp_reg);
122 else 116 else
123 return usbhs_read(priv, pipe_reg); 117 return usbhs_read(priv, pipe_reg);
@@ -136,7 +130,7 @@ static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
136 */ 130 */
137static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val) 131static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
138{ 132{
139 if (usbhsp_is_dcp(pipe)) 133 if (usbhs_pipe_is_dcp(pipe))
140 return; 134 return;
141 135
142 __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val); 136 __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val);
@@ -160,7 +154,7 @@ static u16 usbhsp_pipe_maxp_get(struct usbhs_pipe *pipe)
160 */ 154 */
161static void usbhsp_pipe_select(struct usbhs_pipe *pipe) 155static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
162{ 156{
163 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 157 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
164 158
165 /* 159 /*
166 * On pipe, this is necessary before 160 * On pipe, this is necessary before
@@ -182,7 +176,7 @@ static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
182 176
183static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe) 177static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
184{ 178{
185 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 179 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
186 int timeout = 1024; 180 int timeout = 1024;
187 u16 val; 181 u16 val;
188 182
@@ -205,7 +199,7 @@ static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
205 * - "Pipe Control Registers Switching Procedure" 199 * - "Pipe Control Registers Switching Procedure"
206 */ 200 */
207 usbhs_write(priv, CFIFOSEL, 0); 201 usbhs_write(priv, CFIFOSEL, 0);
208 usbhs_fifo_disable(pipe); 202 usbhs_pipe_disable(pipe);
209 203
210 do { 204 do {
211 val = usbhsp_pipectrl_get(pipe); 205 val = usbhsp_pipectrl_get(pipe);
@@ -220,7 +214,7 @@ static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
220 return -EBUSY; 214 return -EBUSY;
221} 215}
222 216
223static int usbhsp_pipe_is_accessible(struct usbhs_pipe *pipe) 217int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe)
224{ 218{
225 u16 val; 219 u16 val;
226 220
@@ -253,7 +247,7 @@ static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe)
253 } 247 }
254} 248}
255 249
256void usbhs_fifo_disable(struct usbhs_pipe *pipe) 250void usbhs_pipe_disable(struct usbhs_pipe *pipe)
257{ 251{
258 int timeout = 1024; 252 int timeout = 1024;
259 u16 val; 253 u16 val;
@@ -273,7 +267,7 @@ void usbhs_fifo_disable(struct usbhs_pipe *pipe)
273 } while (timeout--); 267 } while (timeout--);
274} 268}
275 269
276void usbhs_fifo_enable(struct usbhs_pipe *pipe) 270void usbhs_pipe_enable(struct usbhs_pipe *pipe)
277{ 271{
278 /* see "Pipe n Control Register" - "PID" */ 272 /* see "Pipe n Control Register" - "PID" */
279 __usbhsp_pid_try_nak_if_stall(pipe); 273 __usbhsp_pid_try_nak_if_stall(pipe);
@@ -281,7 +275,7 @@ void usbhs_fifo_enable(struct usbhs_pipe *pipe)
281 usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF); 275 usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF);
282} 276}
283 277
284void usbhs_fifo_stall(struct usbhs_pipe *pipe) 278void usbhs_pipe_stall(struct usbhs_pipe *pipe)
285{ 279{
286 u16 pid = usbhsp_pipectrl_get(pipe); 280 u16 pid = usbhsp_pipectrl_get(pipe);
287 281
@@ -302,191 +296,6 @@ void usbhs_fifo_stall(struct usbhs_pipe *pipe)
302} 296}
303 297
304/* 298/*
305 * CFIFO ctrl
306 */
307void usbhs_fifo_send_terminator(struct usbhs_pipe *pipe)
308{
309 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
310
311 usbhs_bset(priv, CFIFOCTR, BVAL, BVAL);
312}
313
314static void usbhsp_fifo_clear(struct usbhs_pipe *pipe)
315{
316 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
317
318 usbhs_write(priv, CFIFOCTR, BCLR);
319}
320
321static int usbhsp_fifo_barrier(struct usbhs_priv *priv)
322{
323 int timeout = 1024;
324
325 do {
326 /* The FIFO port is accessible */
327 if (usbhs_read(priv, CFIFOCTR) & FRDY)
328 return 0;
329
330 udelay(10);
331 } while (timeout--);
332
333 return -EBUSY;
334}
335
336static int usbhsp_fifo_rcv_len(struct usbhs_priv *priv)
337{
338 return usbhs_read(priv, CFIFOCTR) & DTLN_MASK;
339}
340
341static int usbhsp_fifo_select(struct usbhs_pipe *pipe, int write)
342{
343 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
344 struct device *dev = usbhs_priv_to_dev(priv);
345 int timeout = 1024;
346 u16 mask = ((1 << 5) | 0xF); /* mask of ISEL | CURPIPE */
347 u16 base = usbhs_pipe_number(pipe); /* CURPIPE */
348
349 if (usbhsp_is_dcp(pipe))
350 base |= (1 == write) << 5; /* ISEL */
351
352 /* "base" will be used below */
353 usbhs_write(priv, CFIFOSEL, base | MBW_32);
354
355 /* check ISEL and CURPIPE value */
356 while (timeout--) {
357 if (base == (mask & usbhs_read(priv, CFIFOSEL)))
358 return 0;
359 udelay(10);
360 }
361
362 dev_err(dev, "fifo select error\n");
363
364 return -EIO;
365}
366
367int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe)
368{
369 return usbhsp_fifo_select(pipe, 1);
370}
371
372int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
373{
374 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
375 void __iomem *addr = priv->base + CFIFO;
376 int maxp = usbhs_pipe_get_maxpacket(pipe);
377 int total_len;
378 int i, ret;
379
380 ret = usbhsp_pipe_is_accessible(pipe);
381 if (ret < 0)
382 return ret;
383
384 ret = usbhsp_fifo_select(pipe, 1);
385 if (ret < 0)
386 return ret;
387
388 ret = usbhsp_fifo_barrier(priv);
389 if (ret < 0)
390 return ret;
391
392 len = min(len, maxp);
393 total_len = len;
394
395 /*
396 * FIXME
397 *
398 * 32-bit access only
399 */
400 if (len >= 4 &&
401 !((unsigned long)buf & 0x03)) {
402 iowrite32_rep(addr, buf, len / 4);
403 len %= 4;
404 buf += total_len - len;
405 }
406
407 /* the rest operation */
408 for (i = 0; i < len; i++)
409 iowrite8(buf[i], addr + (0x03 - (i & 0x03)));
410
411 if (total_len < maxp)
412 usbhs_fifo_send_terminator(pipe);
413
414 return total_len;
415}
416
417int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
418{
419 int ret;
420
421 /*
422 * select pipe and enable it to prepare packet receive
423 */
424 ret = usbhsp_fifo_select(pipe, 0);
425 if (ret < 0)
426 return ret;
427
428 usbhs_fifo_enable(pipe);
429
430 return ret;
431}
432
433int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
434{
435 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
436 void __iomem *addr = priv->base + CFIFO;
437 int rcv_len;
438 int i, ret;
439 int total_len;
440 u32 data = 0;
441
442 ret = usbhsp_fifo_select(pipe, 0);
443 if (ret < 0)
444 return ret;
445
446 ret = usbhsp_fifo_barrier(priv);
447 if (ret < 0)
448 return ret;
449
450 rcv_len = usbhsp_fifo_rcv_len(priv);
451
452 /*
453 * Buffer clear if Zero-Length packet
454 *
455 * see
456 * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
457 */
458 if (0 == rcv_len) {
459 usbhsp_fifo_clear(pipe);
460 return 0;
461 }
462
463 len = min(rcv_len, len);
464 total_len = len;
465
466 /*
467 * FIXME
468 *
469 * 32-bit access only
470 */
471 if (len >= 4 &&
472 !((unsigned long)buf & 0x03)) {
473 ioread32_rep(addr, buf, len / 4);
474 len %= 4;
475 buf += rcv_len - len;
476 }
477
478 /* the rest operation */
479 for (i = 0; i < len; i++) {
480 if (!(i & 0x03))
481 data = ioread32(addr);
482
483 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
484 }
485
486 return total_len;
487}
488
489/*
490 * pipe setup 299 * pipe setup
491 */ 300 */
492static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe) 301static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe)
@@ -519,7 +328,7 @@ static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
519 }; 328 };
520 int is_double = usbhsp_possible_double_buffer(pipe); 329 int is_double = usbhsp_possible_double_buffer(pipe);
521 330
522 if (usbhsp_is_dcp(pipe)) 331 if (usbhs_pipe_is_dcp(pipe))
523 return -EINVAL; 332 return -EINVAL;
524 333
525 /* 334 /*
@@ -590,8 +399,8 @@ static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe,
590 const struct usb_endpoint_descriptor *desc, 399 const struct usb_endpoint_descriptor *desc,
591 int is_host) 400 int is_host)
592{ 401{
593 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 402 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
594 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); 403 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
595 struct device *dev = usbhs_priv_to_dev(priv); 404 struct device *dev = usbhs_priv_to_dev(priv);
596 int pipe_num = usbhs_pipe_number(pipe); 405 int pipe_num = usbhs_pipe_number(pipe);
597 int is_double = usbhsp_possible_double_buffer(pipe); 406 int is_double = usbhsp_possible_double_buffer(pipe);
@@ -669,7 +478,7 @@ static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe,
669 */ 478 */
670int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe) 479int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
671{ 480{
672 u16 mask = usbhsp_is_dcp(pipe) ? DCP_MAXP_MASK : PIPE_MAXP_MASK; 481 u16 mask = usbhs_pipe_is_dcp(pipe) ? DCP_MAXP_MASK : PIPE_MAXP_MASK;
673 482
674 usbhsp_pipe_select(pipe); 483 usbhsp_pipe_select(pipe);
675 484
@@ -724,7 +533,7 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
724 533
725void usbhs_pipe_init(struct usbhs_priv *priv) 534void usbhs_pipe_init(struct usbhs_priv *priv)
726{ 535{
727 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); 536 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
728 struct usbhs_pipe *pipe; 537 struct usbhs_pipe *pipe;
729 int i; 538 int i;
730 539
@@ -748,7 +557,9 @@ void usbhs_pipe_init(struct usbhs_priv *priv)
748 usbhsp_flags_init(pipe); 557 usbhsp_flags_init(pipe);
749 pipe->mod_private = NULL; 558 pipe->mod_private = NULL;
750 559
751 usbhsp_fifo_clear(pipe); 560 /* pipe force init */
561 usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
562 usbhsp_pipectrl_set(pipe, ACLRM, 0);
752 } 563 }
753} 564}
754 565
@@ -769,7 +580,7 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
769 return NULL; 580 return NULL;
770 } 581 }
771 582
772 usbhs_fifo_disable(pipe); 583 usbhs_pipe_disable(pipe);
773 584
774 /* make sure pipe is not busy */ 585 /* make sure pipe is not busy */
775 ret = usbhsp_pipe_barrier(pipe); 586 ret = usbhsp_pipe_barrier(pipe);
@@ -782,11 +593,6 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
782 pipebuf = usbhsp_setup_pipebuff(pipe, desc, is_host); 593 pipebuf = usbhsp_setup_pipebuff(pipe, desc, is_host);
783 pipemaxp = usbhsp_setup_pipemaxp(pipe, desc, is_host); 594 pipemaxp = usbhsp_setup_pipemaxp(pipe, desc, is_host);
784 595
785 /* buffer clear
786 * see PIPECFG :: BFRE */
787 usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
788 usbhsp_pipectrl_set(pipe, ACLRM, 0);
789
790 usbhsp_pipe_select(pipe); 596 usbhsp_pipe_select(pipe);
791 usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg); 597 usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
792 usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf); 598 usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
@@ -827,9 +633,9 @@ struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
827 633
828void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe) 634void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
829{ 635{
830 WARN_ON(!usbhsp_is_dcp(pipe)); 636 WARN_ON(!usbhs_pipe_is_dcp(pipe));
831 637
832 usbhs_fifo_enable(pipe); 638 usbhs_pipe_enable(pipe);
833 usbhsp_pipectrl_set(pipe, CCPL, CCPL); 639 usbhsp_pipectrl_set(pipe, CCPL, CCPL);
834} 640}
835 641
@@ -839,7 +645,7 @@ void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
839 */ 645 */
840int usbhs_pipe_probe(struct usbhs_priv *priv) 646int usbhs_pipe_probe(struct usbhs_priv *priv)
841{ 647{
842 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); 648 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
843 struct usbhs_pipe *pipe; 649 struct usbhs_pipe *pipe;
844 struct device *dev = usbhs_priv_to_dev(priv); 650 struct device *dev = usbhs_priv_to_dev(priv);
845 u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); 651 u32 *pipe_type = usbhs_get_dparam(priv, pipe_type);
@@ -876,7 +682,7 @@ int usbhs_pipe_probe(struct usbhs_priv *priv)
876 682
877void usbhs_pipe_remove(struct usbhs_priv *priv) 683void usbhs_pipe_remove(struct usbhs_priv *priv)
878{ 684{
879 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); 685 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
880 686
881 kfree(info->pipe); 687 kfree(info->pipe);
882} 688}
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
index c906eb646d24..2fb69df932ed 100644
--- a/drivers/usb/renesas_usbhs/pipe.h
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -56,25 +56,9 @@ struct usbhs_pipe_info {
56 __usbhs_for_each_pipe(0, pos, &((priv)->pipe_info), i) 56 __usbhs_for_each_pipe(0, pos, &((priv)->pipe_info), i)
57 57
58/* 58/*
59 * pipe module probe / remove 59 * data
60 */ 60 */
61int usbhs_pipe_probe(struct usbhs_priv *priv); 61#define usbhs_priv_to_pipeinfo(pr) (&(pr)->pipe_info)
62void usbhs_pipe_remove(struct usbhs_priv *priv);
63
64/*
65 * cfifo
66 */
67int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len);
68int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len);
69int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe);
70int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe);
71
72void usbhs_fifo_enable(struct usbhs_pipe *pipe);
73void usbhs_fifo_disable(struct usbhs_pipe *pipe);
74void usbhs_fifo_stall(struct usbhs_pipe *pipe);
75
76void usbhs_fifo_send_terminator(struct usbhs_pipe *pipe);
77
78 62
79/* 63/*
80 * usb request 64 * usb request
@@ -88,14 +72,21 @@ void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req);
88struct usbhs_pipe 72struct usbhs_pipe
89*usbhs_pipe_malloc(struct usbhs_priv *priv, 73*usbhs_pipe_malloc(struct usbhs_priv *priv,
90 const struct usb_endpoint_descriptor *desc); 74 const struct usb_endpoint_descriptor *desc);
91 75int usbhs_pipe_probe(struct usbhs_priv *priv);
76void usbhs_pipe_remove(struct usbhs_priv *priv);
92int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); 77int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe);
93int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe); 78int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe);
94void usbhs_pipe_init(struct usbhs_priv *priv); 79void usbhs_pipe_init(struct usbhs_priv *priv);
95int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); 80int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe);
96void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe); 81void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe);
82int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe);
83void usbhs_pipe_enable(struct usbhs_pipe *pipe);
84void usbhs_pipe_disable(struct usbhs_pipe *pipe);
85void usbhs_pipe_stall(struct usbhs_pipe *pipe);
97 86
87#define usbhs_pipe_to_priv(p) ((p)->priv)
98#define usbhs_pipe_number(p) (int)((p) - (p)->priv->pipe_info.pipe) 88#define usbhs_pipe_number(p) (int)((p) - (p)->priv->pipe_info.pipe)
89#define usbhs_pipe_is_dcp(p) ((p)->priv->pipe_info.pipe == (p))
99 90
100/* 91/*
101 * dcp control 92 * dcp control