aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/yenta_socket.c160
1 files changed, 105 insertions, 55 deletions
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 15f716a7968a..6837491f021c 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -527,98 +527,144 @@ static int yenta_sock_suspend(struct pcmcia_socket *sock)
527 * Use an adaptive allocation for the memory resource, 527 * Use an adaptive allocation for the memory resource,
528 * sometimes the memory behind pci bridges is limited: 528 * sometimes the memory behind pci bridges is limited:
529 * 1/8 of the size of the io window of the parent. 529 * 1/8 of the size of the io window of the parent.
530 * max 4 MB, min 16 kB. 530 * max 4 MB, min 16 kB. We try very hard to not get below
531 * the "ACC" values, though.
531 */ 532 */
532#define BRIDGE_MEM_MAX 4*1024*1024 533#define BRIDGE_MEM_MAX 4*1024*1024
534#define BRIDGE_MEM_ACC 128*1024
533#define BRIDGE_MEM_MIN 16*1024 535#define BRIDGE_MEM_MIN 16*1024
534 536
535#define BRIDGE_IO_MAX 256 537#define BRIDGE_IO_MAX 512
538#define BRIDGE_IO_ACC 256
536#define BRIDGE_IO_MIN 32 539#define BRIDGE_IO_MIN 32
537 540
538#ifndef PCIBIOS_MIN_CARDBUS_IO 541#ifndef PCIBIOS_MIN_CARDBUS_IO
539#define PCIBIOS_MIN_CARDBUS_IO PCIBIOS_MIN_IO 542#define PCIBIOS_MIN_CARDBUS_IO PCIBIOS_MIN_IO
540#endif 543#endif
541 544
542static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type) 545static int yenta_search_one_res(struct resource *root, struct resource *res,
546 u32 min)
547{
548 u32 align, size, start, end;
549
550 if (res->flags & IORESOURCE_IO) {
551 align = 1024;
552 size = BRIDGE_IO_MAX;
553 start = PCIBIOS_MIN_CARDBUS_IO;
554 end = ~0U;
555 } else {
556 unsigned long avail = root->end - root->start;
557 int i;
558 size = BRIDGE_MEM_MAX;
559 if (size > avail/8) {
560 size=(avail+1)/8;
561 /* round size down to next power of 2 */
562 i = 0;
563 while ((size /= 2) != 0)
564 i++;
565 size = 1 << i;
566 }
567 if (size < min)
568 size = min;
569 align = size;
570 start = PCIBIOS_MIN_MEM;
571 end = ~0U;
572 }
573
574 do {
575 if (allocate_resource(root, res, size, start, end, align,
576 NULL, NULL)==0) {
577 return 1;
578 }
579 size = size/2;
580 align = size;
581 } while (size >= min);
582
583 return 0;
584}
585
586
587static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
588 u32 min)
589{
590 int i;
591 for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
592 struct resource * root = socket->dev->bus->resource[i];
593 if (!root)
594 continue;
595
596 if ((res->flags ^ root->flags) &
597 (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH))
598 continue; /* Wrong type */
599
600 if (yenta_search_one_res(root, res, min))
601 return 1;
602 }
603 return 0;
604}
605
606static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
543{ 607{
544 struct pci_bus *bus; 608 struct pci_bus *bus;
545 struct resource *root, *res; 609 struct resource *root, *res;
546 u32 start, end; 610 u32 start, end;
547 u32 align, size, min;
548 unsigned offset;
549 unsigned mask; 611 unsigned mask;
550 612
551 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr; 613 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
552 /* Already allocated? */ 614 /* Already allocated? */
553 if (res->parent) 615 if (res->parent)
554 return 0; 616 return;
555 617
556 /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */ 618 /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
557 mask = ~0xfff; 619 mask = ~0xfff;
558 if (type & IORESOURCE_IO) 620 if (type & IORESOURCE_IO)
559 mask = ~3; 621 mask = ~3;
560 622
561 offset = 0x1c + 8*nr;
562 bus = socket->dev->subordinate; 623 bus = socket->dev->subordinate;
563 res->name = bus->name; 624 res->name = bus->name;
564 res->flags = type; 625 res->flags = type;
565 res->start = 0;
566 res->end = 0;
567 root = pci_find_parent_resource(socket->dev, res);
568 626
569 if (!root) 627 start = config_readl(socket, addr_start) & mask;
570 return; 628 end = config_readl(socket, addr_end) | ~mask;
571
572 start = config_readl(socket, offset) & mask;
573 end = config_readl(socket, offset+4) | ~mask;
574 if (start && end > start && !override_bios) { 629 if (start && end > start && !override_bios) {
575 res->start = start; 630 res->start = start;
576 res->end = end; 631 res->end = end;
577 if (request_resource(root, res) == 0) 632 root = pci_find_parent_resource(socket->dev, res);
633 if (root && (request_resource(root, res) == 0))
578 return; 634 return;
579 printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n", 635 printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
580 pci_name(socket->dev), nr); 636 pci_name(socket->dev), nr);
581 res->start = res->end = 0;
582 } 637 }
583 638
584 if (type & IORESOURCE_IO) { 639 if (type & IORESOURCE_IO) {
585 align = 1024; 640 if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) ||
586 size = BRIDGE_IO_MAX; 641 (yenta_search_res(socket, res, BRIDGE_IO_ACC)) ||
587 min = BRIDGE_IO_MIN; 642 (yenta_search_res(socket, res, BRIDGE_IO_MIN))) {
588 start = PCIBIOS_MIN_CARDBUS_IO; 643 config_writel(socket, addr_start, res->start);
589 end = ~0U; 644 config_writel(socket, addr_end, res->end);
645 }
590 } else { 646 } else {
591 unsigned long avail = root->end - root->start; 647 if (type & IORESOURCE_PREFETCH) {
592 int i; 648 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
593 size = BRIDGE_MEM_MAX; 649 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
594 if (size > avail/8) { 650 (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
595 size=(avail+1)/8; 651 config_writel(socket, addr_start, res->start);
596 /* round size down to next power of 2 */ 652 config_writel(socket, addr_end, res->end);
597 i = 0; 653 }
598 while ((size /= 2) != 0) 654 /* Approximating prefetchable by non-prefetchable */
599 i++; 655 res->flags = IORESOURCE_MEM;
600 size = 1 << i;
601 } 656 }
602 if (size < BRIDGE_MEM_MIN) 657 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
603 size = BRIDGE_MEM_MIN; 658 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
604 min = BRIDGE_MEM_MIN; 659 (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
605 align = size; 660 config_writel(socket, addr_start, res->start);
606 start = PCIBIOS_MIN_MEM; 661 config_writel(socket, addr_end, res->end);
607 end = ~0U;
608 }
609
610 do {
611 if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) {
612 config_writel(socket, offset, res->start);
613 config_writel(socket, offset+4, res->end);
614 return;
615 } 662 }
616 size = size/2; 663 }
617 align = size; 664
618 } while (size >= min);
619 printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n", 665 printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
620 pci_name(socket->dev), type); 666 pci_name(socket->dev), type);
621 res->start = res->end = 0; 667 res->start = res->end = res->flags = 0;
622} 668}
623 669
624/* 670/*
@@ -626,10 +672,14 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
626 */ 672 */
627static void yenta_allocate_resources(struct yenta_socket *socket) 673static void yenta_allocate_resources(struct yenta_socket *socket)
628{ 674{
629 yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH); 675 yenta_allocate_res(socket, 0, IORESOURCE_IO,
630 yenta_allocate_res(socket, 1, IORESOURCE_MEM); 676 PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
631 yenta_allocate_res(socket, 2, IORESOURCE_IO); 677 yenta_allocate_res(socket, 1, IORESOURCE_IO,
632 yenta_allocate_res(socket, 3, IORESOURCE_IO); /* PCI isn't clever enough to use this one yet */ 678 PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
679 yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
680 PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
681 yenta_allocate_res(socket, 3, IORESOURCE_MEM,
682 PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
633} 683}
634 684
635 685