Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 259204
b: refs/heads/master
c: e8d548d
h: refs/heads/master
v: v3
  • Loading branch information
Kuninori Morimoto authored and Greg Kroah-Hartman committed Jun 7, 2011
1 parent 1c6ca78 commit 6e34b80
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 252 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ad6f2a8bc53b7cc104f481a648ce357528cc08eb
refs/heads/master: e8d548d549688d335236f7f6f8bcee141a207ff8
2 changes: 1 addition & 1 deletion trunk/drivers/usb/renesas_usbhs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o

renesas_usbhs-y := common.o mod.o pipe.o
renesas_usbhs-y := common.o mod.o pipe.o fifo.o

renesas_usbhs-$(CONFIG_USB_RENESAS_USBHS_UDC) += mod_gadget.o
1 change: 1 addition & 0 deletions trunk/drivers/usb/renesas_usbhs/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct usbhs_priv;

#include "./mod.h"
#include "./pipe.h"
#include "./fifo.h"

/*
*
Expand Down
211 changes: 211 additions & 0 deletions trunk/drivers/usb/renesas_usbhs/fifo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
* Renesas USB driver
*
* Copyright (C) 2011 Renesas Solutions Corp.
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <linux/delay.h>
#include <linux/io.h>
#include "./common.h"
#include "./pipe.h"

/*
* FIFO ctrl
*/
static void usbhsf_send_terminator(struct usbhs_pipe *pipe)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);

usbhs_bset(priv, CFIFOCTR, BVAL, BVAL);
}

static int usbhsf_fifo_barrier(struct usbhs_priv *priv)
{
int timeout = 1024;

do {
/* The FIFO port is accessible */
if (usbhs_read(priv, CFIFOCTR) & FRDY)
return 0;

udelay(10);
} while (timeout--);

return -EBUSY;
}

static void usbhsf_fifo_clear(struct usbhs_pipe *pipe)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);

if (!usbhs_pipe_is_dcp(pipe))
usbhsf_fifo_barrier(priv);

usbhs_write(priv, CFIFOCTR, BCLR);
}

static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv)
{
return usbhs_read(priv, CFIFOCTR) & DTLN_MASK;
}

static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
struct device *dev = usbhs_priv_to_dev(priv);
int timeout = 1024;
u16 mask = ((1 << 5) | 0xF); /* mask of ISEL | CURPIPE */
u16 base = usbhs_pipe_number(pipe); /* CURPIPE */

if (usbhs_pipe_is_dcp(pipe))
base |= (1 == write) << 5; /* ISEL */

/* "base" will be used below */
usbhs_write(priv, CFIFOSEL, base | MBW_32);

/* check ISEL and CURPIPE value */
while (timeout--) {
if (base == (mask & usbhs_read(priv, CFIFOSEL)))
return 0;
udelay(10);
}

dev_err(dev, "fifo select error\n");

return -EIO;
}

/*
* PIO fifo functions
*/
int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe)
{
return usbhsf_fifo_select(pipe, 1);
}

int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
void __iomem *addr = priv->base + CFIFO;
int maxp = usbhs_pipe_get_maxpacket(pipe);
int total_len;
int i, ret;

ret = usbhs_pipe_is_accessible(pipe);
if (ret < 0)
return ret;

ret = usbhsf_fifo_select(pipe, 1);
if (ret < 0)
return ret;

ret = usbhsf_fifo_barrier(priv);
if (ret < 0)
return ret;

len = min(len, maxp);
total_len = len;

/*
* FIXME
*
* 32-bit access only
*/
if (len >= 4 &&
!((unsigned long)buf & 0x03)) {
iowrite32_rep(addr, buf, len / 4);
len %= 4;
buf += total_len - len;
}

/* the rest operation */
for (i = 0; i < len; i++)
iowrite8(buf[i], addr + (0x03 - (i & 0x03)));

if (total_len < maxp)
usbhsf_send_terminator(pipe);

return total_len;
}

int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
{
int ret;

/*
* select pipe and enable it to prepare packet receive
*/
ret = usbhsf_fifo_select(pipe, 0);
if (ret < 0)
return ret;

usbhs_pipe_enable(pipe);

return ret;
}

int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
void __iomem *addr = priv->base + CFIFO;
int rcv_len;
int i, ret;
int total_len;
u32 data = 0;

ret = usbhsf_fifo_select(pipe, 0);
if (ret < 0)
return ret;

ret = usbhsf_fifo_barrier(priv);
if (ret < 0)
return ret;

rcv_len = usbhsf_fifo_rcv_len(priv);

/*
* Buffer clear if Zero-Length packet
*
* see
* "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
*/
if (0 == rcv_len) {
usbhsf_fifo_clear(pipe);
return 0;
}

len = min(rcv_len, len);
total_len = len;

/*
* FIXME
*
* 32-bit access only
*/
if (len >= 4 &&
!((unsigned long)buf & 0x03)) {
ioread32_rep(addr, buf, len / 4);
len %= 4;
buf += rcv_len - len;
}

/* the rest operation */
for (i = 0; i < len; i++) {
if (!(i & 0x03))
data = ioread32(addr);

buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
}

return total_len;
}
30 changes: 30 additions & 0 deletions trunk/drivers/usb/renesas_usbhs/fifo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Renesas USB driver
*
* Copyright (C) 2011 Renesas Solutions Corp.
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef RENESAS_USB_FIFO_H
#define RENESAS_USB_FIFO_H

#include "common.h"

/*
* fifo
*/
int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len);
int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len);
int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe);
int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe);

#endif /* RENESAS_USB_FIFO_H */
16 changes: 8 additions & 8 deletions trunk/drivers/usb/renesas_usbhs/mod_gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep,
* - after callback_update,
* - before queue_pop / stage_end
*/
usbhs_fifo_enable(pipe);
usbhs_pipe_enable(pipe);

/*
* all data were sent ?
Expand Down Expand Up @@ -454,7 +454,7 @@ static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep,
int disable = 0;

uep->handler->irq_mask(uep, disable);
usbhs_fifo_disable(pipe);
usbhs_pipe_disable(pipe);
usbhsg_queue_pop(uep, ureq, 0);
}

Expand Down Expand Up @@ -546,9 +546,9 @@ static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv,
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);

if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) {
usbhs_fifo_disable(pipe);
usbhs_pipe_disable(pipe);
usbhs_pipe_clear_sequence(pipe);
usbhs_fifo_enable(pipe);
usbhs_pipe_enable(pipe);
}

usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
Expand Down Expand Up @@ -695,7 +695,7 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv,
ret = gpriv->driver->setup(&gpriv->gadget, &ctrl);

if (ret < 0)
usbhs_fifo_stall(pipe);
usbhs_pipe_stall(pipe);

return ret;
}
Expand Down Expand Up @@ -803,7 +803,7 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep)
********* assume under spin lock *********
*/

usbhs_fifo_disable(pipe);
usbhs_pipe_disable(pipe);

/*
* disable pipe irq
Expand Down Expand Up @@ -1016,9 +1016,9 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge)
halt, usbhs_pipe_number(pipe));

if (halt)
usbhs_fifo_stall(pipe);
usbhs_pipe_stall(pipe);
else
usbhs_fifo_disable(pipe);
usbhs_pipe_disable(pipe);

if (halt && wedge)
usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE);
Expand Down
Loading

0 comments on commit 6e34b80

Please sign in to comment.