linux/arch/sparc/include/asm/floppy_64.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/* floppy.h: Sparc specific parts of the Floppy driver.
   3 *
   4 * Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net)
   5 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
   6 *
   7 * Ultra/PCI support added: Sep 1997  Eddie C. Dost  (ecd@skynet.be)
   8 */
   9
  10#ifndef __ASM_SPARC64_FLOPPY_H
  11#define __ASM_SPARC64_FLOPPY_H
  12
  13#include <linux/of.h>
  14#include <linux/of_device.h>
  15#include <linux/dma-mapping.h>
  16
  17#include <asm/auxio.h>
  18
  19/*
  20 * Define this to enable exchanging drive 0 and 1 if only drive 1 is
  21 * probed on PCI machines.
  22 */
  23#undef PCI_FDC_SWAP_DRIVES
  24
  25
  26/* References:
  27 * 1) Netbsd Sun floppy driver.
  28 * 2) NCR 82077 controller manual
  29 * 3) Intel 82077 controller manual
  30 */
  31struct sun_flpy_controller {
  32        volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
  33        volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
  34        volatile unsigned char dor_82077;     /* Digital Output reg. */
  35        volatile unsigned char tapectl_82077; /* Tape Control reg */
  36        volatile unsigned char status_82077;  /* Main Status Register. */
  37#define drs_82077              status_82077   /* Digital Rate Select reg. */
  38        volatile unsigned char data_82077;    /* Data fifo. */
  39        volatile unsigned char ___unused;
  40        volatile unsigned char dir_82077;     /* Digital Input reg. */
  41#define dcr_82077              dir_82077      /* Config Control reg. */
  42};
  43
  44/* You'll only ever find one controller on an Ultra anyways. */
  45static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
  46unsigned long fdc_status;
  47static struct platform_device *floppy_op = NULL;
  48
  49struct sun_floppy_ops {
  50        unsigned char   (*fd_inb) (unsigned long port, unsigned int reg);
  51        void            (*fd_outb) (unsigned char value, unsigned long base,
  52                                    unsigned int reg);
  53        void            (*fd_enable_dma) (void);
  54        void            (*fd_disable_dma) (void);
  55        void            (*fd_set_dma_mode) (int);
  56        void            (*fd_set_dma_addr) (char *);
  57        void            (*fd_set_dma_count) (int);
  58        unsigned int    (*get_dma_residue) (void);
  59        int             (*fd_request_irq) (void);
  60        void            (*fd_free_irq) (void);
  61        int             (*fd_eject) (int);
  62};
  63
  64static struct sun_floppy_ops sun_fdops;
  65
  66#define fd_inb(base, reg)         sun_fdops.fd_inb(base, reg)
  67#define fd_outb(value, base, reg) sun_fdops.fd_outb(value, base, reg)
  68#define fd_enable_dma()           sun_fdops.fd_enable_dma()
  69#define fd_disable_dma()          sun_fdops.fd_disable_dma()
  70#define fd_request_dma()          (0) /* nothing... */
  71#define fd_free_dma()             /* nothing... */
  72#define fd_clear_dma_ff()         /* nothing... */
  73#define fd_set_dma_mode(mode)     sun_fdops.fd_set_dma_mode(mode)
  74#define fd_set_dma_addr(addr)     sun_fdops.fd_set_dma_addr(addr)
  75#define fd_set_dma_count(count)   sun_fdops.fd_set_dma_count(count)
  76#define get_dma_residue(x)        sun_fdops.get_dma_residue()
  77#define fd_request_irq()          sun_fdops.fd_request_irq()
  78#define fd_free_irq()             sun_fdops.fd_free_irq()
  79#define fd_eject(drive)           sun_fdops.fd_eject(drive)
  80
  81/* Super paranoid... */
  82#undef HAVE_DISABLE_HLT
  83
  84static int sun_floppy_types[2] = { 0, 0 };
  85
  86/* Here is where we catch the floppy driver trying to initialize,
  87 * therefore this is where we call the PROM device tree probing
  88 * routine etc. on the Sparc.
  89 */
  90#define FLOPPY0_TYPE            sun_floppy_init()
  91#define FLOPPY1_TYPE            sun_floppy_types[1]
  92
  93#define FDC1                    ((unsigned long)sun_fdc)
  94
  95#define N_FDC    1
  96#define N_DRIVE  8
  97
  98/* No 64k boundary crossing problems on the Sparc. */
  99#define CROSS_64KB(a,s) (0)
 100
 101static unsigned char sun_82077_fd_inb(unsigned long base, unsigned int reg)
 102{
 103        udelay(5);
 104        switch (reg) {
 105        default:
 106                printk("floppy: Asked to read unknown port %x\n", reg);
 107                panic("floppy: Port bolixed.");
 108        case FD_STATUS:
 109                return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
 110        case FD_DATA:
 111                return sbus_readb(&sun_fdc->data_82077);
 112        case FD_DIR:
 113                /* XXX: Is DCL on 0x80 in sun4m? */
 114                return sbus_readb(&sun_fdc->dir_82077);
 115        }
 116        panic("sun_82072_fd_inb: How did I get here?");
 117}
 118
 119static void sun_82077_fd_outb(unsigned char value, unsigned long base,
 120                              unsigned int reg)
 121{
 122        udelay(5);
 123        switch (reg) {
 124        default:
 125                printk("floppy: Asked to write to unknown port %x\n", reg);
 126                panic("floppy: Port bolixed.");
 127        case FD_DOR:
 128                /* Happily, the 82077 has a real DOR register. */
 129                sbus_writeb(value, &sun_fdc->dor_82077);
 130                break;
 131        case FD_DATA:
 132                sbus_writeb(value, &sun_fdc->data_82077);
 133                break;
 134        case FD_DCR:
 135                sbus_writeb(value, &sun_fdc->dcr_82077);
 136                break;
 137        case FD_DSR:
 138                sbus_writeb(value, &sun_fdc->status_82077);
 139                break;
 140        }
 141        return;
 142}
 143
 144/* For pseudo-dma (Sun floppy drives have no real DMA available to
 145 * them so we must eat the data fifo bytes directly ourselves) we have
 146 * three state variables.  doing_pdma tells our inline low-level
 147 * assembly floppy interrupt entry point whether it should sit and eat
 148 * bytes from the fifo or just transfer control up to the higher level
 149 * floppy interrupt c-code.  I tried very hard but I could not get the
 150 * pseudo-dma to work in c-code without getting many overruns and
 151 * underruns.  If non-zero, doing_pdma encodes the direction of
 152 * the transfer for debugging.  1=read 2=write
 153 */
 154unsigned char *pdma_vaddr;
 155unsigned long pdma_size;
 156volatile int doing_pdma = 0;
 157
 158/* This is software state */
 159char *pdma_base = NULL;
 160unsigned long pdma_areasize;
 161
 162/* Common routines to all controller types on the Sparc. */
 163static void sun_fd_disable_dma(void)
 164{
 165        doing_pdma = 0;
 166        pdma_base = NULL;
 167}
 168
 169static void sun_fd_set_dma_mode(int mode)
 170{
 171        switch(mode) {
 172        case DMA_MODE_READ:
 173                doing_pdma = 1;
 174                break;
 175        case DMA_MODE_WRITE:
 176                doing_pdma = 2;
 177                break;
 178        default:
 179                printk("Unknown dma mode %d\n", mode);
 180                panic("floppy: Giving up...");
 181        }
 182}
 183
 184static void sun_fd_set_dma_addr(char *buffer)
 185{
 186        pdma_vaddr = buffer;
 187}
 188
 189static void sun_fd_set_dma_count(int length)
 190{
 191        pdma_size = length;
 192}
 193
 194static void sun_fd_enable_dma(void)
 195{
 196        pdma_base = pdma_vaddr;
 197        pdma_areasize = pdma_size;
 198}
 199
 200irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
 201{
 202        if (likely(doing_pdma)) {
 203                void __iomem *stat = (void __iomem *) fdc_status;
 204                unsigned char *vaddr = pdma_vaddr;
 205                unsigned long size = pdma_size;
 206                u8 val;
 207
 208                while (size) {
 209                        val = readb(stat);
 210                        if (unlikely(!(val & 0x80))) {
 211                                pdma_vaddr = vaddr;
 212                                pdma_size = size;
 213                                return IRQ_HANDLED;
 214                        }
 215                        if (unlikely(!(val & 0x20))) {
 216                                pdma_vaddr = vaddr;
 217                                pdma_size = size;
 218                                doing_pdma = 0;
 219                                goto main_interrupt;
 220                        }
 221                        if (val & 0x40) {
 222                                /* read */
 223                                *vaddr++ = readb(stat + 1);
 224                        } else {
 225                                unsigned char data = *vaddr++;
 226
 227                                /* write */
 228                                writeb(data, stat + 1);
 229                        }
 230                        size--;
 231                }
 232
 233                pdma_vaddr = vaddr;
 234                pdma_size = size;
 235
 236                /* Send Terminal Count pulse to floppy controller. */
 237                val = readb(auxio_register);
 238                val |= AUXIO_AUX1_FTCNT;
 239                writeb(val, auxio_register);
 240                val &= ~AUXIO_AUX1_FTCNT;
 241                writeb(val, auxio_register);
 242
 243                doing_pdma = 0;
 244        }
 245
 246main_interrupt:
 247        return floppy_interrupt(irq, dev_cookie);
 248}
 249
 250static int sun_fd_request_irq(void)
 251{
 252        static int once = 0;
 253        int error;
 254
 255        if(!once) {
 256                once = 1;
 257
 258                error = request_irq(FLOPPY_IRQ, sparc_floppy_irq,
 259                                    0, "floppy", NULL);
 260
 261                return ((error == 0) ? 0 : -1);
 262        }
 263        return 0;
 264}
 265
 266static void sun_fd_free_irq(void)
 267{
 268}
 269
 270static unsigned int sun_get_dma_residue(void)
 271{
 272        /* XXX This isn't really correct. XXX */
 273        return 0;
 274}
 275
 276static int sun_fd_eject(int drive)
 277{
 278        set_dor(0x00, 0xff, 0x90);
 279        udelay(500);
 280        set_dor(0x00, 0x6f, 0x00);
 281        udelay(500);
 282        return 0;
 283}
 284
 285#include <asm/ebus_dma.h>
 286#include <asm/ns87303.h>
 287
 288static struct ebus_dma_info sun_pci_fd_ebus_dma;
 289static struct device *sun_floppy_dev;
 290static int sun_pci_broken_drive = -1;
 291
 292struct sun_pci_dma_op {
 293        unsigned int    addr;
 294        int             len;
 295        int             direction;
 296        char            *buf;
 297};
 298static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
 299static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
 300
 301irqreturn_t floppy_interrupt(int irq, void *dev_id);
 302
 303static unsigned char sun_pci_fd_inb(unsigned long base, unsigned int reg)
 304{
 305        udelay(5);
 306        return inb(base + reg);
 307}
 308
 309static void sun_pci_fd_outb(unsigned char val, unsigned long base,
 310                            unsigned int reg)
 311{
 312        udelay(5);
 313        outb(val, base + reg);
 314}
 315
 316static void sun_pci_fd_broken_outb(unsigned char val, unsigned long base,
 317                                   unsigned int reg)
 318{
 319        udelay(5);
 320        /*
 321         * XXX: Due to SUN's broken floppy connector on AX and AXi
 322         *      we need to turn on MOTOR_0 also, if the floppy is
 323         *      jumpered to DS1 (like most PC floppies are). I hope
 324         *      this does not hurt correct hardware like the AXmp.
 325         *      (Eddie, Sep 12 1998).
 326         */
 327        if (reg == FD_DOR) {
 328                if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
 329                        val |= 0x10;
 330                }
 331        }
 332        outb(val, base + reg);
 333}
 334
 335#ifdef PCI_FDC_SWAP_DRIVES
 336static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long base,
 337                                       unsigned int reg)
 338{
 339        udelay(5);
 340        /*
 341         * XXX: Due to SUN's broken floppy connector on AX and AXi
 342         *      we need to turn on MOTOR_0 also, if the floppy is
 343         *      jumpered to DS1 (like most PC floppies are). I hope
 344         *      this does not hurt correct hardware like the AXmp.
 345         *      (Eddie, Sep 12 1998).
 346         */
 347        if (reg == FD_DOR) {
 348                if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
 349                        val &= ~(0x03);
 350                        val |= 0x21;
 351                }
 352        }
 353        outb(val, base + reg);
 354}
 355#endif /* PCI_FDC_SWAP_DRIVES */
 356
 357static void sun_pci_fd_enable_dma(void)
 358{
 359        BUG_ON((NULL == sun_pci_dma_pending.buf)        ||
 360            (0    == sun_pci_dma_pending.len)   ||
 361            (0    == sun_pci_dma_pending.direction));
 362
 363        sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
 364        sun_pci_dma_current.len = sun_pci_dma_pending.len;
 365        sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
 366
 367        sun_pci_dma_pending.buf  = NULL;
 368        sun_pci_dma_pending.len  = 0;
 369        sun_pci_dma_pending.direction = 0;
 370        sun_pci_dma_pending.addr = -1U;
 371
 372        sun_pci_dma_current.addr =
 373                dma_map_single(sun_floppy_dev,
 374                               sun_pci_dma_current.buf,
 375                               sun_pci_dma_current.len,
 376                               sun_pci_dma_current.direction);
 377
 378        ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
 379
 380        if (ebus_dma_request(&sun_pci_fd_ebus_dma,
 381                             sun_pci_dma_current.addr,
 382                             sun_pci_dma_current.len))
 383                BUG();
 384}
 385
 386static void sun_pci_fd_disable_dma(void)
 387{
 388        ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
 389        if (sun_pci_dma_current.addr != -1U)
 390                dma_unmap_single(sun_floppy_dev,
 391                                 sun_pci_dma_current.addr,
 392                                 sun_pci_dma_current.len,
 393                                 sun_pci_dma_current.direction);
 394        sun_pci_dma_current.addr = -1U;
 395}
 396
 397static void sun_pci_fd_set_dma_mode(int mode)
 398{
 399        if (mode == DMA_MODE_WRITE)
 400                sun_pci_dma_pending.direction = DMA_TO_DEVICE;
 401        else
 402                sun_pci_dma_pending.direction = DMA_FROM_DEVICE;
 403
 404        ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
 405}
 406
 407static void sun_pci_fd_set_dma_count(int length)
 408{
 409        sun_pci_dma_pending.len = length;
 410}
 411
 412static void sun_pci_fd_set_dma_addr(char *buffer)
 413{
 414        sun_pci_dma_pending.buf = buffer;
 415}
 416
 417static unsigned int sun_pci_get_dma_residue(void)
 418{
 419        return ebus_dma_residue(&sun_pci_fd_ebus_dma);
 420}
 421
 422static int sun_pci_fd_request_irq(void)
 423{
 424        return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
 425}
 426
 427static void sun_pci_fd_free_irq(void)
 428{
 429        ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
 430}
 431
 432static int sun_pci_fd_eject(int drive)
 433{
 434        return -EINVAL;
 435}
 436
 437void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
 438{
 439        floppy_interrupt(0, NULL);
 440}
 441
 442/*
 443 * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
 444 * even if this is configured using DS1, thus looks like /dev/fd1 with
 445 * the cabling used in Ultras.
 446 */
 447#define DOR     (port + 2)
 448#define MSR     (port + 4)
 449#define FIFO    (port + 5)
 450
 451static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
 452                                unsigned long reg)
 453{
 454        unsigned char status;
 455        int timeout = 1000;
 456
 457        while (!((status = inb(MSR)) & 0x80) && --timeout)
 458                udelay(100);
 459        outb(val, reg);
 460}
 461
 462static unsigned char sun_pci_fd_sensei(unsigned long port)
 463{
 464        unsigned char result[2] = { 0x70, 0x00 };
 465        unsigned char status;
 466        int i = 0;
 467
 468        sun_pci_fd_out_byte(port, 0x08, FIFO);
 469        do {
 470                int timeout = 1000;
 471
 472                while (!((status = inb(MSR)) & 0x80) && --timeout)
 473                        udelay(100);
 474
 475                if (!timeout)
 476                        break;
 477
 478                if ((status & 0xf0) == 0xd0)
 479                        result[i++] = inb(FIFO);
 480                else
 481                        break;
 482        } while (i < 2);
 483
 484        return result[0];
 485}
 486
 487static void sun_pci_fd_reset(unsigned long port)
 488{
 489        unsigned char mask = 0x00;
 490        unsigned char status;
 491        int timeout = 10000;
 492
 493        outb(0x80, MSR);
 494        do {
 495                status = sun_pci_fd_sensei(port);
 496                if ((status & 0xc0) == 0xc0)
 497                        mask |= 1 << (status & 0x03);
 498                else
 499                        udelay(100);
 500        } while ((mask != 0x0f) && --timeout);
 501}
 502
 503static int sun_pci_fd_test_drive(unsigned long port, int drive)
 504{
 505        unsigned char status, data;
 506        int timeout = 1000;
 507        int ready;
 508
 509        sun_pci_fd_reset(port);
 510
 511        data = (0x10 << drive) | 0x0c | drive;
 512        sun_pci_fd_out_byte(port, data, DOR);
 513
 514        sun_pci_fd_out_byte(port, 0x07, FIFO);
 515        sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
 516
 517        do {
 518                udelay(100);
 519                status = sun_pci_fd_sensei(port);
 520        } while (((status & 0xc0) == 0x80) && --timeout);
 521
 522        if (!timeout)
 523                ready = 0;
 524        else
 525                ready = (status & 0x10) ? 0 : 1;
 526
 527        sun_pci_fd_reset(port);
 528        return ready;
 529}
 530#undef FIFO
 531#undef MSR
 532#undef DOR
 533
 534static int __init ebus_fdthree_p(struct device_node *dp)
 535{
 536        if (of_node_name_eq(dp, "fdthree"))
 537                return 1;
 538        if (of_node_name_eq(dp, "floppy")) {
 539                const char *compat;
 540
 541                compat = of_get_property(dp, "compatible", NULL);
 542                if (compat && !strcmp(compat, "fdthree"))
 543                        return 1;
 544        }
 545        return 0;
 546}
 547
 548static unsigned long __init sun_floppy_init(void)
 549{
 550        static int initialized = 0;
 551        struct device_node *dp;
 552        struct platform_device *op;
 553        const char *prop;
 554        char state[128];
 555
 556        if (initialized)
 557                return sun_floppy_types[0];
 558        initialized = 1;
 559
 560        op = NULL;
 561
 562        for_each_node_by_name(dp, "SUNW,fdtwo") {
 563                if (!of_node_name_eq(dp->parent, "sbus"))
 564                        continue;
 565                op = of_find_device_by_node(dp);
 566                if (op)
 567                        break;
 568        }
 569        if (op) {
 570                floppy_op = op;
 571                FLOPPY_IRQ = op->archdata.irqs[0];
 572        } else {
 573                struct device_node *ebus_dp;
 574                void __iomem *auxio_reg;
 575                const char *state_prop;
 576                unsigned long config;
 577
 578                dp = NULL;
 579                for_each_node_by_name(ebus_dp, "ebus") {
 580                        for (dp = ebus_dp->child; dp; dp = dp->sibling) {
 581                                if (ebus_fdthree_p(dp))
 582                                        goto found_fdthree;
 583                        }
 584                }
 585        found_fdthree:
 586                if (!dp)
 587                        return 0;
 588
 589                op = of_find_device_by_node(dp);
 590                if (!op)
 591                        return 0;
 592
 593                state_prop = of_get_property(op->dev.of_node, "status", NULL);
 594                if (state_prop && !strncmp(state_prop, "disabled", 8))
 595                        return 0;
 596
 597                FLOPPY_IRQ = op->archdata.irqs[0];
 598
 599                /* Make sure the high density bit is set, some systems
 600                 * (most notably Ultra5/Ultra10) come up with it clear.
 601                 */
 602                auxio_reg = (void __iomem *) op->resource[2].start;
 603                writel(readl(auxio_reg)|0x2, auxio_reg);
 604
 605                sun_floppy_dev = &op->dev;
 606
 607                spin_lock_init(&sun_pci_fd_ebus_dma.lock);
 608
 609                /* XXX ioremap */
 610                sun_pci_fd_ebus_dma.regs = (void __iomem *)
 611                        op->resource[1].start;
 612                if (!sun_pci_fd_ebus_dma.regs)
 613                        return 0;
 614
 615                sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
 616                                             EBUS_DMA_FLAG_TCI_DISABLE);
 617                sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
 618                sun_pci_fd_ebus_dma.client_cookie = NULL;
 619                sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
 620                strcpy(sun_pci_fd_ebus_dma.name, "floppy");
 621                if (ebus_dma_register(&sun_pci_fd_ebus_dma))
 622                        return 0;
 623
 624                /* XXX ioremap */
 625                sun_fdc = (struct sun_flpy_controller *) op->resource[0].start;
 626
 627                sun_fdops.fd_inb = sun_pci_fd_inb;
 628                sun_fdops.fd_outb = sun_pci_fd_outb;
 629
 630                can_use_virtual_dma = use_virtual_dma = 0;
 631                sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
 632                sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
 633                sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
 634                sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
 635                sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
 636                sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
 637
 638                sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
 639                sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
 640
 641                sun_fdops.fd_eject = sun_pci_fd_eject;
 642
 643                fdc_status = (unsigned long) &sun_fdc->status_82077;
 644
 645                /*
 646                 * XXX: Find out on which machines this is really needed.
 647                 */
 648                if (1) {
 649                        sun_pci_broken_drive = 1;
 650                        sun_fdops.fd_outb = sun_pci_fd_broken_outb;
 651                }
 652
 653                allowed_drive_mask = 0;
 654                if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
 655                        sun_floppy_types[0] = 4;
 656                if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
 657                        sun_floppy_types[1] = 4;
 658
 659                /*
 660                 * Find NS87303 SuperIO config registers (through ecpp).
 661                 */
 662                config = 0;
 663                for (dp = ebus_dp->child; dp; dp = dp->sibling) {
 664                        if (of_node_name_eq(dp, "ecpp")) {
 665                                struct platform_device *ecpp_op;
 666
 667                                ecpp_op = of_find_device_by_node(dp);
 668                                if (ecpp_op)
 669                                        config = ecpp_op->resource[1].start;
 670                                goto config_done;
 671                        }
 672                }
 673        config_done:
 674
 675                /*
 676                 * Sanity check, is this really the NS87303?
 677                 */
 678                switch (config & 0x3ff) {
 679                case 0x02e:
 680                case 0x15c:
 681                case 0x26e:
 682                case 0x398:
 683                        break;
 684                default:
 685                        config = 0;
 686                }
 687
 688                if (!config)
 689                        return sun_floppy_types[0];
 690
 691                /* Enable PC-AT mode. */
 692                ns87303_modify(config, ASC, 0, 0xc0);
 693
 694#ifdef PCI_FDC_SWAP_DRIVES
 695                /*
 696                 * If only Floppy 1 is present, swap drives.
 697                 */
 698                if (!sun_floppy_types[0] && sun_floppy_types[1]) {
 699                        /*
 700                         * Set the drive exchange bit in FCR on NS87303,
 701                         * make sure other bits are sane before doing so.
 702                         */
 703                        ns87303_modify(config, FER, FER_EDM, 0);
 704                        ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
 705                        ns87303_modify(config, FCR, 0, FCR_LDE);
 706
 707                        config = sun_floppy_types[0];
 708                        sun_floppy_types[0] = sun_floppy_types[1];
 709                        sun_floppy_types[1] = config;
 710
 711                        if (sun_pci_broken_drive != -1) {
 712                                sun_pci_broken_drive = 1 - sun_pci_broken_drive;
 713                                sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
 714                        }
 715                }
 716#endif /* PCI_FDC_SWAP_DRIVES */
 717
 718                return sun_floppy_types[0];
 719        }
 720        prop = of_get_property(op->dev.of_node, "status", NULL);
 721        if (prop && !strncmp(state, "disabled", 8))
 722                return 0;
 723
 724        /*
 725         * We cannot do of_ioremap here: it does request_region,
 726         * which the generic floppy driver tries to do once again.
 727         * But we must use the sdev resource values as they have
 728         * had parent ranges applied.
 729         */
 730        sun_fdc = (struct sun_flpy_controller *)
 731                (op->resource[0].start +
 732                 ((op->resource[0].flags & 0x1ffUL) << 32UL));
 733
 734        /* Last minute sanity check... */
 735        if (sbus_readb(&sun_fdc->status1_82077) == 0xff) {
 736                sun_fdc = (struct sun_flpy_controller *)-1;
 737                return 0;
 738        }
 739
 740        sun_fdops.fd_inb = sun_82077_fd_inb;
 741        sun_fdops.fd_outb = sun_82077_fd_outb;
 742
 743        can_use_virtual_dma = use_virtual_dma = 1;
 744        sun_fdops.fd_enable_dma = sun_fd_enable_dma;
 745        sun_fdops.fd_disable_dma = sun_fd_disable_dma;
 746        sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
 747        sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
 748        sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
 749        sun_fdops.get_dma_residue = sun_get_dma_residue;
 750
 751        sun_fdops.fd_request_irq = sun_fd_request_irq;
 752        sun_fdops.fd_free_irq = sun_fd_free_irq;
 753
 754        sun_fdops.fd_eject = sun_fd_eject;
 755
 756        fdc_status = (unsigned long) &sun_fdc->status_82077;
 757
 758        /* Success... */
 759        allowed_drive_mask = 0x01;
 760        sun_floppy_types[0] = 4;
 761        sun_floppy_types[1] = 0;
 762
 763        return sun_floppy_types[0];
 764}
 765
 766#define EXTRA_FLOPPY_PARAMS
 767
 768static DEFINE_SPINLOCK(dma_spin_lock);
 769
 770#define claim_dma_lock() \
 771({      unsigned long flags; \
 772        spin_lock_irqsave(&dma_spin_lock, flags); \
 773        flags; \
 774})
 775
 776#define release_dma_lock(__flags) \
 777        spin_unlock_irqrestore(&dma_spin_lock, __flags);
 778
 779#endif /* !(__ASM_SPARC64_FLOPPY_H) */
 780