diff options
Diffstat (limited to 'drivers/pcmcia/yenta_socket.c')
-rw-r--r-- | drivers/pcmcia/yenta_socket.c | 174 |
1 files changed, 115 insertions, 59 deletions
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 02b23abc2df1..6837491f021c 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | 20 | ||
21 | #include <pcmcia/version.h> | ||
22 | #include <pcmcia/cs_types.h> | 21 | #include <pcmcia/cs_types.h> |
23 | #include <pcmcia/ss.h> | 22 | #include <pcmcia/ss.h> |
24 | #include <pcmcia/cs.h> | 23 | #include <pcmcia/cs.h> |
@@ -528,98 +527,144 @@ static int yenta_sock_suspend(struct pcmcia_socket *sock) | |||
528 | * Use an adaptive allocation for the memory resource, | 527 | * Use an adaptive allocation for the memory resource, |
529 | * sometimes the memory behind pci bridges is limited: | 528 | * sometimes the memory behind pci bridges is limited: |
530 | * 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. |
531 | * 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. | ||
532 | */ | 532 | */ |
533 | #define BRIDGE_MEM_MAX 4*1024*1024 | 533 | #define BRIDGE_MEM_MAX 4*1024*1024 |
534 | #define BRIDGE_MEM_ACC 128*1024 | ||
534 | #define BRIDGE_MEM_MIN 16*1024 | 535 | #define BRIDGE_MEM_MIN 16*1024 |
535 | 536 | ||
536 | #define BRIDGE_IO_MAX 256 | 537 | #define BRIDGE_IO_MAX 512 |
538 | #define BRIDGE_IO_ACC 256 | ||
537 | #define BRIDGE_IO_MIN 32 | 539 | #define BRIDGE_IO_MIN 32 |
538 | 540 | ||
539 | #ifndef PCIBIOS_MIN_CARDBUS_IO | 541 | #ifndef PCIBIOS_MIN_CARDBUS_IO |
540 | #define PCIBIOS_MIN_CARDBUS_IO PCIBIOS_MIN_IO | 542 | #define PCIBIOS_MIN_CARDBUS_IO PCIBIOS_MIN_IO |
541 | #endif | 543 | #endif |
542 | 544 | ||
543 | static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type) | 545 | static 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 | |||
587 | static 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 | |||
606 | static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end) | ||
544 | { | 607 | { |
545 | struct pci_bus *bus; | 608 | struct pci_bus *bus; |
546 | struct resource *root, *res; | 609 | struct resource *root, *res; |
547 | u32 start, end; | 610 | u32 start, end; |
548 | u32 align, size, min; | ||
549 | unsigned offset; | ||
550 | unsigned mask; | 611 | unsigned mask; |
551 | 612 | ||
552 | res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr; | 613 | res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr; |
553 | /* Already allocated? */ | 614 | /* Already allocated? */ |
554 | if (res->parent) | 615 | if (res->parent) |
555 | return 0; | 616 | return; |
556 | 617 | ||
557 | /* 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 */ |
558 | mask = ~0xfff; | 619 | mask = ~0xfff; |
559 | if (type & IORESOURCE_IO) | 620 | if (type & IORESOURCE_IO) |
560 | mask = ~3; | 621 | mask = ~3; |
561 | 622 | ||
562 | offset = 0x1c + 8*nr; | ||
563 | bus = socket->dev->subordinate; | 623 | bus = socket->dev->subordinate; |
564 | res->name = bus->name; | 624 | res->name = bus->name; |
565 | res->flags = type; | 625 | res->flags = type; |
566 | res->start = 0; | ||
567 | res->end = 0; | ||
568 | root = pci_find_parent_resource(socket->dev, res); | ||
569 | 626 | ||
570 | if (!root) | 627 | start = config_readl(socket, addr_start) & mask; |
571 | return; | 628 | end = config_readl(socket, addr_end) | ~mask; |
572 | |||
573 | start = config_readl(socket, offset) & mask; | ||
574 | end = config_readl(socket, offset+4) | ~mask; | ||
575 | if (start && end > start && !override_bios) { | 629 | if (start && end > start && !override_bios) { |
576 | res->start = start; | 630 | res->start = start; |
577 | res->end = end; | 631 | res->end = end; |
578 | if (request_resource(root, res) == 0) | 632 | root = pci_find_parent_resource(socket->dev, res); |
633 | if (root && (request_resource(root, res) == 0)) | ||
579 | return; | 634 | return; |
580 | 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", |
581 | pci_name(socket->dev), nr); | 636 | pci_name(socket->dev), nr); |
582 | res->start = res->end = 0; | ||
583 | } | 637 | } |
584 | 638 | ||
585 | if (type & IORESOURCE_IO) { | 639 | if (type & IORESOURCE_IO) { |
586 | align = 1024; | 640 | if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) || |
587 | size = BRIDGE_IO_MAX; | 641 | (yenta_search_res(socket, res, BRIDGE_IO_ACC)) || |
588 | min = BRIDGE_IO_MIN; | 642 | (yenta_search_res(socket, res, BRIDGE_IO_MIN))) { |
589 | start = PCIBIOS_MIN_CARDBUS_IO; | 643 | config_writel(socket, addr_start, res->start); |
590 | end = ~0U; | 644 | config_writel(socket, addr_end, res->end); |
645 | } | ||
591 | } else { | 646 | } else { |
592 | unsigned long avail = root->end - root->start; | 647 | if (type & IORESOURCE_PREFETCH) { |
593 | int i; | 648 | if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) || |
594 | size = BRIDGE_MEM_MAX; | 649 | (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) || |
595 | if (size > avail/8) { | 650 | (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { |
596 | size=(avail+1)/8; | 651 | config_writel(socket, addr_start, res->start); |
597 | /* round size down to next power of 2 */ | 652 | config_writel(socket, addr_end, res->end); |
598 | i = 0; | 653 | } |
599 | while ((size /= 2) != 0) | 654 | /* Approximating prefetchable by non-prefetchable */ |
600 | i++; | 655 | res->flags = IORESOURCE_MEM; |
601 | size = 1 << i; | ||
602 | } | 656 | } |
603 | if (size < BRIDGE_MEM_MIN) | 657 | if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) || |
604 | size = BRIDGE_MEM_MIN; | 658 | (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) || |
605 | min = BRIDGE_MEM_MIN; | 659 | (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { |
606 | align = size; | 660 | config_writel(socket, addr_start, res->start); |
607 | start = PCIBIOS_MIN_MEM; | 661 | config_writel(socket, addr_end, res->end); |
608 | end = ~0U; | ||
609 | } | ||
610 | |||
611 | do { | ||
612 | if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) { | ||
613 | config_writel(socket, offset, res->start); | ||
614 | config_writel(socket, offset+4, res->end); | ||
615 | return; | ||
616 | } | 662 | } |
617 | size = size/2; | 663 | } |
618 | align = size; | 664 | |
619 | } while (size >= min); | ||
620 | 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", |
621 | pci_name(socket->dev), type); | 666 | pci_name(socket->dev), type); |
622 | res->start = res->end = 0; | 667 | res->start = res->end = res->flags = 0; |
623 | } | 668 | } |
624 | 669 | ||
625 | /* | 670 | /* |
@@ -627,10 +672,14 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ | |||
627 | */ | 672 | */ |
628 | static void yenta_allocate_resources(struct yenta_socket *socket) | 673 | static void yenta_allocate_resources(struct yenta_socket *socket) |
629 | { | 674 | { |
630 | yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH); | 675 | yenta_allocate_res(socket, 0, IORESOURCE_IO, |
631 | yenta_allocate_res(socket, 1, IORESOURCE_MEM); | 676 | PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0); |
632 | yenta_allocate_res(socket, 2, IORESOURCE_IO); | 677 | yenta_allocate_res(socket, 1, IORESOURCE_IO, |
633 | 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); | ||
634 | } | 683 | } |
635 | 684 | ||
636 | 685 | ||
@@ -869,14 +918,11 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) | |||
869 | */ | 918 | */ |
870 | static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask) | 919 | static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask) |
871 | { | 920 | { |
872 | socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS; | ||
873 | socket->socket.map_size = 0x1000; | ||
874 | socket->socket.pci_irq = socket->cb_irq; | 921 | socket->socket.pci_irq = socket->cb_irq; |
875 | if (isa_probe) | 922 | if (isa_probe) |
876 | socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask); | 923 | socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask); |
877 | else | 924 | else |
878 | socket->socket.irq_mask = 0; | 925 | socket->socket.irq_mask = 0; |
879 | socket->socket.cb_dev = socket->dev; | ||
880 | 926 | ||
881 | printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n", | 927 | printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n", |
882 | socket->socket.irq_mask, socket->cb_irq); | 928 | socket->socket.irq_mask, socket->cb_irq); |
@@ -942,6 +988,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i | |||
942 | socket->socket.dev.dev = &dev->dev; | 988 | socket->socket.dev.dev = &dev->dev; |
943 | socket->socket.driver_data = socket; | 989 | socket->socket.driver_data = socket; |
944 | socket->socket.owner = THIS_MODULE; | 990 | socket->socket.owner = THIS_MODULE; |
991 | socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD; | ||
992 | socket->socket.map_size = 0x1000; | ||
993 | socket->socket.cb_dev = dev; | ||
945 | 994 | ||
946 | /* prepare struct yenta_socket */ | 995 | /* prepare struct yenta_socket */ |
947 | socket->dev = dev; | 996 | socket->dev = dev; |
@@ -1012,6 +1061,10 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i | |||
1012 | socket->poll_timer.data = (unsigned long)socket; | 1061 | socket->poll_timer.data = (unsigned long)socket; |
1013 | socket->poll_timer.expires = jiffies + HZ; | 1062 | socket->poll_timer.expires = jiffies + HZ; |
1014 | add_timer(&socket->poll_timer); | 1063 | add_timer(&socket->poll_timer); |
1064 | printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n" | ||
1065 | KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n"); | ||
1066 | } else { | ||
1067 | socket->socket.features |= SS_CAP_CARDBUS; | ||
1015 | } | 1068 | } |
1016 | 1069 | ||
1017 | /* Figure out what the dang thing can do for the PCMCIA layer... */ | 1070 | /* Figure out what the dang thing can do for the PCMCIA layer... */ |
@@ -1052,6 +1105,7 @@ static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state) | |||
1052 | pci_save_state(dev); | 1105 | pci_save_state(dev); |
1053 | pci_read_config_dword(dev, 16*4, &socket->saved_state[0]); | 1106 | pci_read_config_dword(dev, 16*4, &socket->saved_state[0]); |
1054 | pci_read_config_dword(dev, 17*4, &socket->saved_state[1]); | 1107 | pci_read_config_dword(dev, 17*4, &socket->saved_state[1]); |
1108 | pci_disable_device(dev); | ||
1055 | 1109 | ||
1056 | /* | 1110 | /* |
1057 | * Some laptops (IBM T22) do not like us putting the Cardbus | 1111 | * Some laptops (IBM T22) do not like us putting the Cardbus |
@@ -1075,6 +1129,8 @@ static int yenta_dev_resume (struct pci_dev *dev) | |||
1075 | pci_restore_state(dev); | 1129 | pci_restore_state(dev); |
1076 | pci_write_config_dword(dev, 16*4, socket->saved_state[0]); | 1130 | pci_write_config_dword(dev, 16*4, socket->saved_state[0]); |
1077 | pci_write_config_dword(dev, 17*4, socket->saved_state[1]); | 1131 | pci_write_config_dword(dev, 17*4, socket->saved_state[1]); |
1132 | pci_enable_device(dev); | ||
1133 | pci_set_master(dev); | ||
1078 | 1134 | ||
1079 | if (socket->type && socket->type->restore_state) | 1135 | if (socket->type && socket->type->restore_state) |
1080 | socket->type->restore_state(socket); | 1136 | socket->type->restore_state(socket); |