diff options
Diffstat (limited to 'drivers/pcmcia/yenta_socket.c')
-rw-r--r-- | drivers/pcmcia/yenta_socket.c | 47 |
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 | ||
77 | static inline u8 config_readb(struct yenta_socket *socket, unsigned offset) | 78 | static 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 | ||
141 | static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val) | 143 | static 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 | ||
670 | static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end) | 676 | static 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, ®ion); | 698 | pcibios_bus_to_resource(socket->dev, res, ®ion); |
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 | */ |
737 | static void yenta_allocate_resources(struct yenta_socket *socket) | 735 | static 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 | ||