root/arch/mips/pci/ops-rc32434.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. config_access
  2. read_config_byte
  3. read_config_word
  4. read_config_dword
  5. write_config_byte
  6. write_config_word
  7. write_config_dword
  8. pci_config_read
  9. pci_config_write

   1 /*
   2  *  BRIEF MODULE DESCRIPTION
   3  *     pci_ops for IDT EB434 board
   4  *
   5  *  Copyright 2004 IDT Inc. (rischelp@idt.com)
   6  *  Copyright 2006 Felix Fietkau <nbd@openwrt.org>
   7  *
   8  *  This program is free software; you can redistribute  it and/or modify it
   9  *  under  the terms of  the GNU General  Public License as published by the
  10  *  Free Software Foundation;  either version 2 of the  License, or (at your
  11  *  option) any later version.
  12  *
  13  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
  14  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
  15  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  16  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
  17  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  18  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
  19  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  21  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  22  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23  *
  24  *  You should have received a copy of the  GNU General Public License along
  25  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  26  *  675 Mass Ave, Cambridge, MA 02139, USA.
  27  */
  28 #include <linux/delay.h>
  29 #include <linux/io.h>
  30 #include <linux/pci.h>
  31 #include <linux/types.h>
  32 
  33 #include <asm/cpu.h>
  34 #include <asm/mach-rc32434/rc32434.h>
  35 #include <asm/mach-rc32434/pci.h>
  36 
  37 #define PCI_ACCESS_READ  0
  38 #define PCI_ACCESS_WRITE 1
  39 
  40 
  41 #define PCI_CFG_SET(bus, slot, func, off) \
  42         (rc32434_pci->pcicfga = (0x80000000 | \
  43                                 ((bus) << 16) | ((slot)<<11) | \
  44                                 ((func)<<8) | (off)))
  45 
  46 static inline int config_access(unsigned char access_type,
  47                                 struct pci_bus *bus, unsigned int devfn,
  48                                 unsigned char where, u32 *data)
  49 {
  50         unsigned int slot = PCI_SLOT(devfn);
  51         u8 func = PCI_FUNC(devfn);
  52 
  53         /* Setup address */
  54         PCI_CFG_SET(bus->number, slot, func, where);
  55         rc32434_sync();
  56 
  57         if (access_type == PCI_ACCESS_WRITE)
  58                 rc32434_pci->pcicfgd = *data;
  59         else
  60                 *data = rc32434_pci->pcicfgd;
  61 
  62         rc32434_sync();
  63 
  64         return 0;
  65 }
  66 
  67 
  68 /*
  69  * We can't address 8 and 16 bit words directly.  Instead we have to
  70  * read/write a 32bit word and mask/modify the data we actually want.
  71  */
  72 static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
  73                             int where, u8 *val)
  74 {
  75         u32 data;
  76         int ret;
  77 
  78         ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
  79         *val = (data >> ((where & 3) << 3)) & 0xff;
  80         return ret;
  81 }
  82 
  83 static int read_config_word(struct pci_bus *bus, unsigned int devfn,
  84                             int where, u16 *val)
  85 {
  86         u32 data;
  87         int ret;
  88 
  89         ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
  90         *val = (data >> ((where & 3) << 3)) & 0xffff;
  91         return ret;
  92 }
  93 
  94 static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
  95                              int where, u32 *val)
  96 {
  97         int ret;
  98         int delay = 1;
  99 
 100         /*
 101          * Don't scan too far, else there will be errors with plugged in
 102          * daughterboard (rb564).
 103          */
 104         if (bus->number == 0 && PCI_SLOT(devfn) > 21)
 105                 return 0;
 106 
 107 retry:
 108         ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
 109 
 110         /*
 111          * Certain devices react delayed at device scan time, this
 112          * gives them time to settle
 113          */
 114         if (where == PCI_VENDOR_ID) {
 115                 if (ret == 0xffffffff || ret == 0x00000000 ||
 116                     ret == 0x0000ffff || ret == 0xffff0000) {
 117                         if (delay > 4)
 118                                 return 0;
 119                         delay *= 2;
 120                         msleep(delay);
 121                         goto retry;
 122                 }
 123         }
 124 
 125         return ret;
 126 }
 127 
 128 static int
 129 write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
 130                   u8 val)
 131 {
 132         u32 data = 0;
 133 
 134         if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
 135                 return -1;
 136 
 137         data = (data & ~(0xff << ((where & 3) << 3))) |
 138             (val << ((where & 3) << 3));
 139 
 140         if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
 141                 return -1;
 142 
 143         return PCIBIOS_SUCCESSFUL;
 144 }
 145 
 146 
 147 static int
 148 write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
 149                   u16 val)
 150 {
 151         u32 data = 0;
 152 
 153         if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
 154                 return -1;
 155 
 156         data = (data & ~(0xffff << ((where & 3) << 3))) |
 157             (val << ((where & 3) << 3));
 158 
 159         if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
 160                 return -1;
 161 
 162 
 163         return PCIBIOS_SUCCESSFUL;
 164 }
 165 
 166 
 167 static int
 168 write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
 169                    u32 val)
 170 {
 171         if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
 172                 return -1;
 173 
 174         return PCIBIOS_SUCCESSFUL;
 175 }
 176 
 177 static int pci_config_read(struct pci_bus *bus, unsigned int devfn,
 178                            int where, int size, u32 *val)
 179 {
 180         switch (size) {
 181         case 1:
 182                 return read_config_byte(bus, devfn, where, (u8 *) val);
 183         case 2:
 184                 return read_config_word(bus, devfn, where, (u16 *) val);
 185         default:
 186                 return read_config_dword(bus, devfn, where, val);
 187         }
 188 }
 189 
 190 static int pci_config_write(struct pci_bus *bus, unsigned int devfn,
 191                             int where, int size, u32 val)
 192 {
 193         switch (size) {
 194         case 1:
 195                 return write_config_byte(bus, devfn, where, (u8) val);
 196         case 2:
 197                 return write_config_word(bus, devfn, where, (u16) val);
 198         default:
 199                 return write_config_dword(bus, devfn, where, val);
 200         }
 201 }
 202 
 203 struct pci_ops rc32434_pci_ops = {
 204         .read = pci_config_read,
 205         .write = pci_config_write,
 206 };

/* [<][>][^][v][top][bottom][index][help] */