mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-28 00:31:54 +02:00
[adm5120] minor usb driver cleanup
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@8385 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
80886edaa0
commit
8f4b522143
@ -89,7 +89,6 @@ MODULE_AUTHOR("Jeroen Vreeken (pe1rxq@amsat.org)");
|
|||||||
#define ADMHCD_REG_PORTSTATUS1 0x7c
|
#define ADMHCD_REG_PORTSTATUS1 0x7c
|
||||||
#define ADMHCD_REG_HOSTHEAD 0x80
|
#define ADMHCD_REG_HOSTHEAD 0x80
|
||||||
|
|
||||||
|
|
||||||
#define ADMHCD_NUMPORTS 2
|
#define ADMHCD_NUMPORTS 2
|
||||||
|
|
||||||
struct admhcd_ed {
|
struct admhcd_ed {
|
||||||
@ -136,9 +135,9 @@ struct admhcd_td {
|
|||||||
|
|
||||||
static int admhcd_td_err[16] = {
|
static int admhcd_td_err[16] = {
|
||||||
0, /* No */
|
0, /* No */
|
||||||
-EREMOTEIO, /* CRC */
|
-EREMOTEIO, /* CRC */
|
||||||
-EREMOTEIO, /* bit stuff */
|
-EREMOTEIO, /* bit stuff */
|
||||||
-EREMOTEIO, /* data toggle */
|
-EREMOTEIO, /* data toggle */
|
||||||
-EPIPE, /* stall */
|
-EPIPE, /* stall */
|
||||||
-ETIMEDOUT, /* timeout */
|
-ETIMEDOUT, /* timeout */
|
||||||
-EPROTO, /* pid err */
|
-EPROTO, /* pid err */
|
||||||
@ -203,14 +202,14 @@ static void admhcd_lock(struct admhcd *ahcd)
|
|||||||
{
|
{
|
||||||
spin_lock_irqsave(&ahcd->lock, ahcd->flags);
|
spin_lock_irqsave(&ahcd->lock, ahcd->flags);
|
||||||
ahcd->dma_en = admhcd_reg_get(ahcd, ADMHCD_REG_HOSTCONTROL) &
|
ahcd->dma_en = admhcd_reg_get(ahcd, ADMHCD_REG_HOSTCONTROL) &
|
||||||
ADMHCD_DMA_EN;
|
ADMHCD_DMA_EN;
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP);
|
admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void admhcd_unlock(struct admhcd *ahcd)
|
static void admhcd_unlock(struct admhcd *ahcd)
|
||||||
{
|
{
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL,
|
admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL,
|
||||||
ADMHCD_STATE_OP | ahcd->dma_en);
|
ADMHCD_STATE_OP | ahcd->dma_en);
|
||||||
spin_unlock_irqrestore(&ahcd->lock, ahcd->flags);
|
spin_unlock_irqrestore(&ahcd->lock, ahcd->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,12 +217,12 @@ static struct admhcd_td *admhcd_td_alloc(struct admhcd_ed *ed, struct urb *urb)
|
|||||||
{
|
{
|
||||||
struct admhcd_td *tdn, *td;
|
struct admhcd_td *tdn, *td;
|
||||||
|
|
||||||
tdn = kmalloc(sizeof(struct admhcd_td), GFP_ATOMIC);
|
tdn = kzalloc(sizeof(*tdn), GFP_ATOMIC);
|
||||||
if (!tdn)
|
if (!tdn)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
tdn->real = tdn;
|
tdn->real = tdn;
|
||||||
tdn = (struct admhcd_td *)KSEG1ADDR(tdn);
|
tdn = (struct admhcd_td *)KSEG1ADDR(tdn);
|
||||||
memset(tdn, 0, sizeof(struct admhcd_td));
|
|
||||||
if (ed->cur == NULL) {
|
if (ed->cur == NULL) {
|
||||||
ed->cur = tdn;
|
ed->cur = tdn;
|
||||||
ed->head = tdn;
|
ed->head = tdn;
|
||||||
@ -265,7 +264,7 @@ static void admhcd_td_free(struct admhcd_ed *ed, struct urb *urb)
|
|||||||
in the DMA chain
|
in the DMA chain
|
||||||
*/
|
*/
|
||||||
static struct admhcd_ed *admhcd_get_ed(struct admhcd *ahcd,
|
static struct admhcd_ed *admhcd_get_ed(struct admhcd *ahcd,
|
||||||
struct usb_host_endpoint *ep, struct urb *urb)
|
struct usb_host_endpoint *ep, struct urb *urb)
|
||||||
{
|
{
|
||||||
struct admhcd_ed *hosthead;
|
struct admhcd_ed *hosthead;
|
||||||
struct admhcd_ed *found = NULL, *ed = NULL;
|
struct admhcd_ed *found = NULL, *ed = NULL;
|
||||||
@ -284,10 +283,9 @@ static struct admhcd_ed *admhcd_get_ed(struct admhcd *ahcd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = kmalloc(sizeof(struct admhcd_ed), GFP_ATOMIC);
|
found = kzalloc(sizeof(*found), GFP_ATOMIC);
|
||||||
if (!found)
|
if (!found)
|
||||||
goto out;
|
goto out;
|
||||||
memset(found, 0, sizeof(struct admhcd_ed));
|
|
||||||
found->real = found;
|
found->real = found;
|
||||||
found->ep = ep;
|
found->ep = ep;
|
||||||
found = (struct admhcd_ed *)KSEG1ADDR(found);
|
found = (struct admhcd_ed *)KSEG1ADDR(found);
|
||||||
@ -313,7 +311,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct admhcd_td *admhcd_td_fill(u32 control, struct admhcd_td *td,
|
static struct admhcd_td *admhcd_td_fill(u32 control, struct admhcd_td *td,
|
||||||
dma_addr_t data, int len)
|
dma_addr_t data, int len)
|
||||||
{
|
{
|
||||||
td->buffer = data;
|
td->buffer = data;
|
||||||
td->buflen = len;
|
td->buflen = len;
|
||||||
@ -342,7 +340,7 @@ static void admhcd_ed_start(struct admhcd *ahcd, struct admhcd_ed *ed)
|
|||||||
ahcd->dma_en |= ADMHCD_DMA_EN;
|
ahcd->dma_en |= ADMHCD_DMA_EN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t adm5120hcd_irq(struct usb_hcd *hcd)
|
static irqreturn_t admhcd_irq(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
||||||
u32 intstatus;
|
u32 intstatus;
|
||||||
@ -350,12 +348,14 @@ static irqreturn_t adm5120hcd_irq(struct usb_hcd *hcd)
|
|||||||
intstatus = admhcd_reg_get(ahcd, ADMHCD_REG_INTSTATUS);
|
intstatus = admhcd_reg_get(ahcd, ADMHCD_REG_INTSTATUS);
|
||||||
if (intstatus & ADMHCD_INT_FATAL) {
|
if (intstatus & ADMHCD_INT_FATAL) {
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_FATAL);
|
admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_FATAL);
|
||||||
//
|
/* FIXME: handle fatal interrupts */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intstatus & ADMHCD_INT_SW) {
|
if (intstatus & ADMHCD_INT_SW) {
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_SW);
|
admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_SW);
|
||||||
//
|
/* FIXME: handle software interrupts */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intstatus & ADMHCD_INT_TD) {
|
if (intstatus & ADMHCD_INT_TD) {
|
||||||
struct admhcd_ed *ed, *head;
|
struct admhcd_ed *ed, *head;
|
||||||
|
|
||||||
@ -389,7 +389,7 @@ static irqreturn_t adm5120hcd_irq(struct usb_hcd *hcd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
|
static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
|
||||||
struct urb *urb, gfp_t mem_flags)
|
struct urb *urb, gfp_t mem_flags)
|
||||||
{
|
{
|
||||||
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
||||||
struct admhcd_ed *ed;
|
struct admhcd_ed *ed;
|
||||||
@ -404,26 +404,26 @@ static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
switch(usb_pipetype(pipe)) {
|
switch(usb_pipetype(pipe)) {
|
||||||
case PIPE_CONTROL:
|
case PIPE_CONTROL:
|
||||||
size = 2;
|
size = 2;
|
||||||
case PIPE_INTERRUPT:
|
case PIPE_INTERRUPT:
|
||||||
case PIPE_BULK:
|
case PIPE_BULK:
|
||||||
default:
|
default:
|
||||||
size += urb->transfer_buffer_length / 4096;
|
size += urb->transfer_buffer_length / 4096;
|
||||||
if (urb->transfer_buffer_length % 4096)
|
if (urb->transfer_buffer_length % 4096)
|
||||||
size++;
|
size++;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
size++;
|
size++;
|
||||||
else if (urb->transfer_flags & URB_ZERO_PACKET &&
|
else if (urb->transfer_flags & URB_ZERO_PACKET &&
|
||||||
!(urb->transfer_buffer_length %
|
!(urb->transfer_buffer_length %
|
||||||
usb_maxpacket(urb->dev, pipe, usb_pipeout(pipe)))) {
|
usb_maxpacket(urb->dev, pipe, usb_pipeout(pipe)))) {
|
||||||
size++;
|
size++;
|
||||||
zero = 1;
|
zero = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PIPE_ISOCHRONOUS:
|
case PIPE_ISOCHRONOUS:
|
||||||
size = urb->number_of_packets;
|
size = urb->number_of_packets;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
admhcd_lock(ahcd);
|
admhcd_lock(ahcd);
|
||||||
@ -451,52 +451,52 @@ static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch(usb_pipetype(pipe)) {
|
switch(usb_pipetype(pipe)) {
|
||||||
case PIPE_CONTROL:
|
case PIPE_CONTROL:
|
||||||
td = admhcd_td_fill(ADMHCD_TD_SETUP | ADMHCD_TD_DATA0,
|
td = admhcd_td_fill(ADMHCD_TD_SETUP | ADMHCD_TD_DATA0,
|
||||||
td, (dma_addr_t)urb->setup_packet, 8);
|
td, (dma_addr_t)urb->setup_packet, 8);
|
||||||
while (data_len > 0) {
|
while (data_len > 0) {
|
||||||
td = admhcd_td_fill(ADMHCD_TD_DATA1
|
td = admhcd_td_fill(ADMHCD_TD_DATA1
|
||||||
| ADMHCD_TD_R |
|
| ADMHCD_TD_R |
|
||||||
(usb_pipeout(pipe) ?
|
(usb_pipeout(pipe) ?
|
||||||
ADMHCD_TD_OUT : ADMHCD_TD_IN), td,
|
ADMHCD_TD_OUT : ADMHCD_TD_IN), td,
|
||||||
data, data_len % 4097);
|
data, data_len % 4097);
|
||||||
data_len -= 4096;
|
data_len -= 4096;
|
||||||
}
|
}
|
||||||
admhcd_td_fill(ADMHCD_TD_DATA1 | (usb_pipeout(pipe) ?
|
admhcd_td_fill(ADMHCD_TD_DATA1 | (usb_pipeout(pipe) ?
|
||||||
ADMHCD_TD_IN : ADMHCD_TD_OUT), td,
|
ADMHCD_TD_IN : ADMHCD_TD_OUT), td,
|
||||||
data, 0);
|
data, 0);
|
||||||
break;
|
break;
|
||||||
case PIPE_INTERRUPT:
|
case PIPE_INTERRUPT:
|
||||||
case PIPE_BULK:
|
case PIPE_BULK:
|
||||||
//info ok for interrupt?
|
//info ok for interrupt?
|
||||||
i = 0;
|
i = 0;
|
||||||
while(data_len > 4096) {
|
while(data_len > 4096) {
|
||||||
td = admhcd_td_fill((usb_pipeout(pipe) ?
|
|
||||||
ADMHCD_TD_OUT :
|
|
||||||
ADMHCD_TD_IN | ADMHCD_TD_R) |
|
|
||||||
(i ? ADMHCD_TD_TOGGLE : toggle), td,
|
|
||||||
data, 4096);
|
|
||||||
data += 4096;
|
|
||||||
data_len -= 4096;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
td = admhcd_td_fill((usb_pipeout(pipe) ?
|
td = admhcd_td_fill((usb_pipeout(pipe) ?
|
||||||
ADMHCD_TD_OUT : ADMHCD_TD_IN) |
|
ADMHCD_TD_OUT :
|
||||||
(i ? ADMHCD_TD_TOGGLE : toggle), td, data, data_len);
|
ADMHCD_TD_IN | ADMHCD_TD_R) |
|
||||||
|
(i ? ADMHCD_TD_TOGGLE : toggle), td,
|
||||||
|
data, 4096);
|
||||||
|
data += 4096;
|
||||||
|
data_len -= 4096;
|
||||||
i++;
|
i++;
|
||||||
if (zero)
|
}
|
||||||
admhcd_td_fill((usb_pipeout(pipe) ?
|
td = admhcd_td_fill((usb_pipeout(pipe) ?
|
||||||
ADMHCD_TD_OUT : ADMHCD_TD_IN) |
|
ADMHCD_TD_OUT : ADMHCD_TD_IN) |
|
||||||
(i ? ADMHCD_TD_TOGGLE : toggle), td, 0, 0);
|
(i ? ADMHCD_TD_TOGGLE : toggle), td, data, data_len);
|
||||||
break;
|
i++;
|
||||||
case PIPE_ISOCHRONOUS:
|
if (zero)
|
||||||
for (i = 0; i < urb->number_of_packets; i++) {
|
admhcd_td_fill((usb_pipeout(pipe) ?
|
||||||
td = admhcd_td_fill(ADMHCD_TD_ISO |
|
ADMHCD_TD_OUT : ADMHCD_TD_IN) |
|
||||||
((urb->start_frame + i) & 0xffff), td,
|
(i ? ADMHCD_TD_TOGGLE : toggle), td, 0, 0);
|
||||||
data + urb->iso_frame_desc[i].offset,
|
break;
|
||||||
urb->iso_frame_desc[i].length);
|
case PIPE_ISOCHRONOUS:
|
||||||
}
|
for (i = 0; i < urb->number_of_packets; i++) {
|
||||||
break;
|
td = admhcd_td_fill(ADMHCD_TD_ISO |
|
||||||
|
((urb->start_frame + i) & 0xffff), td,
|
||||||
|
data + urb->iso_frame_desc[i].offset,
|
||||||
|
urb->iso_frame_desc[i].length);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
urb->hcpriv = ed;
|
urb->hcpriv = ed;
|
||||||
admhcd_ed_start(ahcd, ed);
|
admhcd_ed_start(ahcd, ed);
|
||||||
@ -551,6 +551,7 @@ static void admhcd_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoin
|
|||||||
}
|
}
|
||||||
for (edt = head; edt->next != ed; edt = edt->next);
|
for (edt = head; edt->next != ed; edt = edt->next);
|
||||||
edt->next = ed->next;
|
edt->next = ed->next;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
kfree(ed->real);
|
kfree(ed->real);
|
||||||
out:
|
out:
|
||||||
@ -591,7 +592,7 @@ static __u8 root_hub_hub_des[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int admhcd_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
static int admhcd_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||||
u16 wIndex, char *buf, u16 wLength)
|
u16 wIndex, char *buf, u16 wLength)
|
||||||
{
|
{
|
||||||
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
||||||
int retval = 0, len;
|
int retval = 0, len;
|
||||||
@ -707,45 +708,45 @@ static int admhcd_start(struct usb_hcd *hcd)
|
|||||||
|
|
||||||
spin_lock_irqsave(&ahcd->lock, flags);
|
spin_lock_irqsave(&ahcd->lock, flags);
|
||||||
|
|
||||||
/* Initialise the HCD registers */
|
/* Initialise the HCD registers */
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, 0);
|
admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, 0);
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
|
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_SW_RESET);
|
admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_SW_RESET);
|
||||||
|
|
||||||
while (admhcd_reg_get(ahcd, ADMHCD_REG_CONTROL) & ADMHCD_SW_RESET) {
|
while (admhcd_reg_get(ahcd, ADMHCD_REG_CONTROL) & ADMHCD_SW_RESET) {
|
||||||
printk(KERN_WARNING PFX "waiting for reset to complete\n");
|
printk(KERN_WARNING PFX "waiting for reset to complete\n");
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
hcd->uses_new_polling = 1;
|
hcd->uses_new_polling = 1;
|
||||||
|
|
||||||
/* Enable USB host mode */
|
/* Enable USB host mode */
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_HOST_EN);
|
admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_HOST_EN);
|
||||||
|
|
||||||
/* Set host specific settings */
|
/* Set host specific settings */
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, 0x00000000);
|
admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, 0x00000000);
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_FMINTERVAL, 0x20002edf);
|
admhcd_reg_set(ahcd, ADMHCD_REG_FMINTERVAL, 0x20002edf);
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_LSTHRESH, 0x628);
|
admhcd_reg_set(ahcd, ADMHCD_REG_LSTHRESH, 0x628);
|
||||||
|
|
||||||
/* Set interrupts */
|
/* Set interrupts */
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE,
|
admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, ADMHCD_INT_ACT |
|
||||||
ADMHCD_INT_ACT | ADMHCD_INT_FATAL | ADMHCD_INT_SW | ADMHCD_INT_TD);
|
ADMHCD_INT_FATAL | ADMHCD_INT_SW | ADMHCD_INT_TD);
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS,
|
admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_ACT |
|
||||||
ADMHCD_INT_ACT | ADMHCD_INT_FATAL | ADMHCD_INT_SW | ADMHCD_INT_TD);
|
ADMHCD_INT_FATAL | ADMHCD_INT_SW | ADMHCD_INT_TD);
|
||||||
|
|
||||||
/* Power on all ports */
|
/* Power on all ports */
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_RHDESCR, ADMHCD_NPS | ADMHCD_LPSC);
|
admhcd_reg_set(ahcd, ADMHCD_REG_RHDESCR, ADMHCD_NPS | ADMHCD_LPSC);
|
||||||
|
|
||||||
/* HCD is now operationnal */
|
/* HCD is now operationnal */
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP);
|
admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP);
|
||||||
|
|
||||||
hcd->state = HC_STATE_RUNNING;
|
hcd->state = HC_STATE_RUNNING;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ahcd->lock, flags);
|
spin_unlock_irqrestore(&ahcd->lock, flags);
|
||||||
|
|
||||||
printk(KERN_DEBUG PFX "returning 0 from admhcd_start\n");
|
printk(KERN_DEBUG PFX "returning 0 from admhcd_start\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int admhcd_sw_reset(struct admhcd *ahcd)
|
static int admhcd_sw_reset(struct admhcd *ahcd)
|
||||||
@ -757,11 +758,11 @@ static int admhcd_sw_reset(struct admhcd *ahcd)
|
|||||||
spin_lock_irqsave(&ahcd->lock, flags);
|
spin_lock_irqsave(&ahcd->lock, flags);
|
||||||
|
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, 0);
|
admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, 0);
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
|
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_SW_RESET);
|
admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_SW_RESET);
|
||||||
|
|
||||||
while (--retries) {
|
while (--retries) {
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
if (!(admhcd_reg_get(ahcd, ADMHCD_REG_CONTROL) & ADMHCD_SW_RESET))
|
if (!(admhcd_reg_get(ahcd, ADMHCD_REG_CONTROL) & ADMHCD_SW_RESET))
|
||||||
break;
|
break;
|
||||||
@ -777,7 +778,7 @@ static int admhcd_sw_reset(struct admhcd *ahcd)
|
|||||||
static int admhcd_reset(struct usb_hcd *hcd)
|
static int admhcd_reset(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
||||||
u32 state = 0;
|
u32 state = 0;
|
||||||
int ret, timeout = 15; /* ms */
|
int ret, timeout = 15; /* ms */
|
||||||
unsigned long t;
|
unsigned long t;
|
||||||
|
|
||||||
@ -787,32 +788,32 @@ static int admhcd_reset(struct usb_hcd *hcd)
|
|||||||
|
|
||||||
t = jiffies + msecs_to_jiffies(timeout);
|
t = jiffies + msecs_to_jiffies(timeout);
|
||||||
do {
|
do {
|
||||||
spin_lock_irq(&ahcd->lock);
|
spin_lock_irq(&ahcd->lock);
|
||||||
state = admhcd_reg_get(ahcd, ADMHCD_REG_HOSTCONTROL);
|
state = admhcd_reg_get(ahcd, ADMHCD_REG_HOSTCONTROL);
|
||||||
spin_unlock_irq(&ahcd->lock);
|
spin_unlock_irq(&ahcd->lock);
|
||||||
state &= ADMHCD_STATE_MASK;
|
state &= ADMHCD_STATE_MASK;
|
||||||
if (state == ADMHCD_STATE_RST)
|
if (state == ADMHCD_STATE_RST)
|
||||||
break;
|
break;
|
||||||
msleep(4);
|
msleep(4);
|
||||||
} while (time_before_eq(jiffies, t));
|
} while (time_before_eq(jiffies, t));
|
||||||
|
|
||||||
if (state != ADMHCD_STATE_RST) {
|
if (state != ADMHCD_STATE_RST) {
|
||||||
printk(KERN_WARNING "%s: device not ready after %dms\n",
|
printk(KERN_WARNING "%s: device not ready after %dms\n",
|
||||||
hcd_name, timeout);
|
hcd_name, timeout);
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void admhcd_stop(struct usb_hcd *hcd)
|
static void admhcd_stop(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
struct admhcd *ahcd = hcd_to_admhcd(hcd);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
spin_lock_irqsave(&ahcd->lock, flags);
|
spin_lock_irqsave(&ahcd->lock, flags);
|
||||||
admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, 0);
|
admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, 0);
|
||||||
|
|
||||||
/* Set global control of power for ports */
|
/* Set global control of power for ports */
|
||||||
val = admhcd_reg_get(ahcd, ADMHCD_REG_RHDESCR);
|
val = admhcd_reg_get(ahcd, ADMHCD_REG_RHDESCR);
|
||||||
@ -830,7 +831,7 @@ static struct hc_driver adm5120_hc_driver = {
|
|||||||
.description = hcd_name,
|
.description = hcd_name,
|
||||||
.product_desc = "ADM5120 HCD",
|
.product_desc = "ADM5120 HCD",
|
||||||
.hcd_priv_size = sizeof(struct admhcd),
|
.hcd_priv_size = sizeof(struct admhcd),
|
||||||
.irq = adm5120hcd_irq,
|
.irq = admhcd_irq,
|
||||||
.flags = HCD_USB11,
|
.flags = HCD_USB11,
|
||||||
.urb_enqueue = admhcd_urb_enqueue,
|
.urb_enqueue = admhcd_urb_enqueue,
|
||||||
.urb_dequeue = admhcd_urb_dequeue,
|
.urb_dequeue = admhcd_urb_dequeue,
|
||||||
@ -847,51 +848,51 @@ static struct hc_driver adm5120_hc_driver = {
|
|||||||
|
|
||||||
static int __init adm5120hcd_probe(struct platform_device *pdev)
|
static int __init adm5120hcd_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct usb_hcd *hcd;
|
struct usb_hcd *hcd;
|
||||||
struct admhcd *ahcd;
|
struct admhcd *ahcd;
|
||||||
struct resource *data;
|
struct resource *data;
|
||||||
void __iomem *data_reg;
|
void __iomem *data_reg;
|
||||||
|
|
||||||
int err = 0, irq;
|
int err = 0, irq;
|
||||||
|
|
||||||
if (pdev->num_resources < 2) {
|
if (pdev->num_resources < 2) {
|
||||||
printk(KERN_WARNING PFX "not enough resources\n");
|
printk(KERN_WARNING PFX "not enough resources\n");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
|
||||||
if (pdev->dev.dma_mask) {
|
if (pdev->dev.dma_mask) {
|
||||||
printk(KERN_DEBUG PFX "no we won't dma\n");
|
printk(KERN_DEBUG PFX "no we won't dma\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data || irq < 0) {
|
if (!data || irq < 0) {
|
||||||
printk(KERN_DEBUG PFX "either IRQ or data resource is invalid\n");
|
printk(KERN_DEBUG PFX "either IRQ or data resource is invalid\n");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!request_mem_region(data->start, resource_len(data), hcd_name)) {
|
if (!request_mem_region(data->start, resource_len(data), hcd_name)) {
|
||||||
printk(KERN_DEBUG PFX "cannot request memory regions for the data resource\n");
|
printk(KERN_DEBUG PFX "cannot request memory regions for the data resource\n");
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_reg = ioremap(data->start, resource_len(data));
|
data_reg = ioremap(data->start, resource_len(data));
|
||||||
if (data_reg == NULL) {
|
if (data_reg == NULL) {
|
||||||
printk(KERN_DEBUG PFX "unable to ioremap\n");
|
printk(KERN_DEBUG PFX "unable to ioremap\n");
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_mem;
|
goto out_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
hcd = usb_create_hcd(&adm5120_hc_driver, &pdev->dev, pdev->dev.bus_id);
|
hcd = usb_create_hcd(&adm5120_hc_driver, &pdev->dev, pdev->dev.bus_id);
|
||||||
if (!hcd) {
|
if (!hcd) {
|
||||||
printk(KERN_DEBUG PFX "unable to create the hcd\n");
|
printk(KERN_DEBUG PFX "unable to create the hcd\n");
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_unmap;
|
goto out_unmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
hcd->rsrc_start = data->start;
|
hcd->rsrc_start = data->start;
|
||||||
|
Loading…
Reference in New Issue
Block a user