diff options
Diffstat (limited to 'drivers/usb/host/r8a66597-hcd.c')
-rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 256 |
1 files changed, 180 insertions, 76 deletions
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 9f80e5285575..f4fa93dabdde 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -46,15 +46,17 @@ MODULE_LICENSE("GPL"); | |||
46 | MODULE_AUTHOR("Yoshihiro Shimoda"); | 46 | MODULE_AUTHOR("Yoshihiro Shimoda"); |
47 | MODULE_ALIAS("platform:r8a66597_hcd"); | 47 | MODULE_ALIAS("platform:r8a66597_hcd"); |
48 | 48 | ||
49 | #define DRIVER_VERSION "29 May 2007" | 49 | #define DRIVER_VERSION "10 Apr 2008" |
50 | 50 | ||
51 | static const char hcd_name[] = "r8a66597_hcd"; | 51 | static const char hcd_name[] = "r8a66597_hcd"; |
52 | 52 | ||
53 | /* module parameters */ | 53 | /* module parameters */ |
54 | #if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) | ||
54 | static unsigned short clock = XTAL12; | 55 | static unsigned short clock = XTAL12; |
55 | module_param(clock, ushort, 0644); | 56 | module_param(clock, ushort, 0644); |
56 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " | 57 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " |
57 | "(default=0)"); | 58 | "(default=0)"); |
59 | #endif | ||
58 | 60 | ||
59 | static unsigned short vif = LDRV; | 61 | static unsigned short vif = LDRV; |
60 | module_param(vif, ushort, 0644); | 62 | module_param(vif, ushort, 0644); |
@@ -106,11 +108,22 @@ static void set_devadd_reg(struct r8a66597 *r8a66597, u8 r8a66597_address, | |||
106 | r8a66597_write(r8a66597, val, devadd_reg); | 108 | r8a66597_write(r8a66597, val, devadd_reg); |
107 | } | 109 | } |
108 | 110 | ||
109 | static int enable_controller(struct r8a66597 *r8a66597) | 111 | static int r8a66597_clock_enable(struct r8a66597 *r8a66597) |
110 | { | 112 | { |
111 | u16 tmp; | 113 | u16 tmp; |
112 | int i = 0; | 114 | int i = 0; |
113 | 115 | ||
116 | #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) | ||
117 | do { | ||
118 | r8a66597_write(r8a66597, SCKE, SYSCFG0); | ||
119 | tmp = r8a66597_read(r8a66597, SYSCFG0); | ||
120 | if (i++ > 1000) { | ||
121 | err("register access fail."); | ||
122 | return -ENXIO; | ||
123 | } | ||
124 | } while ((tmp & SCKE) != SCKE); | ||
125 | r8a66597_write(r8a66597, 0x04, 0x02); | ||
126 | #else | ||
114 | do { | 127 | do { |
115 | r8a66597_write(r8a66597, USBE, SYSCFG0); | 128 | r8a66597_write(r8a66597, USBE, SYSCFG0); |
116 | tmp = r8a66597_read(r8a66597, SYSCFG0); | 129 | tmp = r8a66597_read(r8a66597, SYSCFG0); |
@@ -132,13 +145,63 @@ static int enable_controller(struct r8a66597 *r8a66597) | |||
132 | return -ENXIO; | 145 | return -ENXIO; |
133 | } | 146 | } |
134 | } while ((tmp & SCKE) != SCKE); | 147 | } while ((tmp & SCKE) != SCKE); |
148 | #endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static void r8a66597_clock_disable(struct r8a66597 *r8a66597) | ||
154 | { | ||
155 | r8a66597_bclr(r8a66597, SCKE, SYSCFG0); | ||
156 | udelay(1); | ||
157 | #if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) | ||
158 | r8a66597_bclr(r8a66597, PLLC, SYSCFG0); | ||
159 | r8a66597_bclr(r8a66597, XCKE, SYSCFG0); | ||
160 | r8a66597_bclr(r8a66597, USBE, SYSCFG0); | ||
161 | #endif | ||
162 | } | ||
163 | |||
164 | static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port) | ||
165 | { | ||
166 | u16 val; | ||
167 | |||
168 | val = port ? DRPD : DCFM | DRPD; | ||
169 | r8a66597_bset(r8a66597, val, get_syscfg_reg(port)); | ||
170 | r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); | ||
171 | |||
172 | r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, get_dmacfg_reg(port)); | ||
173 | r8a66597_bclr(r8a66597, DTCHE, get_intenb_reg(port)); | ||
174 | r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); | ||
175 | } | ||
135 | 176 | ||
136 | r8a66597_bset(r8a66597, DCFM | DRPD, SYSCFG0); | 177 | static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port) |
137 | r8a66597_bset(r8a66597, DRPD, SYSCFG1); | 178 | { |
179 | u16 val, tmp; | ||
180 | |||
181 | r8a66597_write(r8a66597, 0, get_intenb_reg(port)); | ||
182 | r8a66597_write(r8a66597, 0, get_intsts_reg(port)); | ||
183 | |||
184 | r8a66597_port_power(r8a66597, port, 0); | ||
185 | |||
186 | do { | ||
187 | tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS; | ||
188 | udelay(640); | ||
189 | } while (tmp == EDGESTS); | ||
190 | |||
191 | val = port ? DRPD : DCFM | DRPD; | ||
192 | r8a66597_bclr(r8a66597, val, get_syscfg_reg(port)); | ||
193 | r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port)); | ||
194 | } | ||
195 | |||
196 | static int enable_controller(struct r8a66597 *r8a66597) | ||
197 | { | ||
198 | int ret, port; | ||
199 | |||
200 | ret = r8a66597_clock_enable(r8a66597); | ||
201 | if (ret < 0) | ||
202 | return ret; | ||
138 | 203 | ||
139 | r8a66597_bset(r8a66597, vif & LDRV, PINCFG); | 204 | r8a66597_bset(r8a66597, vif & LDRV, PINCFG); |
140 | r8a66597_bset(r8a66597, HSE, SYSCFG0); | ||
141 | r8a66597_bset(r8a66597, HSE, SYSCFG1); | ||
142 | r8a66597_bset(r8a66597, USBE, SYSCFG0); | 205 | r8a66597_bset(r8a66597, USBE, SYSCFG0); |
143 | 206 | ||
144 | r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0); | 207 | r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0); |
@@ -146,53 +209,30 @@ static int enable_controller(struct r8a66597 *r8a66597) | |||
146 | r8a66597_bset(r8a66597, BRDY0, BRDYENB); | 209 | r8a66597_bset(r8a66597, BRDY0, BRDYENB); |
147 | r8a66597_bset(r8a66597, BEMP0, BEMPENB); | 210 | r8a66597_bset(r8a66597, BEMP0, BEMPENB); |
148 | 211 | ||
149 | r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA0CFG); | ||
150 | r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA1CFG); | ||
151 | |||
152 | r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL); | 212 | r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL); |
153 | r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL); | 213 | r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL); |
154 | r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL); | 214 | r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL); |
155 | |||
156 | r8a66597_bset(r8a66597, TRNENSEL, SOFCFG); | 215 | r8a66597_bset(r8a66597, TRNENSEL, SOFCFG); |
157 | 216 | ||
158 | r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1); | 217 | r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1); |
159 | r8a66597_bclr(r8a66597, DTCHE, INTENB1); | 218 | |
160 | r8a66597_bset(r8a66597, ATTCHE, INTENB1); | 219 | for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) |
161 | r8a66597_bclr(r8a66597, DTCHE, INTENB2); | 220 | r8a66597_enable_port(r8a66597, port); |
162 | r8a66597_bset(r8a66597, ATTCHE, INTENB2); | ||
163 | 221 | ||
164 | return 0; | 222 | return 0; |
165 | } | 223 | } |
166 | 224 | ||
167 | static void disable_controller(struct r8a66597 *r8a66597) | 225 | static void disable_controller(struct r8a66597 *r8a66597) |
168 | { | 226 | { |
169 | u16 tmp; | 227 | int port; |
170 | 228 | ||
171 | r8a66597_write(r8a66597, 0, INTENB0); | 229 | r8a66597_write(r8a66597, 0, INTENB0); |
172 | r8a66597_write(r8a66597, 0, INTENB1); | ||
173 | r8a66597_write(r8a66597, 0, INTENB2); | ||
174 | r8a66597_write(r8a66597, 0, INTSTS0); | 230 | r8a66597_write(r8a66597, 0, INTSTS0); |
175 | r8a66597_write(r8a66597, 0, INTSTS1); | ||
176 | r8a66597_write(r8a66597, 0, INTSTS2); | ||
177 | |||
178 | r8a66597_port_power(r8a66597, 0, 0); | ||
179 | r8a66597_port_power(r8a66597, 1, 0); | ||
180 | |||
181 | do { | ||
182 | tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS; | ||
183 | udelay(640); | ||
184 | } while (tmp == EDGESTS); | ||
185 | 231 | ||
186 | r8a66597_bclr(r8a66597, DCFM | DRPD, SYSCFG0); | 232 | for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) |
187 | r8a66597_bclr(r8a66597, DRPD, SYSCFG1); | 233 | r8a66597_disable_port(r8a66597, port); |
188 | r8a66597_bclr(r8a66597, HSE, SYSCFG0); | ||
189 | r8a66597_bclr(r8a66597, HSE, SYSCFG1); | ||
190 | 234 | ||
191 | r8a66597_bclr(r8a66597, SCKE, SYSCFG0); | 235 | r8a66597_clock_disable(r8a66597); |
192 | udelay(1); | ||
193 | r8a66597_bclr(r8a66597, PLLC, SYSCFG0); | ||
194 | r8a66597_bclr(r8a66597, XCKE, SYSCFG0); | ||
195 | r8a66597_bclr(r8a66597, USBE, SYSCFG0); | ||
196 | } | 236 | } |
197 | 237 | ||
198 | static int get_parent_r8a66597_address(struct r8a66597 *r8a66597, | 238 | static int get_parent_r8a66597_address(struct r8a66597 *r8a66597, |
@@ -577,13 +617,9 @@ static void pipe_buffer_setting(struct r8a66597 *r8a66597, | |||
577 | PIPEBUF); | 617 | PIPEBUF); |
578 | r8a66597_write(r8a66597, make_devsel(info->address) | info->maxpacket, | 618 | r8a66597_write(r8a66597, make_devsel(info->address) | info->maxpacket, |
579 | PIPEMAXP); | 619 | PIPEMAXP); |
580 | if (info->interval) | ||
581 | info->interval--; | ||
582 | r8a66597_write(r8a66597, info->interval, PIPEPERI); | 620 | r8a66597_write(r8a66597, info->interval, PIPEPERI); |
583 | } | 621 | } |
584 | 622 | ||
585 | |||
586 | |||
587 | /* this function must be called with interrupt disabled */ | 623 | /* this function must be called with interrupt disabled */ |
588 | static void pipe_setting(struct r8a66597 *r8a66597, struct r8a66597_td *td) | 624 | static void pipe_setting(struct r8a66597 *r8a66597, struct r8a66597_td *td) |
589 | { | 625 | { |
@@ -715,6 +751,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597, | |||
715 | struct r8a66597_pipe *pipe, | 751 | struct r8a66597_pipe *pipe, |
716 | struct urb *urb) | 752 | struct urb *urb) |
717 | { | 753 | { |
754 | #if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) | ||
718 | int i; | 755 | int i; |
719 | struct r8a66597_pipe_info *info = &pipe->info; | 756 | struct r8a66597_pipe_info *info = &pipe->info; |
720 | 757 | ||
@@ -742,6 +779,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597, | |||
742 | break; | 779 | break; |
743 | } | 780 | } |
744 | } | 781 | } |
782 | #endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ | ||
745 | } | 783 | } |
746 | 784 | ||
747 | /* this function must be called with interrupt disabled */ | 785 | /* this function must be called with interrupt disabled */ |
@@ -825,6 +863,25 @@ static void disable_r8a66597_pipe_all(struct r8a66597 *r8a66597, | |||
825 | dev->dma_map = 0; | 863 | dev->dma_map = 0; |
826 | } | 864 | } |
827 | 865 | ||
866 | static unsigned long get_timer_interval(struct urb *urb, __u8 interval) | ||
867 | { | ||
868 | __u8 i; | ||
869 | unsigned long time = 1; | ||
870 | |||
871 | if (usb_pipeisoc(urb->pipe)) | ||
872 | return 0; | ||
873 | |||
874 | if (get_r8a66597_usb_speed(urb->dev->speed) == HSMODE) { | ||
875 | for (i = 0; i < (interval - 1); i++) | ||
876 | time *= 2; | ||
877 | time = time * 125 / 1000; /* uSOF -> msec */ | ||
878 | } else { | ||
879 | time = interval; | ||
880 | } | ||
881 | |||
882 | return time; | ||
883 | } | ||
884 | |||
828 | /* this function must be called with interrupt disabled */ | 885 | /* this function must be called with interrupt disabled */ |
829 | static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, | 886 | static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, |
830 | struct usb_host_endpoint *hep, | 887 | struct usb_host_endpoint *hep, |
@@ -840,7 +897,16 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, | |||
840 | & USB_ENDPOINT_XFERTYPE_MASK); | 897 | & USB_ENDPOINT_XFERTYPE_MASK); |
841 | info.bufnum = get_bufnum(info.pipenum); | 898 | info.bufnum = get_bufnum(info.pipenum); |
842 | info.buf_bsize = get_buf_bsize(info.pipenum); | 899 | info.buf_bsize = get_buf_bsize(info.pipenum); |
843 | info.interval = ep->bInterval; | 900 | if (info.type == R8A66597_BULK) { |
901 | info.interval = 0; | ||
902 | info.timer_interval = 0; | ||
903 | } else { | ||
904 | if (ep->bInterval > IITV) | ||
905 | info.interval = IITV; | ||
906 | else | ||
907 | info.interval = ep->bInterval ? ep->bInterval - 1 : 0; | ||
908 | info.timer_interval = get_timer_interval(urb, ep->bInterval); | ||
909 | } | ||
844 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 910 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
845 | info.dir_in = 1; | 911 | info.dir_in = 1; |
846 | else | 912 | else |
@@ -876,10 +942,19 @@ static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum) | |||
876 | } | 942 | } |
877 | 943 | ||
878 | /* this function must be called with interrupt disabled */ | 944 | /* this function must be called with interrupt disabled */ |
879 | static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port) | 945 | static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, |
946 | u16 syssts) | ||
880 | { | 947 | { |
881 | r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) | 948 | if (syssts == SE0) { |
882 | | (1 << USB_PORT_FEAT_C_CONNECTION); | 949 | r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); |
950 | return; | ||
951 | } | ||
952 | |||
953 | if (syssts == FS_JSTS) | ||
954 | r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); | ||
955 | else if (syssts == LS_JSTS) | ||
956 | r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port)); | ||
957 | |||
883 | r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); | 958 | r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); |
884 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); | 959 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); |
885 | } | 960 | } |
@@ -960,9 +1035,9 @@ static void prepare_packet_read(struct r8a66597 *r8a66597, | |||
960 | r8a66597_write(r8a66597, TRCLR, | 1035 | r8a66597_write(r8a66597, TRCLR, |
961 | td->pipe->pipetre); | 1036 | td->pipe->pipetre); |
962 | r8a66597_write(r8a66597, | 1037 | r8a66597_write(r8a66597, |
963 | (urb->transfer_buffer_length | 1038 | DIV_ROUND_UP |
964 | + td->maxpacket - 1) | 1039 | (urb->transfer_buffer_length, |
965 | / td->maxpacket, | 1040 | td->maxpacket), |
966 | td->pipe->pipetrn); | 1041 | td->pipe->pipetrn); |
967 | r8a66597_bset(r8a66597, TRENB, | 1042 | r8a66597_bset(r8a66597, TRENB, |
968 | td->pipe->pipetre); | 1043 | td->pipe->pipetre); |
@@ -1021,8 +1096,7 @@ static void prepare_status_packet(struct r8a66597 *r8a66597, | |||
1021 | r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); | 1096 | r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); |
1022 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); | 1097 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); |
1023 | r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); | 1098 | r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); |
1024 | r8a66597_write(r8a66597, BCLR, CFIFOCTR); | 1099 | r8a66597_write(r8a66597, BCLR | BVAL, CFIFOCTR); |
1025 | r8a66597_write(r8a66597, BVAL, CFIFOCTR); | ||
1026 | enable_irq_empty(r8a66597, 0); | 1100 | enable_irq_empty(r8a66597, 0); |
1027 | } else { | 1101 | } else { |
1028 | r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); | 1102 | r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); |
@@ -1454,13 +1528,21 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) | |||
1454 | } | 1528 | } |
1455 | } | 1529 | } |
1456 | 1530 | ||
1531 | static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597) | ||
1532 | { | ||
1533 | mod_timer(&r8a66597->rh_timer, | ||
1534 | jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME)); | ||
1535 | } | ||
1536 | |||
1457 | static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port) | 1537 | static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port) |
1458 | { | 1538 | { |
1459 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; | 1539 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; |
1460 | 1540 | ||
1461 | rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; | 1541 | rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; |
1462 | rh->scount = R8A66597_MAX_SAMPLING; | 1542 | rh->scount = R8A66597_MAX_SAMPLING; |
1463 | mod_timer(&r8a66597->rh_timer, jiffies + msecs_to_jiffies(50)); | 1543 | r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) |
1544 | | (1 << USB_PORT_FEAT_C_CONNECTION); | ||
1545 | r8a66597_root_hub_start_polling(r8a66597); | ||
1464 | } | 1546 | } |
1465 | 1547 | ||
1466 | static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | 1548 | static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) |
@@ -1547,41 +1629,55 @@ static void r8a66597_root_hub_control(struct r8a66597 *r8a66597, int port) | |||
1547 | if ((tmp & USBRST) == USBRST) { | 1629 | if ((tmp & USBRST) == USBRST) { |
1548 | r8a66597_mdfy(r8a66597, UACT, USBRST | UACT, | 1630 | r8a66597_mdfy(r8a66597, UACT, USBRST | UACT, |
1549 | dvstctr_reg); | 1631 | dvstctr_reg); |
1550 | mod_timer(&r8a66597->rh_timer, | 1632 | r8a66597_root_hub_start_polling(r8a66597); |
1551 | jiffies + msecs_to_jiffies(50)); | ||
1552 | } else | 1633 | } else |
1553 | r8a66597_usb_connect(r8a66597, port); | 1634 | r8a66597_usb_connect(r8a66597, port); |
1554 | } | 1635 | } |
1555 | 1636 | ||
1637 | if (!(rh->port & (1 << USB_PORT_FEAT_CONNECTION))) { | ||
1638 | r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port)); | ||
1639 | r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); | ||
1640 | } | ||
1641 | |||
1556 | if (rh->scount > 0) { | 1642 | if (rh->scount > 0) { |
1557 | tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; | 1643 | tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; |
1558 | if (tmp == rh->old_syssts) { | 1644 | if (tmp == rh->old_syssts) { |
1559 | rh->scount--; | 1645 | rh->scount--; |
1560 | if (rh->scount == 0) { | 1646 | if (rh->scount == 0) |
1561 | if (tmp == FS_JSTS) { | 1647 | r8a66597_check_syssts(r8a66597, port, tmp); |
1562 | r8a66597_bset(r8a66597, HSE, | 1648 | else |
1563 | get_syscfg_reg(port)); | 1649 | r8a66597_root_hub_start_polling(r8a66597); |
1564 | r8a66597_usb_preconnect(r8a66597, port); | ||
1565 | } else if (tmp == LS_JSTS) { | ||
1566 | r8a66597_bclr(r8a66597, HSE, | ||
1567 | get_syscfg_reg(port)); | ||
1568 | r8a66597_usb_preconnect(r8a66597, port); | ||
1569 | } else if (tmp == SE0) | ||
1570 | r8a66597_bset(r8a66597, ATTCHE, | ||
1571 | get_intenb_reg(port)); | ||
1572 | } else { | ||
1573 | mod_timer(&r8a66597->rh_timer, | ||
1574 | jiffies + msecs_to_jiffies(50)); | ||
1575 | } | ||
1576 | } else { | 1650 | } else { |
1577 | rh->scount = R8A66597_MAX_SAMPLING; | 1651 | rh->scount = R8A66597_MAX_SAMPLING; |
1578 | rh->old_syssts = tmp; | 1652 | rh->old_syssts = tmp; |
1579 | mod_timer(&r8a66597->rh_timer, | 1653 | r8a66597_root_hub_start_polling(r8a66597); |
1580 | jiffies + msecs_to_jiffies(50)); | ||
1581 | } | 1654 | } |
1582 | } | 1655 | } |
1583 | } | 1656 | } |
1584 | 1657 | ||
1658 | static void r8a66597_interval_timer(unsigned long _r8a66597) | ||
1659 | { | ||
1660 | struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; | ||
1661 | unsigned long flags; | ||
1662 | u16 pipenum; | ||
1663 | struct r8a66597_td *td; | ||
1664 | |||
1665 | spin_lock_irqsave(&r8a66597->lock, flags); | ||
1666 | |||
1667 | for (pipenum = 0; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { | ||
1668 | if (!(r8a66597->interval_map & (1 << pipenum))) | ||
1669 | continue; | ||
1670 | if (timer_pending(&r8a66597->interval_timer[pipenum])) | ||
1671 | continue; | ||
1672 | |||
1673 | td = r8a66597_get_td(r8a66597, pipenum); | ||
1674 | if (td) | ||
1675 | start_transfer(r8a66597, td); | ||
1676 | } | ||
1677 | |||
1678 | spin_unlock_irqrestore(&r8a66597->lock, flags); | ||
1679 | } | ||
1680 | |||
1585 | static void r8a66597_td_timer(unsigned long _r8a66597) | 1681 | static void r8a66597_td_timer(unsigned long _r8a66597) |
1586 | { | 1682 | { |
1587 | struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; | 1683 | struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; |
@@ -1763,10 +1859,17 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | |||
1763 | urb->hcpriv = td; | 1859 | urb->hcpriv = td; |
1764 | 1860 | ||
1765 | if (request) { | 1861 | if (request) { |
1766 | ret = start_transfer(r8a66597, td); | 1862 | if (td->pipe->info.timer_interval) { |
1767 | if (ret < 0) { | 1863 | r8a66597->interval_map |= 1 << td->pipenum; |
1768 | list_del(&td->queue); | 1864 | mod_timer(&r8a66597->interval_timer[td->pipenum], |
1769 | kfree(td); | 1865 | jiffies + msecs_to_jiffies( |
1866 | td->pipe->info.timer_interval)); | ||
1867 | } else { | ||
1868 | ret = start_transfer(r8a66597, td); | ||
1869 | if (ret < 0) { | ||
1870 | list_del(&td->queue); | ||
1871 | kfree(td); | ||
1872 | } | ||
1770 | } | 1873 | } |
1771 | } else | 1874 | } else |
1772 | set_td_timer(r8a66597, td); | 1875 | set_td_timer(r8a66597, td); |
@@ -2107,13 +2210,11 @@ static struct hc_driver r8a66597_hc_driver = { | |||
2107 | #if defined(CONFIG_PM) | 2210 | #if defined(CONFIG_PM) |
2108 | static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state) | 2211 | static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state) |
2109 | { | 2212 | { |
2110 | pdev->dev.power.power_state = state; | ||
2111 | return 0; | 2213 | return 0; |
2112 | } | 2214 | } |
2113 | 2215 | ||
2114 | static int r8a66597_resume(struct platform_device *pdev) | 2216 | static int r8a66597_resume(struct platform_device *pdev) |
2115 | { | 2217 | { |
2116 | pdev->dev.power.power_state = PMSG_ON; | ||
2117 | return 0; | 2218 | return 0; |
2118 | } | 2219 | } |
2119 | #else /* if defined(CONFIG_PM) */ | 2220 | #else /* if defined(CONFIG_PM) */ |
@@ -2194,6 +2295,9 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
2194 | init_timer(&r8a66597->td_timer[i]); | 2295 | init_timer(&r8a66597->td_timer[i]); |
2195 | r8a66597->td_timer[i].function = r8a66597_td_timer; | 2296 | r8a66597->td_timer[i].function = r8a66597_td_timer; |
2196 | r8a66597->td_timer[i].data = (unsigned long)r8a66597; | 2297 | r8a66597->td_timer[i].data = (unsigned long)r8a66597; |
2298 | setup_timer(&r8a66597->interval_timer[i], | ||
2299 | r8a66597_interval_timer, | ||
2300 | (unsigned long)r8a66597); | ||
2197 | } | 2301 | } |
2198 | INIT_LIST_HEAD(&r8a66597->child_device); | 2302 | INIT_LIST_HEAD(&r8a66597->child_device); |
2199 | 2303 | ||