linux-old/arch/sh/kernel/pci-sd0001.c
<<
>>
Prefs
   1/*
   2 *   $Id: pci-sd0001.c,v 1.1.2.1 2003/06/24 08:40:50 dwmw2 Exp $
   3 *
   4 *   linux/arch/sh/kernel/pci-sd0001.c
   5 *
   6 *   Support Hitachi Semcon SD0001 SH3 PCI Host Bridge .
   7 *  
   8 *
   9 *   Copyright (C) 2000  Hitachi ULSI Systems Co., Ltd.
  10 *   All Rights Reserved.
  11 *
  12 *   Copyright (C) 2001-2003 Red Hat, Inc.
  13 *
  14 *   Authors:   Masayuki Okada (macha@adc.hitachi-ul.co.jp)
  15 *              David Woodhouse (dwmw2@redhat.com)
  16 *
  17 *
  18 *   This program is free software; you can redistribute it and/or modify
  19 *   it under the terms of the GNU General Public License as published by
  20 *   the Free Software Foundation; either version 2, or (at your option)
  21 *   any later version.
  22 *
  23 *   This program is distributed in the hope that it will be useful,
  24 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  25 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26 *   GNU General Public License for more details.
  27 *
  28 *   You should have received a copy of the GNU General Public License
  29 *   along with this program; if not, write to the Free Software
  30 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  31 */
  32
  33#include <linux/init.h>
  34#include <linux/pci.h>
  35#include <linux/kernel.h>
  36#include <linux/irq.h>
  37#include <linux/interrupt.h>
  38#include <linux/spinlock.h>
  39#include <linux/delay.h>
  40#include <linux/vmalloc.h>
  41
  42#include <asm/pci.h>
  43#include <asm/io.h>
  44#include <asm/irq.h>
  45
  46#include "pci-sd0001.h"
  47
  48spinlock_t sd0001_indirect_lock = SPIN_LOCK_UNLOCKED;
  49
  50int remap_area_pages(unsigned long address, unsigned long phys_addr,
  51                     unsigned long size, unsigned long flags);
  52
  53
  54#undef DEBUG
  55
  56#ifdef DEBUG
  57#define DBG(x...) printk(x)
  58#else
  59#define DBG(x...)
  60#endif
  61#define SD0001_INDIR_TIME       1000000         /* ´ÖÀÜ¥¢¥¯¥»¥¹´°Î»ÂÔ¤ÁºÇÂç²ó¿ô */
  62
  63static char *err_int_msg [] = {
  64        "Detect Master Abort",
  65        "Assert Master Abort",
  66        "Detect Target Abort",
  67        "Assert Target Abort",
  68        "Assert PERR",
  69        "Detect PERR",
  70        "Detect SERR",
  71        "Asster SERR",
  72        "Bus Timeout",
  73        "Bus Retry Over",
  74};
  75
  76/*
  77 * PCI¥Ð¥¹¤Î¥Ð¥¹¥ê¥»¥Ã¥È¼Â¹Ô
  78 */
  79static void sd0001_bus_reset(void)
  80{
  81        sd0001_writel(SD0001_RST_BUSRST, RESET);
  82
  83        udelay(64);
  84
  85        sd0001_writel(0, RESET);
  86}
  87
  88/*
  89 * SD0001¥½¥Õ¥È¥ê¥»¥Ã¥È
  90 */
  91static void sd0001_chip_reset(void)
  92{
  93        sd0001_writel(SD0001_RST_SWRST, RESET);
  94}
  95
  96
  97#define ROUND_UP(x, a)          (((x) + (a) - 1) & ~((a) - 1))
  98
  99static void
 100sd0001_int_pcierr (int irq, void *dummy, struct pt_regs *regs)
 101{
 102        static char  errStrings[30*12];
 103        u32 int_status;
 104        u32 mask;
 105        u32 indrct_flg;
 106        int reset_fatal;
 107        int   i;
 108        int   to_cnt = 0;
 109        unsigned long flags;
 110
 111        spin_lock_irqsave(&sd0001_indirect_lock, flags);
 112
 113        if ((int_status = (sd0001_readl(INT_STS1) & SD0001_INT_BUSERR))) {
 114                DBG("pciIntErrorHandle Called: status 0x%08x\n", int_status, 0, 0, 0, 0, 0);
 115
 116                for (mask = 1 << 20, i = 0, errStrings[0] = '\0'; i < 11; i++, mask <<= 1) {
 117                        if (int_status & mask) {
 118/*                              err_int_cnt[i] ++; */
 119                                strcat(errStrings, err_int_msg[i]);
 120                                strcat(errStrings, ", ");
 121                        }
 122                }
 123                i = strlen(errStrings);
 124                errStrings[i-2]= '\0';
 125
 126                printk(KERN_ERR "PCI Bus 0x%08x(%s) Error\n", int_status, errStrings);
 127
 128                reset_fatal = 0;
 129
 130                if (int_status & (SD0001_INT_SSERR|SD0001_INT_RPERR
 131                                  |SD0001_INT_SPERR|SD0001_INT_STABT
 132                                  |SD0001_INT_RTABT|SD0001_INT_RMABT)) {
 133                        /* Clear of Configration Status Bits */
 134                        sd0001_writel(4, INDIRECT_ADR);
 135                        sd0001_writel(0xf9000000, INDIRECT_DATA);
 136                        sd0001_writel(0x000c0002, INDIRECT_CTL);
 137                        to_cnt = 0;
 138                        while (((indrct_flg = sd0001_readl(INDIRECT_STS)) & SD0001_INDRCTF_INDFLG)
 139                               && (to_cnt++ < SD0001_INDIR_TIME))
 140                                ;
 141
 142
 143                        if (indrct_flg & SD0001_INDRCTF_INDFLG) {
 144                                panic("SD0001 Fatal Error 1\n");
 145                        } else {
 146                                if (indrct_flg & SD0001_INDRCTF_MABTRCV) {
 147                                        sd0001_writel(SD0001_INDRCTC_FLGRESET, INDIRECT_CTL);
 148                                        reset_fatal = -1;
 149                                }
 150                        }
 151                        int_status = sd0001_readl(INT_STS1) & SD0001_INT_BUSERR;
 152                }
 153
 154                if (int_status != 0) {
 155                        sd0001_writel(int_status, INT_STS1); /* ³ä¤ê¹þ¤ß¥¯¥ê¥¢ */
 156
 157                        if (reset_fatal || (sd0001_readl(INT_STS2) & SD0001_INT_BUSERR)) {
 158                                printk(KERN_CRIT "Fatal Error:SD0001 PCI Status Can't Clear 0x%08x\n",
 159                                       int_status & 0x7fffffff);
 160                                sd0001_writel(sd0001_readl(INT_ENABLE) & ~int_status, INT_ENABLE);
 161                                /* Masked Error Interrupt */
 162                        }
 163                }
 164        }
 165        spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
 166}
 167
 168
 169static inline u32 convert_dev_to_addr (struct pci_dev *dev, u32 reg)
 170{
 171        return (SD0001_CONFIG_ADDR_EN
 172                | (dev->bus->number << 16)
 173                | ((dev->devfn & 0xff) << 8)
 174                | (reg & 0xff)
 175                | ((dev->bus->number)?0x00:0x01));
 176}
 177
 178
 179static int sd0001_indirect_RW (u32  addr, u32 cmd, u32  be,
 180                                  u32  rw, u32  *data)
 181{
 182        u32 indrct_flg;
 183        u32 int_sts;
 184        u32 to_cnt = 0;
 185        int st = PCIBIOS_SUCCESSFUL;
 186        unsigned long flags;
 187
 188        spin_lock_irqsave(&sd0001_indirect_lock, flags);
 189        if ((cmd & SD0001_INDRCTC_CMD_MASK) == SD0001_INDRCTC_CMD_MEMR
 190            || (cmd & SD0001_INDRCTC_CMD_MASK) == SD0001_INDRCTC_CMD_MEMW)
 191                sd0001_writel(addr & 0xfffffffc, INDIRECT_ADR);
 192        else
 193                sd0001_writel(addr, INDIRECT_ADR);
 194
 195        if (rw == SD0001_INDRCTC_IOWT || rw == SD0001_INDRCTC_COWT)
 196                sd0001_writel(*data, INDIRECT_DATA);
 197
 198        sd0001_writel(be | cmd | rw , INDIRECT_CTL);
 199
 200        while (((indrct_flg = sd0001_readl(INDIRECT_STS)) & SD0001_INDRCTF_INDFLG)
 201               && (to_cnt++ < SD0001_INDIR_TIME));
 202
 203        int_sts = sd0001_readl(INT_STS1) & SD0001_INT_BUSERR;
 204    
 205        if (indrct_flg & SD0001_INDRCTF_INDFLG) {       /* ¥¿¥¤¥à¥¢¥¦¥È */
 206                printk("SD0001 Fatal Error 2\n");
 207                spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
 208
 209                return PCIBIOS_DEVICE_NOT_FOUND;
 210        }
 211
 212        if (int_sts != 0 || (indrct_flg & SD0001_INDRCTF_MABTRCV) != 0) {
 213                if ((st = (indrct_flg & SD0001_INDRCTF_MABTRCV) >> 19) != 0) {
 214                        sd0001_writel(SD0001_INDRCTC_FLGRESET, INDIRECT_CTL);
 215                        st |= 0x80000000;
 216                }
 217
 218                st |= 0x80000000 | int_sts;
 219
 220                if ((int_sts & (SD0001_INT_SSERR|SD0001_INT_RPERR
 221                                |SD0001_INT_SPERR|SD0001_INT_STABT
 222                                |SD0001_INT_RTABT|SD0001_INT_RMABT))
 223                    || (indrct_flg & SD0001_INDRCTF_MABTRCV)) {
 224                        /* Clear of Configration Status Bits */
 225                        sd0001_writel(4, INDIRECT_ADR);
 226                        sd0001_writel(0xf9000000, INDIRECT_DATA);
 227                        sd0001_writel(0x000c0002, INDIRECT_CTL);
 228
 229                        to_cnt = 0;
 230                        while (((indrct_flg = sd0001_readl(INDIRECT_STS)) & SD0001_INDRCTF_INDFLG)
 231                               && (to_cnt++ < SD0001_INDIR_TIME));
 232
 233                        if (indrct_flg & SD0001_INDRCTF_INDFLG) {       /* ¥¿¥¤¥à¥¢¥¦¥È */
 234                                panic("SD0001 Fatal Error 3\n");
 235                        }
 236
 237                        if (indrct_flg & SD0001_INDRCTF_MABTRCV) {
 238                                
 239                                sd0001_writel(SD0001_INDRCTC_FLGRESET, INDIRECT_CTL);
 240                        }
 241                }
 242                
 243                printk(KERN_ERR "PCI Bus Error: status 0x%08x\n", st);
 244
 245                if ((int_sts = sd0001_readl(INT_STS1) & SD0001_INT_BUSERR) != 0) {
 246                        sd0001_writel(int_sts, INT_STS1);       /* ³ä¤ê¹þ¤ß¥¯¥ê¥¢ */
 247                        
 248                        if (sd0001_readl(INT_STS2) & SD0001_INT_BUSERR) {
 249                                printk(KERN_CRIT "Fatal Error:SD0001 PCI Status Can't Clear 0x%08x\n",
 250                                       sd0001_readl(INT_STS2) & SD0001_INT_BUSERR);
 251                                sd0001_writel(sd0001_readl(INT_ENABLE) & ~int_sts, INT_ENABLE); /* Masked Error Interrupt */
 252                        }
 253                }
 254
 255                *data = 0xffffffff;
 256        } else {
 257                if (rw != SD0001_INDRCTC_IOWT && rw != SD0001_INDRCTC_COWT)
 258                        *data = sd0001_readl(INDIRECT_DATA);
 259        }
 260
 261        spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
 262        return st;
 263}
 264
 265static inline
 266int sd0001_config_RW (struct pci_dev *dev, u32 reg, u32 be, u32 rw, u32 *data)
 267{
 268        u32  reg_addr = convert_dev_to_addr(dev, reg);
 269
 270        if (reg_addr == 0) {
 271                *data = 0xffffffff;
 272                return PCIBIOS_SUCCESSFUL;
 273        }
 274    
 275        return sd0001_indirect_RW (reg_addr, 0, be, rw, data);
 276
 277}
 278
 279
 280static int sd0001_read_config_byte(struct pci_dev *dev, int reg, u8 *val)
 281{
 282        int  offset;
 283        u32  be;
 284        int  re;
 285        union {
 286                u32 ldata;
 287                u8  bdata[4];
 288        } work;
 289
 290        be = SD0001_INDRCTC_BE_BYTE << (reg & 0x03);
 291        re = sd0001_config_RW (dev, reg, be, SD0001_INDRCTC_CORD, &work.ldata);
 292
 293#if __LITTLE_ENDIAN__
 294        offset = reg & 0x03;
 295#else  /* __LITTLE_ENDIAN__ */
 296        offset = 3 - (reg & 0x03);
 297#endif /* __LITTLE_ENDIAN__ */
 298        *val = work.bdata[offset];
 299
 300        return re;
 301
 302}
 303
 304
 305static int sd0001_read_config_word(struct pci_dev *dev, int reg, u16 *val)
 306{
 307        int  offset;
 308        u32 be;
 309        int  re;
 310        union {
 311                u32 ldata;
 312                u16 wdata[2];
 313        } work;
 314
 315        be = SD0001_INDRCTC_BE_WORD << (reg & 0x02);
 316        
 317        re = sd0001_config_RW (dev, reg, be, SD0001_INDRCTC_CORD, &work.ldata);
 318        
 319#if __LITTLE_ENDIAN__
 320        offset = (reg >> 1) & 0x01;
 321#else  /* __LITTLE_ENDIAN__ */
 322        offset = 1 - ((reg >> 1) & 0x01);
 323#endif /* __LITTLE_ENDIAN__ */
 324        
 325        *val = work.wdata[offset];
 326        
 327        return re;
 328}
 329
 330
 331static int sd0001_read_config_dword(struct pci_dev *dev, int reg, u32 *val)
 332{
 333        return sd0001_config_RW (dev, reg, SD0001_INDRCTC_BE_LONG,
 334                              SD0001_INDRCTC_CORD, val);
 335}
 336
 337static int sd0001_write_config_byte (struct pci_dev *dev, int reg, u8 val)
 338{
 339        int  offset;
 340        u32 be;
 341        union {
 342                u32 ldata;
 343                u8  bdata[4];
 344        } work;
 345
 346        be = SD0001_INDRCTC_BE_BYTE << (reg & 0x03);
 347#if __LITTLE_ENDIAN__
 348        offset = reg & 0x03;
 349#else  /* __LITTLE_ENDIAN__ */
 350        offset = 3 - (reg & 0x03);
 351#endif /* __LITTLE_ENDIAN__ */
 352        work.bdata[offset] = val;
 353
 354        return sd0001_config_RW(dev, reg, be, SD0001_INDRCTC_COWT, &work.ldata);
 355    
 356}
 357
 358
 359static int sd0001_write_config_word (struct pci_dev *dev, int reg, u16 val)
 360{
 361        int  offset;
 362        u32 be;
 363        union {
 364                u32  ldata;
 365                u16  wdata[2];
 366        } work;
 367
 368
 369        be = SD0001_INDRCTC_BE_WORD << (reg & 0x02);
 370#if __LITTLE_ENDIAN__
 371        offset = (reg >> 1) & 0x01;
 372#else  /* __LITTLE_ENDIAN__ */
 373        offset = 1 - ((reg >> 1) & 0x01);
 374#endif /* __LITTLE_ENDIAN__ */
 375
 376        work.wdata[offset] = val;
 377
 378        return sd0001_config_RW (dev, reg, be, SD0001_INDRCTC_COWT, &work.ldata);
 379
 380}
 381
 382
 383static int sd0001_write_config_dword (struct pci_dev *dev, int reg, u32 val)
 384{
 385        return sd0001_config_RW (dev, reg, SD0001_INDRCTC_BE_LONG, SD0001_INDRCTC_COWT, &val);
 386}
 387
 388static struct pci_ops sd0001_pci_ops = 
 389{
 390        .read_byte =    sd0001_read_config_byte,
 391        .read_word =    sd0001_read_config_word,
 392        .read_dword =   sd0001_read_config_dword,
 393        .write_byte =   sd0001_write_config_byte,
 394        .write_word =   sd0001_write_config_word,
 395        .write_dword =  sd0001_write_config_dword
 396};
 397
 398int __init pci_setup_sd0001 (void)
 399{
 400        sd0001_writel(0, INT_ENABLE);           /* all Interrupt = Mask */
 401
 402        sd0001_bus_reset();
 403
 404        /*
 405         * PCI¥Ð¥¹À©¸æ¤Îưºî¥â¡¼¥É(MCW0¥ì¥¸¥¹¥¿)ÀßÄê
 406         * ¡¦PCI¥Ð¥¹¤Î¥ê¥È¥é¥¤²ó¿ô : ̵¸Â²ó
 407         * ¡¦¥Ð¥¹¥°¥é¥ó¥É¤ÎÍ޻ߤʤ·
 408         */
 409#if __LITTLE_ENDIAN__
 410        sd0001_writel(0x0000, PCI_CTL);
 411#else
 412        sd0001_writel(SD0001_CTL_MASTER_SWAP | SD0001_CTL_PCI_EDCONV, PCI_CTL);
 413#endif
 414        sd0001_writel(0, PCI_IO_OFFSET);
 415        sd0001_writel(PCIBIOS_MIN_MEM, PCI_MEM_OFFSET);
 416
 417
 418        if (request_irq(CONFIG_PCI_SD0001_IRQ, &sd0001_int_pcierr, SA_SHIRQ, "PCI Bus Error", NULL))
 419                printk(KERN_ERR "Can't Setup PCI Bus Error Interrupt\n");
 420
 421        /* FIXME: Enable INT[ABCD] only when devices actually want them.
 422           We should probably demux them so they appear to the kernel as
 423           separate IRQs */
 424        sd0001_writel(SD0001_INT_INTEN|SD0001_INT_BUSERR
 425                |SD0001_INT_INTD|SD0001_INT_INTC|SD0001_INT_INTB
 426                |SD0001_INT_INTA, INT_ENABLE);
 427
 428
 429        return PCIBIOS_SUCCESSFUL;
 430}
 431
 432
 433void __init
 434pcibios_fixup_pbus_ranges(struct pci_bus * bus,
 435        struct pbus_set_ranges_data * ranges)
 436{
 437        ranges->io_start -= bus->resource[0]->start;
 438        ranges->io_end -= bus->resource[0]->start;
 439        ranges->mem_start -= bus->resource[1]->start;
 440        ranges->mem_end -= bus->resource[1]->start;
 441}
 442
 443
 444static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
 445{
 446        return PCI_SLOT(dev->devfn);
 447}
 448
 449static int __init sd0001_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 450{
 451        return CONFIG_PCI_SD0001_IRQ;
 452}
 453
 454void __init pcibios_init(void)
 455{
 456        printk(KERN_NOTICE "Linux/SH SD0001 PCI Initialise\n");
 457        
 458        ioport_resource.end = 0xffff;
 459        iomem_resource.end = 0xfeffffff;
 460
 461        pci_setup_sd0001();
 462        pci_scan_bus(0, &sd0001_pci_ops, NULL);
 463
 464        pci_assign_unassigned_resources();
 465
 466        pci_fixup_irqs(no_swizzle, sd0001_map_irq);
 467}
 468
 469char * __init pcibios_setup(char *str)
 470{
 471        return str;
 472}
 473
 474extern unsigned long memory_start, memory_end;
 475
 476void __init pcibios_fixup_bus(struct pci_bus *bus)
 477{
 478        struct list_head *list;
 479
 480        list_for_each(list, &bus->devices) {
 481                struct pci_dev *dev = pci_dev_b(list);
 482                u16 cmd;
 483                if (dev->class >> 8 == PCI_CLASS_BRIDGE_HOST) {
 484                        memset(&dev->resource[1], 0, sizeof(struct resource));
 485                        dev->resource[1].start = __pa(memory_start);
 486                        dev->resource[1].end = __pa(memory_end)-1;
 487                        dev->resource[1].flags = IORESOURCE_MEM|IORESOURCE_PREFETCH;
 488                        dev->resource[1].name = "PCI Host RAM";
 489                        request_resource(&iomem_resource, &dev->resource[1]);
 490
 491#if 0
 492                        printk("res1 (@%p) %s %08lx %08lx %x %p %p %p\n", 
 493                               &dev->resource[1],
 494                               dev->resource[1].name,
 495                               dev->resource[1].start,
 496                               dev->resource[1].end,
 497                               dev->resource[1].flags,
 498                               dev->resource[1].parent,
 499                               dev->resource[1].sibling,
 500                               dev->resource[1].child);
 501#endif
 502                        pcibios_update_resource(dev, bus->resource[1], 
 503                                                &dev->resource[1], 1);
 504
 505                        cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
 506                        pci_write_config_word(dev, PCI_COMMAND, cmd);
 507                        pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
 508                }
 509        }
 510}
 511
 512
 513
 514/* Add future fixups here... */
 515struct pci_fixup pcibios_fixups[] = {
 516        { 0 }
 517};
 518
 519
 520        /*
 521         * Mapping for PCI Devices.
 522         * The SD0001 has a 48MiB window onto the PCI memory space, mapped
 523         * into the CPU's address space at 0xb1000000-0xb3ffffff. 
 524         * The range of the PCI space which is accessible is controlled
 525         * by the SD0001's PCI_MEM_OFFSET register, which has a granularity
 526         * of 64MiB. 
 527         *
 528         * As far as I can tell from the little I can understand of
 529         * the SD0001 documentation and from the behaviour of the
 530         * device, you have a 48MiB window which can only be moved
 531         * with 64MiB granularity. Therefore to the best of my
 532         * knowledge, you cannot access any PCI memory address where
 533         * (<addr> & 0x03000000) == 0x03000000, except by going 
 534         * indirectly through the PCI bridge like we do for configuration
 535         * and I/O cycles.
 536         *
 537         * Hopefully, this is untrue and there's some way of doing it that
 538         * I just don't know because I can't read the docs. For now, we
 539         * allow only access to the first 48MiB of PCI memory space.
 540         *
 541         * In addition to that joy, it appears that when accessing PCI
 542         * memory space directly, the SD0001 swaps address lines #21
 543         * and #22, hence the macro below to swap addresses back
 544         * again.
 545         *
 546         * Me and my baseball bat want a quiet word with someone. 
 547         *
 548         * dwmw2.
 549         */
 550
 551#define unmunge(x) (((x) & ~0x00300000) | ( ((x)&0x00100000) << 1) | ( ((x)&0x00200000) >> 1))
 552
 553void *sd0001_ioremap(unsigned long phys_addr, unsigned long size)
 554{
 555        unsigned long offset;
 556
 557        if ((phys_addr & 0xFFF00000) == ((phys_addr+size) & 0xFFF00000)) {
 558                /* It fits within a single mebibyte we can still use the 
 559                   directly-mapped region... */
 560                return (void *)(SD0001_MEM_BASE-(PCIBIOS_MIN_MEM&0xfc000000)+unmunge(phys_addr));
 561        }
 562
 563        /* It crosses a mebibyte boundary and hence we have to
 564           play VM tricks to make the region which is physically
 565           contiguous on the PCI bus but not physically contiguous
 566           on the SH3 bus appear virtually contiguous to the kernel.
 567           Got that? Did I mention my baseball bat yet? */
 568        void * addr;
 569        struct vm_struct * area;
 570                
 571        offset = phys_addr & ~PAGE_MASK;
 572        phys_addr &= PAGE_MASK;
 573        size = PAGE_ALIGN(phys_addr + size - 1) - phys_addr;
 574
 575        area = get_vm_area(size, VM_IOREMAP);
 576        if (!area)
 577                return NULL;
 578        addr = area->addr;
 579
 580        phys_addr += SD0001_MEM_BASE;
 581        while (size) {
 582                unsigned long this_size;
 583
 584                this_size = 0x100000 - (phys_addr & 0xfffff);
 585                this_size = min(this_size, size);
 586
 587                if (remap_area_pages(VMALLOC_VMADDR(addr),
 588                                     unmunge(phys_addr), this_size, 
 589                                     _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_FLAGS_HARD)) {
 590                        vfree(area->addr);
 591                        return NULL;
 592                }
 593                size -= this_size;
 594                phys_addr += this_size;
 595                addr += this_size;
 596        }
 597        return (void *) (offset + (char *)area->addr);
 598}
 599
 600void sd0001_iounmap(void *addr)
 601{
 602        if ((unsigned long)addr >= VMALLOC_START && 
 603            (unsigned long)addr < VMALLOC_END)
 604                vfree((void *)((unsigned long)addr & ~PAGE_MASK));
 605}
 606
 607
 608static void sd0001_indirect_access_wait(unsigned long i)
 609{
 610
 611        while((sd0001_readl(INDIRECT_STS) & SD0001_INDRCTF_INDFLG)
 612              && --i)
 613                ;
 614
 615        if (i == 0) {
 616                printk("##### Long Indirect access wait #####\n");
 617                mdelay(20);
 618        }
 619}
 620
 621static inline void delay(void)
 622{
 623        ctrl_inw(0xa0000000);
 624}
 625
 626/* PCI IO read long word cycle */
 627unsigned long sd0001_inl(unsigned long port)
 628{
 629        return *(volatile unsigned long *) (SD0001_IO_BASE+port);
 630}
 631void sd0001_outl(unsigned long value, unsigned long port)
 632{
 633        *(volatile unsigned long *)(SD0001_IO_BASE+port) = value;
 634}
 635
 636/* The SD0001 doesn't correctly handle byte enables for sub-word
 637   accesses, so we have to do it indirectly like we do configuration
 638   cycles */
 639
 640/* PCI IO read byte cycle */
 641unsigned char sd0001_inb(unsigned long port)
 642{
 643        unsigned long work, val, byte_e;
 644        unsigned long flags;
 645
 646        spin_lock_irqsave(&sd0001_indirect_lock, flags);
 647        val = 0;
 648        byte_e = 0x00010000;
 649        work = (port & 0x00000003);
 650        byte_e <<= work;
 651
 652        port &= 0xFFFFFFFC;
 653        sd0001_writel(port, INDIRECT_ADR);
 654        sd0001_writel(0x00008204 | byte_e, INDIRECT_CTL); /* I/O read cycle */
 655        sd0001_indirect_access_wait(100);
 656        val = sd0001_readl(INDIRECT_DATA);
 657
 658        val >>= (work*8);
 659        val &= 0x000000FF;
 660
 661        spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
 662
 663        return val;
 664}
 665
 666/* PCI IO write byte cycle */
 667void sd0001_outb(unsigned char value, unsigned long port)
 668{
 669        unsigned long work, data, byte_e;
 670        unsigned long flags;
 671
 672        spin_lock_irqsave(&sd0001_indirect_lock, flags);
 673        byte_e = 0x00010000;
 674        work = (port & 0x00000003);
 675        byte_e <<= work;
 676
 677        data = value;
 678        data <<= (work*8);
 679
 680        port &= 0xFFFFFFFC;
 681        sd0001_writel(data, INDIRECT_DATA);
 682        sd0001_writel(port, INDIRECT_ADR);
 683        sd0001_writel((0x00008308 | byte_e), INDIRECT_CTL);     /* I/O write cycle */
 684        sd0001_indirect_access_wait(100);
 685
 686        spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
 687}
 688
 689/* PCI IO read word cycle */
 690unsigned short sd0001_inw(unsigned long port)
 691{
 692        unsigned long work, val, byte_e;
 693        unsigned long flags;
 694
 695        spin_lock_irqsave(&sd0001_indirect_lock, flags);
 696        val = 0;
 697        byte_e = 0x00030000;
 698        work = (port & 0x00000003);
 699        byte_e <<= (work & 0x00000002);
 700        work >>= 1;
 701
 702        port &= 0xFFFFFFFC;
 703        sd0001_writel(port, INDIRECT_ADR);
 704        sd0001_writel((0x00008204 | byte_e), INDIRECT_CTL);     /* I/O read cycle */
 705        sd0001_indirect_access_wait(100);
 706        val = sd0001_readl(INDIRECT_DATA) ;
 707
 708        val >>= (work*16);
 709        val &= 0x0000FFFF;
 710
 711        spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
 712
 713        return val;
 714}
 715
 716/* PCI IO write word cycle */
 717void sd0001_outw(unsigned short value, unsigned long port)
 718{
 719        unsigned long work, data, byte_e;
 720        unsigned long flags;
 721
 722        spin_lock_irqsave(&sd0001_indirect_lock, flags);
 723        byte_e = 0x00030000;
 724        work = (port & 0x00000003);
 725        byte_e <<= (work & 0x00000002);
 726        work >>= 1;
 727
 728        port &= 0xFFFFFFFC;
 729        data = value;
 730        data <<= (work*16);
 731
 732        sd0001_writel(data, INDIRECT_DATA);
 733        sd0001_writel(port, INDIRECT_ADR);
 734        sd0001_writel((0x00008308 | byte_e), INDIRECT_CTL);     /* I/O write cycle */
 735        sd0001_indirect_access_wait(100);
 736        spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
 737}
 738
 739void sd0001_insb(unsigned long port, void *addr, unsigned long count)
 740{
 741
 742        while (count--)
 743                *((unsigned char *) addr)++ = (unsigned char)sd0001_inb(port);
 744}
 745
 746void sd0001_insw(unsigned long port, void *addr, unsigned long count)
 747{
 748
 749        while (count--)
 750                *((unsigned short *) addr)++ = (unsigned short)sd0001_inw(port);
 751}
 752
 753void sd0001_insl(unsigned long port, void *addr, unsigned long count)
 754{
 755
 756        while (count--)
 757                *((unsigned long *) addr)++ = sd0001_inl(port);
 758}
 759
 760void sd0001_outsb(unsigned long port, const void *addr, unsigned long count)
 761{
 762
 763        while (count--)
 764                sd0001_outb(*((unsigned char *)addr)++, port);
 765}
 766
 767void sd0001_outsw(unsigned long port, const void *addr, unsigned long count)
 768{
 769
 770        while (count--)
 771                sd0001_outw(*((unsigned short *)addr)++, port);
 772}
 773
 774void sd0001_outsl(unsigned long port, const void *addr, unsigned long count)
 775{
 776
 777        while (count--)
 778                sd0001_outl(*((unsigned long *)addr)++, port);
 779}
 780
 781unsigned char sd0001_inb_p(unsigned long port)
 782{
 783        unsigned long v;
 784
 785        v = sd0001_inb(port);
 786        delay();
 787        return v;
 788}
 789
 790void sd0001_outb_p(unsigned char value, unsigned long port)
 791{
 792
 793        sd0001_outb(value, port);
 794        delay();
 795}
 796
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.