aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/yenta_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/yenta_socket.c')
-rw-r--r--drivers/pcmcia/yenta_socket.c47
1 files changed, 24 insertions, 23 deletions
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 0347a29f297b..f0997c36c9b7 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -72,6 +72,7 @@ static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
72{ 72{
73 debug("%p %04x %08x\n", socket, reg, val); 73 debug("%p %04x %08x\n", socket, reg, val);
74 writel(val, socket->base + reg); 74 writel(val, socket->base + reg);
75 readl(socket->base + reg); /* avoid problems with PCI write posting */
75} 76}
76 77
77static inline u8 config_readb(struct yenta_socket *socket, unsigned offset) 78static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
@@ -136,6 +137,7 @@ static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val
136{ 137{
137 debug("%p %04x %02x\n", socket, reg, val); 138 debug("%p %04x %02x\n", socket, reg, val);
138 writeb(val, socket->base + 0x800 + reg); 139 writeb(val, socket->base + 0x800 + reg);
140 readb(socket->base + 0x800 + reg); /* PCI write posting... */
139} 141}
140 142
141static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val) 143static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
@@ -143,6 +145,10 @@ static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
143 debug("%p %04x %04x\n", socket, reg, val); 145 debug("%p %04x %04x\n", socket, reg, val);
144 writeb(val, socket->base + 0x800 + reg); 146 writeb(val, socket->base + 0x800 + reg);
145 writeb(val >> 8, socket->base + 0x800 + reg + 1); 147 writeb(val >> 8, socket->base + 0x800 + reg + 1);
148
149 /* PCI write posting... */
150 readb(socket->base + 0x800 + reg);
151 readb(socket->base + 0x800 + reg + 1);
146} 152}
147 153
148/* 154/*
@@ -667,7 +673,7 @@ static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
667 return 0; 673 return 0;
668} 674}
669 675
670static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end) 676static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
671{ 677{
672 struct resource *root, *res; 678 struct resource *root, *res;
673 struct pci_bus_region region; 679 struct pci_bus_region region;
@@ -676,7 +682,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
676 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr; 682 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
677 /* Already allocated? */ 683 /* Already allocated? */
678 if (res->parent) 684 if (res->parent)
679 return; 685 return 0;
680 686
681 /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */ 687 /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
682 mask = ~0xfff; 688 mask = ~0xfff;
@@ -692,7 +698,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
692 pcibios_bus_to_resource(socket->dev, res, &region); 698 pcibios_bus_to_resource(socket->dev, res, &region);
693 root = pci_find_parent_resource(socket->dev, res); 699 root = pci_find_parent_resource(socket->dev, res);
694 if (root && (request_resource(root, res) == 0)) 700 if (root && (request_resource(root, res) == 0))
695 return; 701 return 0;
696 printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n", 702 printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
697 pci_name(socket->dev), nr); 703 pci_name(socket->dev), nr);
698 } 704 }
@@ -700,35 +706,27 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
700 if (type & IORESOURCE_IO) { 706 if (type & IORESOURCE_IO) {
701 if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) || 707 if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) ||
702 (yenta_search_res(socket, res, BRIDGE_IO_ACC)) || 708 (yenta_search_res(socket, res, BRIDGE_IO_ACC)) ||
703 (yenta_search_res(socket, res, BRIDGE_IO_MIN))) { 709 (yenta_search_res(socket, res, BRIDGE_IO_MIN)))
704 config_writel(socket, addr_start, res->start); 710 return 1;
705 config_writel(socket, addr_end, res->end);
706 return;
707 }
708 } else { 711 } else {
709 if (type & IORESOURCE_PREFETCH) { 712 if (type & IORESOURCE_PREFETCH) {
710 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) || 713 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
711 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) || 714 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
712 (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { 715 (yenta_search_res(socket, res, BRIDGE_MEM_MIN)))
713 config_writel(socket, addr_start, res->start); 716 return 1;
714 config_writel(socket, addr_end, res->end);
715 return;
716 }
717 /* Approximating prefetchable by non-prefetchable */ 717 /* Approximating prefetchable by non-prefetchable */
718 res->flags = IORESOURCE_MEM; 718 res->flags = IORESOURCE_MEM;
719 } 719 }
720 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) || 720 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
721 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) || 721 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
722 (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { 722 (yenta_search_res(socket, res, BRIDGE_MEM_MIN)))
723 config_writel(socket, addr_start, res->start); 723 return 1;
724 config_writel(socket, addr_end, res->end);
725 return;
726 }
727 } 724 }
728 725
729 printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n", 726 printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
730 pci_name(socket->dev), type); 727 pci_name(socket->dev), type);
731 res->start = res->end = res->flags = 0; 728 res->start = res->end = res->flags = 0;
729 return 0;
732} 730}
733 731
734/* 732/*
@@ -736,14 +734,17 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
736 */ 734 */
737static void yenta_allocate_resources(struct yenta_socket *socket) 735static void yenta_allocate_resources(struct yenta_socket *socket)
738{ 736{
739 yenta_allocate_res(socket, 0, IORESOURCE_IO, 737 int program = 0;
738 program += yenta_allocate_res(socket, 0, IORESOURCE_IO,
740 PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0); 739 PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
741 yenta_allocate_res(socket, 1, IORESOURCE_IO, 740 program += yenta_allocate_res(socket, 1, IORESOURCE_IO,
742 PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1); 741 PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
743 yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH, 742 program += yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
744 PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0); 743 PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
745 yenta_allocate_res(socket, 3, IORESOURCE_MEM, 744 program += yenta_allocate_res(socket, 3, IORESOURCE_MEM,
746 PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1); 745 PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
746 if (program)
747 pci_setup_cardbus(socket->dev->subordinate);
747} 748}
748 749
749 750
@@ -758,7 +759,7 @@ static void yenta_free_resources(struct yenta_socket *socket)
758 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i; 759 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
759 if (res->start != 0 && res->end != 0) 760 if (res->start != 0 && res->end != 0)
760 release_resource(res); 761 release_resource(res);
761 res->start = res->end = 0; 762 res->start = res->end = res->flags = 0;
762 } 763 }
763} 764}
764 765