aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-at91.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ohci-at91.c')
-rw-r--r--drivers/usb/host/ohci-at91.c163
1 files changed, 86 insertions, 77 deletions
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index db8963f5fbce..09f597ad6e00 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -27,6 +27,10 @@
27#error "CONFIG_ARCH_AT91 must be defined." 27#error "CONFIG_ARCH_AT91 must be defined."
28#endif 28#endif
29 29
30#define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
31#define at91_for_each_port(index) \
32 for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
33
30/* interface and function clocks; sometimes also an AHB clock */ 34/* interface and function clocks; sometimes also an AHB clock */
31static struct clk *iclk, *fclk, *hclk; 35static struct clk *iclk, *fclk, *hclk;
32static int clocked; 36static int clocked;
@@ -240,26 +244,26 @@ ohci_at91_start (struct usb_hcd *hcd)
240 244
241static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable) 245static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
242{ 246{
243 if (port < 0 || port >= 2) 247 if (!valid_port(port))
244 return; 248 return;
245 249
246 if (!gpio_is_valid(pdata->vbus_pin[port])) 250 if (!gpio_is_valid(pdata->vbus_pin[port]))
247 return; 251 return;
248 252
249 gpio_set_value(pdata->vbus_pin[port], 253 gpio_set_value(pdata->vbus_pin[port],
250 !pdata->vbus_pin_active_low[port] ^ enable); 254 pdata->vbus_pin_active_low[port] ^ enable);
251} 255}
252 256
253static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) 257static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
254{ 258{
255 if (port < 0 || port >= 2) 259 if (!valid_port(port))
256 return -EINVAL; 260 return -EINVAL;
257 261
258 if (!gpio_is_valid(pdata->vbus_pin[port])) 262 if (!gpio_is_valid(pdata->vbus_pin[port]))
259 return -EINVAL; 263 return -EINVAL;
260 264
261 return gpio_get_value(pdata->vbus_pin[port]) ^ 265 return gpio_get_value(pdata->vbus_pin[port]) ^
262 !pdata->vbus_pin_active_low[port]; 266 pdata->vbus_pin_active_low[port];
263} 267}
264 268
265/* 269/*
@@ -271,9 +275,9 @@ static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
271 int length = ohci_hub_status_data(hcd, buf); 275 int length = ohci_hub_status_data(hcd, buf);
272 int port; 276 int port;
273 277
274 for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) { 278 at91_for_each_port(port) {
275 if (pdata->overcurrent_changed[port]) { 279 if (pdata->overcurrent_changed[port]) {
276 if (! length) 280 if (!length)
277 length = 1; 281 length = 1;
278 buf[0] |= 1 << (port + 1); 282 buf[0] |= 1 << (port + 1);
279 } 283 }
@@ -297,11 +301,17 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
297 "ohci_at91_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n", 301 "ohci_at91_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n",
298 hcd, typeReq, wValue, wIndex, buf, wLength); 302 hcd, typeReq, wValue, wIndex, buf, wLength);
299 303
304 wIndex--;
305
300 switch (typeReq) { 306 switch (typeReq) {
301 case SetPortFeature: 307 case SetPortFeature:
302 if (wValue == USB_PORT_FEAT_POWER) { 308 if (wValue == USB_PORT_FEAT_POWER) {
303 dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n"); 309 dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n");
304 ohci_at91_usb_set_power(pdata, wIndex - 1, 1); 310 if (valid_port(wIndex)) {
311 ohci_at91_usb_set_power(pdata, wIndex, 1);
312 ret = 0;
313 }
314
305 goto out; 315 goto out;
306 } 316 }
307 break; 317 break;
@@ -312,9 +322,9 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
312 dev_dbg(hcd->self.controller, 322 dev_dbg(hcd->self.controller,
313 "ClearPortFeature: C_OVER_CURRENT\n"); 323 "ClearPortFeature: C_OVER_CURRENT\n");
314 324
315 if (wIndex == 1 || wIndex == 2) { 325 if (valid_port(wIndex)) {
316 pdata->overcurrent_changed[wIndex-1] = 0; 326 pdata->overcurrent_changed[wIndex] = 0;
317 pdata->overcurrent_status[wIndex-1] = 0; 327 pdata->overcurrent_status[wIndex] = 0;
318 } 328 }
319 329
320 goto out; 330 goto out;
@@ -323,9 +333,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
323 dev_dbg(hcd->self.controller, 333 dev_dbg(hcd->self.controller,
324 "ClearPortFeature: OVER_CURRENT\n"); 334 "ClearPortFeature: OVER_CURRENT\n");
325 335
326 if (wIndex == 1 || wIndex == 2) { 336 if (valid_port(wIndex))
327 pdata->overcurrent_status[wIndex-1] = 0; 337 pdata->overcurrent_status[wIndex] = 0;
328 }
329 338
330 goto out; 339 goto out;
331 340
@@ -333,15 +342,15 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
333 dev_dbg(hcd->self.controller, 342 dev_dbg(hcd->self.controller,
334 "ClearPortFeature: POWER\n"); 343 "ClearPortFeature: POWER\n");
335 344
336 if (wIndex == 1 || wIndex == 2) { 345 if (valid_port(wIndex)) {
337 ohci_at91_usb_set_power(pdata, wIndex - 1, 0); 346 ohci_at91_usb_set_power(pdata, wIndex, 0);
338 return 0; 347 return 0;
339 } 348 }
340 } 349 }
341 break; 350 break;
342 } 351 }
343 352
344 ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); 353 ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
345 if (ret) 354 if (ret)
346 goto out; 355 goto out;
347 356
@@ -377,18 +386,15 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
377 386
378 dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex); 387 dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex);
379 388
380 if (wIndex == 1 || wIndex == 2) { 389 if (valid_port(wIndex)) {
381 if (! ohci_at91_usb_get_power(pdata, wIndex-1)) { 390 if (!ohci_at91_usb_get_power(pdata, wIndex))
382 *data &= ~cpu_to_le32(RH_PS_PPS); 391 *data &= ~cpu_to_le32(RH_PS_PPS);
383 }
384 392
385 if (pdata->overcurrent_changed[wIndex-1]) { 393 if (pdata->overcurrent_changed[wIndex])
386 *data |= cpu_to_le32(RH_PS_OCIC); 394 *data |= cpu_to_le32(RH_PS_OCIC);
387 }
388 395
389 if (pdata->overcurrent_status[wIndex-1]) { 396 if (pdata->overcurrent_status[wIndex])
390 *data |= cpu_to_le32(RH_PS_POCI); 397 *data |= cpu_to_le32(RH_PS_POCI);
391 }
392 } 398 }
393 } 399 }
394 400
@@ -450,14 +456,14 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
450 456
451 /* From the GPIO notifying the over-current situation, find 457 /* From the GPIO notifying the over-current situation, find
452 * out the corresponding port */ 458 * out the corresponding port */
453 for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) { 459 at91_for_each_port(port) {
454 if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) { 460 if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {
455 gpio = pdata->overcurrent_pin[port]; 461 gpio = pdata->overcurrent_pin[port];
456 break; 462 break;
457 } 463 }
458 } 464 }
459 465
460 if (port == ARRAY_SIZE(pdata->overcurrent_pin)) { 466 if (port == AT91_MAX_USBH_PORTS) {
461 dev_err(& pdev->dev, "overcurrent interrupt from unknown GPIO\n"); 467 dev_err(& pdev->dev, "overcurrent interrupt from unknown GPIO\n");
462 return IRQ_HANDLED; 468 return IRQ_HANDLED;
463 } 469 }
@@ -467,7 +473,7 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
467 /* When notified of an over-current situation, disable power 473 /* When notified of an over-current situation, disable power
468 on the corresponding port, and mark this port in 474 on the corresponding port, and mark this port in
469 over-current. */ 475 over-current. */
470 if (! val) { 476 if (!val) {
471 ohci_at91_usb_set_power(pdata, port, 0); 477 ohci_at91_usb_set_power(pdata, port, 0);
472 pdata->overcurrent_status[port] = 1; 478 pdata->overcurrent_status[port] = 1;
473 pdata->overcurrent_changed[port] = 1; 479 pdata->overcurrent_changed[port] = 1;
@@ -492,7 +498,7 @@ static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);
492static int __devinit ohci_at91_of_init(struct platform_device *pdev) 498static int __devinit ohci_at91_of_init(struct platform_device *pdev)
493{ 499{
494 struct device_node *np = pdev->dev.of_node; 500 struct device_node *np = pdev->dev.of_node;
495 int i, ret, gpio; 501 int i, gpio;
496 enum of_gpio_flags flags; 502 enum of_gpio_flags flags;
497 struct at91_usbh_data *pdata; 503 struct at91_usbh_data *pdata;
498 u32 ports; 504 u32 ports;
@@ -514,48 +520,17 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
514 if (!of_property_read_u32(np, "num-ports", &ports)) 520 if (!of_property_read_u32(np, "num-ports", &ports))
515 pdata->ports = ports; 521 pdata->ports = ports;
516 522
517 for (i = 0; i < 2; i++) { 523 at91_for_each_port(i) {
518 gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags); 524 gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags);
519 pdata->vbus_pin[i] = gpio; 525 pdata->vbus_pin[i] = gpio;
520 if (!gpio_is_valid(gpio)) 526 if (!gpio_is_valid(gpio))
521 continue; 527 continue;
522 pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW; 528 pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
523 ret = gpio_request(gpio, "ohci_vbus");
524 if (ret) {
525 dev_warn(&pdev->dev, "can't request vbus gpio %d", gpio);
526 continue;
527 }
528 ret = gpio_direction_output(gpio, !(flags & OF_GPIO_ACTIVE_LOW) ^ 1);
529 if (ret)
530 dev_warn(&pdev->dev, "can't put vbus gpio %d as output %d",
531 !(flags & OF_GPIO_ACTIVE_LOW) ^ 1, gpio);
532 } 529 }
533 530
534 for (i = 0; i < 2; i++) { 531 at91_for_each_port(i)
535 gpio = of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags); 532 pdata->overcurrent_pin[i] =
536 pdata->overcurrent_pin[i] = gpio; 533 of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
537 if (!gpio_is_valid(gpio))
538 continue;
539 ret = gpio_request(gpio, "ohci_overcurrent");
540 if (ret) {
541 dev_err(&pdev->dev, "can't request overcurrent gpio %d", gpio);
542 continue;
543 }
544
545 ret = gpio_direction_input(gpio);
546 if (ret) {
547 dev_err(&pdev->dev, "can't configure overcurrent gpio %d as input", gpio);
548 continue;
549 }
550
551 ret = request_irq(gpio_to_irq(gpio),
552 ohci_hcd_at91_overcurrent_irq,
553 IRQF_SHARED, "ohci_overcurrent", pdev);
554 if (ret) {
555 gpio_free(gpio);
556 dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n");
557 }
558 }
559 534
560 pdev->dev.platform_data = pdata; 535 pdev->dev.platform_data = pdata;
561 536
@@ -574,35 +549,69 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
574{ 549{
575 struct at91_usbh_data *pdata; 550 struct at91_usbh_data *pdata;
576 int i; 551 int i;
552 int gpio;
553 int ret;
577 554
578 i = ohci_at91_of_init(pdev); 555 ret = ohci_at91_of_init(pdev);
579 556 if (ret)
580 if (i) 557 return ret;
581 return i;
582 558
583 pdata = pdev->dev.platform_data; 559 pdata = pdev->dev.platform_data;
584 560
585 if (pdata) { 561 if (pdata) {
586 for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) { 562 at91_for_each_port(i) {
587 if (!gpio_is_valid(pdata->vbus_pin[i])) 563 if (!gpio_is_valid(pdata->vbus_pin[i]))
588 continue; 564 continue;
589 gpio_request(pdata->vbus_pin[i], "ohci_vbus"); 565 gpio = pdata->vbus_pin[i];
566
567 ret = gpio_request(gpio, "ohci_vbus");
568 if (ret) {
569 dev_err(&pdev->dev,
570 "can't request vbus gpio %d\n", gpio);
571 continue;
572 }
573 ret = gpio_direction_output(gpio,
574 !pdata->vbus_pin_active_low[i]);
575 if (ret) {
576 dev_err(&pdev->dev,
577 "can't put vbus gpio %d as output %d\n",
578 gpio, !pdata->vbus_pin_active_low[i]);
579 gpio_free(gpio);
580 continue;
581 }
582
590 ohci_at91_usb_set_power(pdata, i, 1); 583 ohci_at91_usb_set_power(pdata, i, 1);
591 } 584 }
592 585
593 for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) { 586 at91_for_each_port(i) {
594 int ret;
595
596 if (!gpio_is_valid(pdata->overcurrent_pin[i])) 587 if (!gpio_is_valid(pdata->overcurrent_pin[i]))
597 continue; 588 continue;
598 gpio_request(pdata->overcurrent_pin[i], "ohci_overcurrent"); 589 gpio = pdata->overcurrent_pin[i];
590
591 ret = gpio_request(gpio, "ohci_overcurrent");
592 if (ret) {
593 dev_err(&pdev->dev,
594 "can't request overcurrent gpio %d\n",
595 gpio);
596 continue;
597 }
598
599 ret = gpio_direction_input(gpio);
600 if (ret) {
601 dev_err(&pdev->dev,
602 "can't configure overcurrent gpio %d as input\n",
603 gpio);
604 gpio_free(gpio);
605 continue;
606 }
599 607
600 ret = request_irq(gpio_to_irq(pdata->overcurrent_pin[i]), 608 ret = request_irq(gpio_to_irq(gpio),
601 ohci_hcd_at91_overcurrent_irq, 609 ohci_hcd_at91_overcurrent_irq,
602 IRQF_SHARED, "ohci_overcurrent", pdev); 610 IRQF_SHARED, "ohci_overcurrent", pdev);
603 if (ret) { 611 if (ret) {
604 gpio_free(pdata->overcurrent_pin[i]); 612 gpio_free(gpio);
605 dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n"); 613 dev_err(&pdev->dev,
614 "can't get gpio IRQ for overcurrent\n");
606 } 615 }
607 } 616 }
608 } 617 }
@@ -617,14 +626,14 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
617 int i; 626 int i;
618 627
619 if (pdata) { 628 if (pdata) {
620 for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) { 629 at91_for_each_port(i) {
621 if (!gpio_is_valid(pdata->vbus_pin[i])) 630 if (!gpio_is_valid(pdata->vbus_pin[i]))
622 continue; 631 continue;
623 ohci_at91_usb_set_power(pdata, i, 0); 632 ohci_at91_usb_set_power(pdata, i, 0);
624 gpio_free(pdata->vbus_pin[i]); 633 gpio_free(pdata->vbus_pin[i]);
625 } 634 }
626 635
627 for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) { 636 at91_for_each_port(i) {
628 if (!gpio_is_valid(pdata->overcurrent_pin[i])) 637 if (!gpio_is_valid(pdata->overcurrent_pin[i]))
629 continue; 638 continue;
630 free_irq(gpio_to_irq(pdata->overcurrent_pin[i]), pdev); 639 free_irq(gpio_to_irq(pdata->overcurrent_pin[i]), pdev);