1*1a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 28e75f744SArnaud Giersch /* Low-level parallel port routines for built-in port on SGI IP32 38e75f744SArnaud Giersch * 48e75f744SArnaud Giersch * Author: Arnaud Giersch <arnaud.giersch@free.fr> 58e75f744SArnaud Giersch * 68e75f744SArnaud Giersch * Based on parport_pc.c by 78e75f744SArnaud Giersch * Phil Blundell, Tim Waugh, Jose Renau, David Campbell, 88e75f744SArnaud Giersch * Andrea Arcangeli, et al. 98e75f744SArnaud Giersch * 108e75f744SArnaud Giersch * Thanks to Ilya A. Volynets-Evenbakh for his help. 118e75f744SArnaud Giersch * 128e75f744SArnaud Giersch * Copyright (C) 2005, 2006 Arnaud Giersch. 138e75f744SArnaud Giersch */ 148e75f744SArnaud Giersch 158e75f744SArnaud Giersch /* Current status: 168e75f744SArnaud Giersch * 178e75f744SArnaud Giersch * Basic SPP and PS2 modes are supported. 188e75f744SArnaud Giersch * Support for parallel port IRQ is present. 198e75f744SArnaud Giersch * Hardware SPP (a.k.a. compatibility), EPP, and ECP modes are 208e75f744SArnaud Giersch * supported. 218e75f744SArnaud Giersch * SPP/ECP FIFO can be driven in PIO or DMA mode. PIO mode can work with 228e75f744SArnaud Giersch * or without interrupt support. 238e75f744SArnaud Giersch * 248e75f744SArnaud Giersch * Hardware ECP mode is not fully implemented (ecp_read_data and 258e75f744SArnaud Giersch * ecp_write_addr are actually missing). 268e75f744SArnaud Giersch * 278e75f744SArnaud Giersch * To do: 288e75f744SArnaud Giersch * 298e75f744SArnaud Giersch * Fully implement ECP mode. 308e75f744SArnaud Giersch * EPP and ECP mode need to be tested. I currently do not own any 318e75f744SArnaud Giersch * peripheral supporting these extended mode, and cannot test them. 328e75f744SArnaud Giersch * If DMA mode works well, decide if support for PIO FIFO modes should be 338e75f744SArnaud Giersch * dropped. 348e75f744SArnaud Giersch * Use the io{read,write} family functions when they become available in 358e75f744SArnaud Giersch * the linux-mips.org tree. Note: the MIPS specific functions readsb() 368e75f744SArnaud Giersch * and writesb() are to be translated by ioread8_rep() and iowrite8_rep() 378e75f744SArnaud Giersch * respectively. 388e75f744SArnaud Giersch */ 398e75f744SArnaud Giersch 408e75f744SArnaud Giersch /* The built-in parallel port on the SGI 02 workstation (a.k.a. IP32) is an 418e75f744SArnaud Giersch * IEEE 1284 parallel port driven by a Texas Instrument TL16PIR552PH chip[1]. 428e75f744SArnaud Giersch * This chip supports SPP, bidirectional, EPP and ECP modes. It has a 16 byte 438e75f744SArnaud Giersch * FIFO buffer and supports DMA transfers. 448e75f744SArnaud Giersch * 458e75f744SArnaud Giersch * [1] http://focus.ti.com/docs/prod/folders/print/tl16pir552.html 468e75f744SArnaud Giersch * 478e75f744SArnaud Giersch * Theoretically, we could simply use the parport_pc module. It is however 488e75f744SArnaud Giersch * not so simple. The parport_pc code assumes that the parallel port 498e75f744SArnaud Giersch * registers are port-mapped. On the O2, they are memory-mapped. 508e75f744SArnaud Giersch * Furthermore, each register is replicated on 256 consecutive addresses (as 518e75f744SArnaud Giersch * it is for the built-in serial ports on the same chip). 528e75f744SArnaud Giersch */ 538e75f744SArnaud Giersch 548e75f744SArnaud Giersch /*--- Some configuration defines ---------------------------------------*/ 558e75f744SArnaud Giersch 568e75f744SArnaud Giersch /* DEBUG_PARPORT_IP32 578e75f744SArnaud Giersch * 0 disable debug 588e75f744SArnaud Giersch * 1 standard level: pr_debug1 is enabled 598e75f744SArnaud Giersch * 2 parport_ip32_dump_state is enabled 608e75f744SArnaud Giersch * >=3 verbose level: pr_debug is enabled 618e75f744SArnaud Giersch */ 628e75f744SArnaud Giersch #if !defined(DEBUG_PARPORT_IP32) 638e75f744SArnaud Giersch # define DEBUG_PARPORT_IP32 0 /* 0 (disabled) for production */ 648e75f744SArnaud Giersch #endif 658e75f744SArnaud Giersch 668e75f744SArnaud Giersch /*----------------------------------------------------------------------*/ 678e75f744SArnaud Giersch 688e75f744SArnaud Giersch /* Setup DEBUG macros. This is done before any includes, just in case we 698e75f744SArnaud Giersch * activate pr_debug() with DEBUG_PARPORT_IP32 >= 3. 708e75f744SArnaud Giersch */ 718e75f744SArnaud Giersch #if DEBUG_PARPORT_IP32 == 1 728e75f744SArnaud Giersch # warning DEBUG_PARPORT_IP32 == 1 738e75f744SArnaud Giersch #elif DEBUG_PARPORT_IP32 == 2 748e75f744SArnaud Giersch # warning DEBUG_PARPORT_IP32 == 2 758e75f744SArnaud Giersch #elif DEBUG_PARPORT_IP32 >= 3 768e75f744SArnaud Giersch # warning DEBUG_PARPORT_IP32 >= 3 778e75f744SArnaud Giersch # if !defined(DEBUG) 788e75f744SArnaud Giersch # define DEBUG /* enable pr_debug() in kernel.h */ 798e75f744SArnaud Giersch # endif 808e75f744SArnaud Giersch #endif 818e75f744SArnaud Giersch 828e75f744SArnaud Giersch #include <linux/completion.h> 838e75f744SArnaud Giersch #include <linux/delay.h> 848e75f744SArnaud Giersch #include <linux/dma-mapping.h> 858e75f744SArnaud Giersch #include <linux/err.h> 868e75f744SArnaud Giersch #include <linux/init.h> 878e75f744SArnaud Giersch #include <linux/interrupt.h> 888e75f744SArnaud Giersch #include <linux/jiffies.h> 898e75f744SArnaud Giersch #include <linux/kernel.h> 908e75f744SArnaud Giersch #include <linux/module.h> 918e75f744SArnaud Giersch #include <linux/parport.h> 92174cd4b1SIngo Molnar #include <linux/sched/signal.h> 935a0e3ad6STejun Heo #include <linux/slab.h> 948e75f744SArnaud Giersch #include <linux/spinlock.h> 958e75f744SArnaud Giersch #include <linux/stddef.h> 968e75f744SArnaud Giersch #include <linux/types.h> 978e75f744SArnaud Giersch #include <asm/io.h> 988e75f744SArnaud Giersch #include <asm/ip32/ip32_ints.h> 998e75f744SArnaud Giersch #include <asm/ip32/mace.h> 1008e75f744SArnaud Giersch 1018e75f744SArnaud Giersch /*--- Global variables -------------------------------------------------*/ 1028e75f744SArnaud Giersch 1038e75f744SArnaud Giersch /* Verbose probing on by default for debugging. */ 1048e75f744SArnaud Giersch #if DEBUG_PARPORT_IP32 >= 1 1058e75f744SArnaud Giersch # define DEFAULT_VERBOSE_PROBING 1 1068e75f744SArnaud Giersch #else 1078e75f744SArnaud Giersch # define DEFAULT_VERBOSE_PROBING 0 1088e75f744SArnaud Giersch #endif 1098e75f744SArnaud Giersch 1108e75f744SArnaud Giersch /* Default prefix for printk */ 1118e75f744SArnaud Giersch #define PPIP32 "parport_ip32: " 1128e75f744SArnaud Giersch 1138e75f744SArnaud Giersch /* 1148e75f744SArnaud Giersch * These are the module parameters: 1158e75f744SArnaud Giersch * @features: bit mask of features to enable/disable 1168e75f744SArnaud Giersch * (all enabled by default) 1178e75f744SArnaud Giersch * @verbose_probing: log chit-chat during initialization 1188e75f744SArnaud Giersch */ 1198e75f744SArnaud Giersch #define PARPORT_IP32_ENABLE_IRQ (1U << 0) 1208e75f744SArnaud Giersch #define PARPORT_IP32_ENABLE_DMA (1U << 1) 1218e75f744SArnaud Giersch #define PARPORT_IP32_ENABLE_SPP (1U << 2) 1228e75f744SArnaud Giersch #define PARPORT_IP32_ENABLE_EPP (1U << 3) 1238e75f744SArnaud Giersch #define PARPORT_IP32_ENABLE_ECP (1U << 4) 1248e75f744SArnaud Giersch static unsigned int features = ~0U; 12590ab5ee9SRusty Russell static bool verbose_probing = DEFAULT_VERBOSE_PROBING; 1268e75f744SArnaud Giersch 1278e75f744SArnaud Giersch /* We do not support more than one port. */ 128df4c756eSCarlos Palminha static struct parport *this_port; 1298e75f744SArnaud Giersch 1308e75f744SArnaud Giersch /* Timing constants for FIFO modes. */ 1318e75f744SArnaud Giersch #define FIFO_NFAULT_TIMEOUT 100 /* milliseconds */ 1328e75f744SArnaud Giersch #define FIFO_POLLING_INTERVAL 50 /* microseconds */ 1338e75f744SArnaud Giersch 1348e75f744SArnaud Giersch /*--- I/O register definitions -----------------------------------------*/ 1358e75f744SArnaud Giersch 1368e75f744SArnaud Giersch /** 1378e75f744SArnaud Giersch * struct parport_ip32_regs - virtual addresses of parallel port registers 1388e75f744SArnaud Giersch * @data: Data Register 1398e75f744SArnaud Giersch * @dsr: Device Status Register 1408e75f744SArnaud Giersch * @dcr: Device Control Register 1418e75f744SArnaud Giersch * @eppAddr: EPP Address Register 1428e75f744SArnaud Giersch * @eppData0: EPP Data Register 0 1438e75f744SArnaud Giersch * @eppData1: EPP Data Register 1 1448e75f744SArnaud Giersch * @eppData2: EPP Data Register 2 1458e75f744SArnaud Giersch * @eppData3: EPP Data Register 3 1468e75f744SArnaud Giersch * @ecpAFifo: ECP Address FIFO 1478e75f744SArnaud Giersch * @fifo: General FIFO register. The same address is used for: 1488e75f744SArnaud Giersch * - cFifo, the Parallel Port DATA FIFO 1498e75f744SArnaud Giersch * - ecpDFifo, the ECP Data FIFO 1508e75f744SArnaud Giersch * - tFifo, the ECP Test FIFO 1518e75f744SArnaud Giersch * @cnfgA: Configuration Register A 1528e75f744SArnaud Giersch * @cnfgB: Configuration Register B 1538e75f744SArnaud Giersch * @ecr: Extended Control Register 1548e75f744SArnaud Giersch */ 1558e75f744SArnaud Giersch struct parport_ip32_regs { 1568e75f744SArnaud Giersch void __iomem *data; 1578e75f744SArnaud Giersch void __iomem *dsr; 1588e75f744SArnaud Giersch void __iomem *dcr; 1598e75f744SArnaud Giersch void __iomem *eppAddr; 1608e75f744SArnaud Giersch void __iomem *eppData0; 1618e75f744SArnaud Giersch void __iomem *eppData1; 1628e75f744SArnaud Giersch void __iomem *eppData2; 1638e75f744SArnaud Giersch void __iomem *eppData3; 1648e75f744SArnaud Giersch void __iomem *ecpAFifo; 1658e75f744SArnaud Giersch void __iomem *fifo; 1668e75f744SArnaud Giersch void __iomem *cnfgA; 1678e75f744SArnaud Giersch void __iomem *cnfgB; 1688e75f744SArnaud Giersch void __iomem *ecr; 1698e75f744SArnaud Giersch }; 1708e75f744SArnaud Giersch 1718e75f744SArnaud Giersch /* Device Status Register */ 1728e75f744SArnaud Giersch #define DSR_nBUSY (1U << 7) /* PARPORT_STATUS_BUSY */ 1738e75f744SArnaud Giersch #define DSR_nACK (1U << 6) /* PARPORT_STATUS_ACK */ 1748e75f744SArnaud Giersch #define DSR_PERROR (1U << 5) /* PARPORT_STATUS_PAPEROUT */ 1758e75f744SArnaud Giersch #define DSR_SELECT (1U << 4) /* PARPORT_STATUS_SELECT */ 1768e75f744SArnaud Giersch #define DSR_nFAULT (1U << 3) /* PARPORT_STATUS_ERROR */ 1778e75f744SArnaud Giersch #define DSR_nPRINT (1U << 2) /* specific to TL16PIR552 */ 1788e75f744SArnaud Giersch /* #define DSR_reserved (1U << 1) */ 1798e75f744SArnaud Giersch #define DSR_TIMEOUT (1U << 0) /* EPP timeout */ 1808e75f744SArnaud Giersch 1818e75f744SArnaud Giersch /* Device Control Register */ 1828e75f744SArnaud Giersch /* #define DCR_reserved (1U << 7) | (1U << 6) */ 1838e75f744SArnaud Giersch #define DCR_DIR (1U << 5) /* direction */ 1848e75f744SArnaud Giersch #define DCR_IRQ (1U << 4) /* interrupt on nAck */ 1858e75f744SArnaud Giersch #define DCR_SELECT (1U << 3) /* PARPORT_CONTROL_SELECT */ 1868e75f744SArnaud Giersch #define DCR_nINIT (1U << 2) /* PARPORT_CONTROL_INIT */ 1878e75f744SArnaud Giersch #define DCR_AUTOFD (1U << 1) /* PARPORT_CONTROL_AUTOFD */ 1888e75f744SArnaud Giersch #define DCR_STROBE (1U << 0) /* PARPORT_CONTROL_STROBE */ 1898e75f744SArnaud Giersch 1908e75f744SArnaud Giersch /* ECP Configuration Register A */ 1918e75f744SArnaud Giersch #define CNFGA_IRQ (1U << 7) 1928e75f744SArnaud Giersch #define CNFGA_ID_MASK ((1U << 6) | (1U << 5) | (1U << 4)) 1938e75f744SArnaud Giersch #define CNFGA_ID_SHIFT 4 1948e75f744SArnaud Giersch #define CNFGA_ID_16 (00U << CNFGA_ID_SHIFT) 1958e75f744SArnaud Giersch #define CNFGA_ID_8 (01U << CNFGA_ID_SHIFT) 1968e75f744SArnaud Giersch #define CNFGA_ID_32 (02U << CNFGA_ID_SHIFT) 1978e75f744SArnaud Giersch /* #define CNFGA_reserved (1U << 3) */ 1988e75f744SArnaud Giersch #define CNFGA_nBYTEINTRANS (1U << 2) 1998e75f744SArnaud Giersch #define CNFGA_PWORDLEFT ((1U << 1) | (1U << 0)) 2008e75f744SArnaud Giersch 2018e75f744SArnaud Giersch /* ECP Configuration Register B */ 2028e75f744SArnaud Giersch #define CNFGB_COMPRESS (1U << 7) 2038e75f744SArnaud Giersch #define CNFGB_INTRVAL (1U << 6) 2048e75f744SArnaud Giersch #define CNFGB_IRQ_MASK ((1U << 5) | (1U << 4) | (1U << 3)) 2058e75f744SArnaud Giersch #define CNFGB_IRQ_SHIFT 3 2068e75f744SArnaud Giersch #define CNFGB_DMA_MASK ((1U << 2) | (1U << 1) | (1U << 0)) 2078e75f744SArnaud Giersch #define CNFGB_DMA_SHIFT 0 2088e75f744SArnaud Giersch 2098e75f744SArnaud Giersch /* Extended Control Register */ 2108e75f744SArnaud Giersch #define ECR_MODE_MASK ((1U << 7) | (1U << 6) | (1U << 5)) 2118e75f744SArnaud Giersch #define ECR_MODE_SHIFT 5 2128e75f744SArnaud Giersch #define ECR_MODE_SPP (00U << ECR_MODE_SHIFT) 2138e75f744SArnaud Giersch #define ECR_MODE_PS2 (01U << ECR_MODE_SHIFT) 2148e75f744SArnaud Giersch #define ECR_MODE_PPF (02U << ECR_MODE_SHIFT) 2158e75f744SArnaud Giersch #define ECR_MODE_ECP (03U << ECR_MODE_SHIFT) 2168e75f744SArnaud Giersch #define ECR_MODE_EPP (04U << ECR_MODE_SHIFT) 2178e75f744SArnaud Giersch /* #define ECR_MODE_reserved (05U << ECR_MODE_SHIFT) */ 2188e75f744SArnaud Giersch #define ECR_MODE_TST (06U << ECR_MODE_SHIFT) 2198e75f744SArnaud Giersch #define ECR_MODE_CFG (07U << ECR_MODE_SHIFT) 2208e75f744SArnaud Giersch #define ECR_nERRINTR (1U << 4) 2218e75f744SArnaud Giersch #define ECR_DMAEN (1U << 3) 2228e75f744SArnaud Giersch #define ECR_SERVINTR (1U << 2) 2238e75f744SArnaud Giersch #define ECR_F_FULL (1U << 1) 2248e75f744SArnaud Giersch #define ECR_F_EMPTY (1U << 0) 2258e75f744SArnaud Giersch 2268e75f744SArnaud Giersch /*--- Private data -----------------------------------------------------*/ 2278e75f744SArnaud Giersch 2288e75f744SArnaud Giersch /** 2298e75f744SArnaud Giersch * enum parport_ip32_irq_mode - operation mode of interrupt handler 2308e75f744SArnaud Giersch * @PARPORT_IP32_IRQ_FWD: forward interrupt to the upper parport layer 2318e75f744SArnaud Giersch * @PARPORT_IP32_IRQ_HERE: interrupt is handled locally 2328e75f744SArnaud Giersch */ 2338e75f744SArnaud Giersch enum parport_ip32_irq_mode { PARPORT_IP32_IRQ_FWD, PARPORT_IP32_IRQ_HERE }; 2348e75f744SArnaud Giersch 2358e75f744SArnaud Giersch /** 2368e75f744SArnaud Giersch * struct parport_ip32_private - private stuff for &struct parport 2378e75f744SArnaud Giersch * @regs: register addresses 2388e75f744SArnaud Giersch * @dcr_cache: cached contents of DCR 2398e75f744SArnaud Giersch * @dcr_writable: bit mask of writable DCR bits 2408e75f744SArnaud Giersch * @pword: number of bytes per PWord 2418e75f744SArnaud Giersch * @fifo_depth: number of PWords that FIFO will hold 2428e75f744SArnaud Giersch * @readIntrThreshold: minimum number of PWords we can read 2438e75f744SArnaud Giersch * if we get an interrupt 2448e75f744SArnaud Giersch * @writeIntrThreshold: minimum number of PWords we can write 2458e75f744SArnaud Giersch * if we get an interrupt 2468e75f744SArnaud Giersch * @irq_mode: operation mode of interrupt handler for this port 2478e75f744SArnaud Giersch * @irq_complete: mutex used to wait for an interrupt to occur 2488e75f744SArnaud Giersch */ 2498e75f744SArnaud Giersch struct parport_ip32_private { 2508e75f744SArnaud Giersch struct parport_ip32_regs regs; 2518e75f744SArnaud Giersch unsigned int dcr_cache; 2528e75f744SArnaud Giersch unsigned int dcr_writable; 2538e75f744SArnaud Giersch unsigned int pword; 2548e75f744SArnaud Giersch unsigned int fifo_depth; 2558e75f744SArnaud Giersch unsigned int readIntrThreshold; 2568e75f744SArnaud Giersch unsigned int writeIntrThreshold; 2578e75f744SArnaud Giersch enum parport_ip32_irq_mode irq_mode; 2588e75f744SArnaud Giersch struct completion irq_complete; 2598e75f744SArnaud Giersch }; 2608e75f744SArnaud Giersch 2618e75f744SArnaud Giersch /*--- Debug code -------------------------------------------------------*/ 2628e75f744SArnaud Giersch 2638e75f744SArnaud Giersch /* 2648e75f744SArnaud Giersch * pr_debug1 - print debug messages 2658e75f744SArnaud Giersch * 2668e75f744SArnaud Giersch * This is like pr_debug(), but is defined for %DEBUG_PARPORT_IP32 >= 1 2678e75f744SArnaud Giersch */ 2688e75f744SArnaud Giersch #if DEBUG_PARPORT_IP32 >= 1 2698e75f744SArnaud Giersch # define pr_debug1(...) printk(KERN_DEBUG __VA_ARGS__) 2708e75f744SArnaud Giersch #else /* DEBUG_PARPORT_IP32 < 1 */ 2718e75f744SArnaud Giersch # define pr_debug1(...) do { } while (0) 2728e75f744SArnaud Giersch #endif 2738e75f744SArnaud Giersch 2748e75f744SArnaud Giersch /* 2758e75f744SArnaud Giersch * pr_trace, pr_trace1 - trace function calls 2768e75f744SArnaud Giersch * @p: pointer to &struct parport 2778e75f744SArnaud Giersch * @fmt: printk format string 2788e75f744SArnaud Giersch * @...: parameters for format string 2798e75f744SArnaud Giersch * 2808e75f744SArnaud Giersch * Macros used to trace function calls. The given string is formatted after 2818e75f744SArnaud Giersch * function name. pr_trace() uses pr_debug(), and pr_trace1() uses 2828e75f744SArnaud Giersch * pr_debug1(). __pr_trace() is the low-level macro and is not to be used 2838e75f744SArnaud Giersch * directly. 2848e75f744SArnaud Giersch */ 2858e75f744SArnaud Giersch #define __pr_trace(pr, p, fmt, ...) \ 2868e75f744SArnaud Giersch pr("%s: %s" fmt "\n", \ 2878e75f744SArnaud Giersch ({ const struct parport *__p = (p); \ 2888e75f744SArnaud Giersch __p ? __p->name : "parport_ip32"; }), \ 2898e75f744SArnaud Giersch __func__ , ##__VA_ARGS__) 2908e75f744SArnaud Giersch #define pr_trace(p, fmt, ...) __pr_trace(pr_debug, p, fmt , ##__VA_ARGS__) 2918e75f744SArnaud Giersch #define pr_trace1(p, fmt, ...) __pr_trace(pr_debug1, p, fmt , ##__VA_ARGS__) 2928e75f744SArnaud Giersch 2938e75f744SArnaud Giersch /* 2948e75f744SArnaud Giersch * __pr_probe, pr_probe - print message if @verbose_probing is true 2958e75f744SArnaud Giersch * @p: pointer to &struct parport 2968e75f744SArnaud Giersch * @fmt: printk format string 2978e75f744SArnaud Giersch * @...: parameters for format string 2988e75f744SArnaud Giersch * 2998e75f744SArnaud Giersch * For new lines, use pr_probe(). Use __pr_probe() for continued lines. 3008e75f744SArnaud Giersch */ 3018e75f744SArnaud Giersch #define __pr_probe(...) \ 3028e75f744SArnaud Giersch do { if (verbose_probing) printk(__VA_ARGS__); } while (0) 3038e75f744SArnaud Giersch #define pr_probe(p, fmt, ...) \ 3048e75f744SArnaud Giersch __pr_probe(KERN_INFO PPIP32 "0x%lx: " fmt, (p)->base , ##__VA_ARGS__) 3058e75f744SArnaud Giersch 3068e75f744SArnaud Giersch /* 3078e75f744SArnaud Giersch * parport_ip32_dump_state - print register status of parport 3088e75f744SArnaud Giersch * @p: pointer to &struct parport 3098e75f744SArnaud Giersch * @str: string to add in message 3108e75f744SArnaud Giersch * @show_ecp_config: shall we dump ECP configuration registers too? 3118e75f744SArnaud Giersch * 3128e75f744SArnaud Giersch * This function is only here for debugging purpose, and should be used with 3138e75f744SArnaud Giersch * care. Reading the parallel port registers may have undesired side effects. 3148e75f744SArnaud Giersch * Especially if @show_ecp_config is true, the parallel port is resetted. 3158e75f744SArnaud Giersch * This function is only defined if %DEBUG_PARPORT_IP32 >= 2. 3168e75f744SArnaud Giersch */ 3178e75f744SArnaud Giersch #if DEBUG_PARPORT_IP32 >= 2 3188e75f744SArnaud Giersch static void parport_ip32_dump_state(struct parport *p, char *str, 3198e75f744SArnaud Giersch unsigned int show_ecp_config) 3208e75f744SArnaud Giersch { 3218e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 3228e75f744SArnaud Giersch unsigned int i; 3238e75f744SArnaud Giersch 3248e75f744SArnaud Giersch printk(KERN_DEBUG PPIP32 "%s: state (%s):\n", p->name, str); 3258e75f744SArnaud Giersch { 3268e75f744SArnaud Giersch static const char ecr_modes[8][4] = {"SPP", "PS2", "PPF", 3278e75f744SArnaud Giersch "ECP", "EPP", "???", 3288e75f744SArnaud Giersch "TST", "CFG"}; 3298e75f744SArnaud Giersch unsigned int ecr = readb(priv->regs.ecr); 3308e75f744SArnaud Giersch printk(KERN_DEBUG PPIP32 " ecr=0x%02x", ecr); 3318e75f744SArnaud Giersch printk(" %s", 3328e75f744SArnaud Giersch ecr_modes[(ecr & ECR_MODE_MASK) >> ECR_MODE_SHIFT]); 3338e75f744SArnaud Giersch if (ecr & ECR_nERRINTR) 3348e75f744SArnaud Giersch printk(",nErrIntrEn"); 3358e75f744SArnaud Giersch if (ecr & ECR_DMAEN) 3368e75f744SArnaud Giersch printk(",dmaEn"); 3378e75f744SArnaud Giersch if (ecr & ECR_SERVINTR) 3388e75f744SArnaud Giersch printk(",serviceIntr"); 3398e75f744SArnaud Giersch if (ecr & ECR_F_FULL) 3408e75f744SArnaud Giersch printk(",f_full"); 3418e75f744SArnaud Giersch if (ecr & ECR_F_EMPTY) 3428e75f744SArnaud Giersch printk(",f_empty"); 3438e75f744SArnaud Giersch printk("\n"); 3448e75f744SArnaud Giersch } 3458e75f744SArnaud Giersch if (show_ecp_config) { 3468e75f744SArnaud Giersch unsigned int oecr, cnfgA, cnfgB; 3478e75f744SArnaud Giersch oecr = readb(priv->regs.ecr); 3488e75f744SArnaud Giersch writeb(ECR_MODE_PS2, priv->regs.ecr); 3498e75f744SArnaud Giersch writeb(ECR_MODE_CFG, priv->regs.ecr); 3508e75f744SArnaud Giersch cnfgA = readb(priv->regs.cnfgA); 3518e75f744SArnaud Giersch cnfgB = readb(priv->regs.cnfgB); 3528e75f744SArnaud Giersch writeb(ECR_MODE_PS2, priv->regs.ecr); 3538e75f744SArnaud Giersch writeb(oecr, priv->regs.ecr); 3548e75f744SArnaud Giersch printk(KERN_DEBUG PPIP32 " cnfgA=0x%02x", cnfgA); 3558e75f744SArnaud Giersch printk(" ISA-%s", (cnfgA & CNFGA_IRQ) ? "Level" : "Pulses"); 3568e75f744SArnaud Giersch switch (cnfgA & CNFGA_ID_MASK) { 3578e75f744SArnaud Giersch case CNFGA_ID_8: 3588e75f744SArnaud Giersch printk(",8 bits"); 3598e75f744SArnaud Giersch break; 3608e75f744SArnaud Giersch case CNFGA_ID_16: 3618e75f744SArnaud Giersch printk(",16 bits"); 3628e75f744SArnaud Giersch break; 3638e75f744SArnaud Giersch case CNFGA_ID_32: 3648e75f744SArnaud Giersch printk(",32 bits"); 3658e75f744SArnaud Giersch break; 3668e75f744SArnaud Giersch default: 3678e75f744SArnaud Giersch printk(",unknown ID"); 3688e75f744SArnaud Giersch break; 3698e75f744SArnaud Giersch } 3708e75f744SArnaud Giersch if (!(cnfgA & CNFGA_nBYTEINTRANS)) 3718e75f744SArnaud Giersch printk(",ByteInTrans"); 3728e75f744SArnaud Giersch if ((cnfgA & CNFGA_ID_MASK) != CNFGA_ID_8) 3738e75f744SArnaud Giersch printk(",%d byte%s left", cnfgA & CNFGA_PWORDLEFT, 3748e75f744SArnaud Giersch ((cnfgA & CNFGA_PWORDLEFT) > 1) ? "s" : ""); 3758e75f744SArnaud Giersch printk("\n"); 3768e75f744SArnaud Giersch printk(KERN_DEBUG PPIP32 " cnfgB=0x%02x", cnfgB); 3778e75f744SArnaud Giersch printk(" irq=%u,dma=%u", 3788e75f744SArnaud Giersch (cnfgB & CNFGB_IRQ_MASK) >> CNFGB_IRQ_SHIFT, 3798e75f744SArnaud Giersch (cnfgB & CNFGB_DMA_MASK) >> CNFGB_DMA_SHIFT); 3808e75f744SArnaud Giersch printk(",intrValue=%d", !!(cnfgB & CNFGB_INTRVAL)); 3818e75f744SArnaud Giersch if (cnfgB & CNFGB_COMPRESS) 3828e75f744SArnaud Giersch printk(",compress"); 3838e75f744SArnaud Giersch printk("\n"); 3848e75f744SArnaud Giersch } 3858e75f744SArnaud Giersch for (i = 0; i < 2; i++) { 3868e75f744SArnaud Giersch unsigned int dcr = i ? priv->dcr_cache : readb(priv->regs.dcr); 3878e75f744SArnaud Giersch printk(KERN_DEBUG PPIP32 " dcr(%s)=0x%02x", 3888e75f744SArnaud Giersch i ? "soft" : "hard", dcr); 3898e75f744SArnaud Giersch printk(" %s", (dcr & DCR_DIR) ? "rev" : "fwd"); 3908e75f744SArnaud Giersch if (dcr & DCR_IRQ) 3918e75f744SArnaud Giersch printk(",ackIntEn"); 3928e75f744SArnaud Giersch if (!(dcr & DCR_SELECT)) 3938e75f744SArnaud Giersch printk(",nSelectIn"); 3948e75f744SArnaud Giersch if (dcr & DCR_nINIT) 3958e75f744SArnaud Giersch printk(",nInit"); 3968e75f744SArnaud Giersch if (!(dcr & DCR_AUTOFD)) 3978e75f744SArnaud Giersch printk(",nAutoFD"); 3988e75f744SArnaud Giersch if (!(dcr & DCR_STROBE)) 3998e75f744SArnaud Giersch printk(",nStrobe"); 4008e75f744SArnaud Giersch printk("\n"); 4018e75f744SArnaud Giersch } 4028e75f744SArnaud Giersch #define sep (f++ ? ',' : ' ') 4038e75f744SArnaud Giersch { 4048e75f744SArnaud Giersch unsigned int f = 0; 4058e75f744SArnaud Giersch unsigned int dsr = readb(priv->regs.dsr); 4068e75f744SArnaud Giersch printk(KERN_DEBUG PPIP32 " dsr=0x%02x", dsr); 4078e75f744SArnaud Giersch if (!(dsr & DSR_nBUSY)) 4088e75f744SArnaud Giersch printk("%cBusy", sep); 4098e75f744SArnaud Giersch if (dsr & DSR_nACK) 4108e75f744SArnaud Giersch printk("%cnAck", sep); 4118e75f744SArnaud Giersch if (dsr & DSR_PERROR) 4128e75f744SArnaud Giersch printk("%cPError", sep); 4138e75f744SArnaud Giersch if (dsr & DSR_SELECT) 4148e75f744SArnaud Giersch printk("%cSelect", sep); 4158e75f744SArnaud Giersch if (dsr & DSR_nFAULT) 4168e75f744SArnaud Giersch printk("%cnFault", sep); 4178e75f744SArnaud Giersch if (!(dsr & DSR_nPRINT)) 4188e75f744SArnaud Giersch printk("%c(Print)", sep); 4198e75f744SArnaud Giersch if (dsr & DSR_TIMEOUT) 4208e75f744SArnaud Giersch printk("%cTimeout", sep); 4218e75f744SArnaud Giersch printk("\n"); 4228e75f744SArnaud Giersch } 4238e75f744SArnaud Giersch #undef sep 4248e75f744SArnaud Giersch } 4258e75f744SArnaud Giersch #else /* DEBUG_PARPORT_IP32 < 2 */ 4268e75f744SArnaud Giersch #define parport_ip32_dump_state(...) do { } while (0) 4278e75f744SArnaud Giersch #endif 4288e75f744SArnaud Giersch 4298e75f744SArnaud Giersch /* 4308e75f744SArnaud Giersch * CHECK_EXTRA_BITS - track and log extra bits 4318e75f744SArnaud Giersch * @p: pointer to &struct parport 4328e75f744SArnaud Giersch * @b: byte to inspect 4338e75f744SArnaud Giersch * @m: bit mask of authorized bits 4348e75f744SArnaud Giersch * 4358e75f744SArnaud Giersch * This is used to track and log extra bits that should not be there in 4368e75f744SArnaud Giersch * parport_ip32_write_control() and parport_ip32_frob_control(). It is only 4378e75f744SArnaud Giersch * defined if %DEBUG_PARPORT_IP32 >= 1. 4388e75f744SArnaud Giersch */ 4398e75f744SArnaud Giersch #if DEBUG_PARPORT_IP32 >= 1 4408e75f744SArnaud Giersch #define CHECK_EXTRA_BITS(p, b, m) \ 4418e75f744SArnaud Giersch do { \ 4428e75f744SArnaud Giersch unsigned int __b = (b), __m = (m); \ 4438e75f744SArnaud Giersch if (__b & ~__m) \ 4448e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: extra bits in %s(%s): " \ 4458e75f744SArnaud Giersch "0x%02x/0x%02x\n", \ 4468e75f744SArnaud Giersch (p)->name, __func__, #b, __b, __m); \ 4478e75f744SArnaud Giersch } while (0) 4488e75f744SArnaud Giersch #else /* DEBUG_PARPORT_IP32 < 1 */ 4498e75f744SArnaud Giersch #define CHECK_EXTRA_BITS(...) do { } while (0) 4508e75f744SArnaud Giersch #endif 4518e75f744SArnaud Giersch 4528e75f744SArnaud Giersch /*--- IP32 parallel port DMA operations --------------------------------*/ 4538e75f744SArnaud Giersch 4548e75f744SArnaud Giersch /** 4558e75f744SArnaud Giersch * struct parport_ip32_dma_data - private data needed for DMA operation 4568e75f744SArnaud Giersch * @dir: DMA direction (from or to device) 4578e75f744SArnaud Giersch * @buf: buffer physical address 4588e75f744SArnaud Giersch * @len: buffer length 4598e75f744SArnaud Giersch * @next: address of next bytes to DMA transfer 4608e75f744SArnaud Giersch * @left: number of bytes remaining 4618e75f744SArnaud Giersch * @ctx: next context to write (0: context_a; 1: context_b) 4628e75f744SArnaud Giersch * @irq_on: are the DMA IRQs currently enabled? 4638e75f744SArnaud Giersch * @lock: spinlock to protect access to the structure 4648e75f744SArnaud Giersch */ 4658e75f744SArnaud Giersch struct parport_ip32_dma_data { 4668e75f744SArnaud Giersch enum dma_data_direction dir; 4678e75f744SArnaud Giersch dma_addr_t buf; 4688e75f744SArnaud Giersch dma_addr_t next; 4698e75f744SArnaud Giersch size_t len; 4708e75f744SArnaud Giersch size_t left; 4718e75f744SArnaud Giersch unsigned int ctx; 4728e75f744SArnaud Giersch unsigned int irq_on; 4738e75f744SArnaud Giersch spinlock_t lock; 4748e75f744SArnaud Giersch }; 4758e75f744SArnaud Giersch static struct parport_ip32_dma_data parport_ip32_dma; 4768e75f744SArnaud Giersch 4778e75f744SArnaud Giersch /** 4788e75f744SArnaud Giersch * parport_ip32_dma_setup_context - setup next DMA context 4798e75f744SArnaud Giersch * @limit: maximum data size for the context 4808e75f744SArnaud Giersch * 4818e75f744SArnaud Giersch * The alignment constraints must be verified in caller function, and the 4828e75f744SArnaud Giersch * parameter @limit must be set accordingly. 4838e75f744SArnaud Giersch */ 4848e75f744SArnaud Giersch static void parport_ip32_dma_setup_context(unsigned int limit) 4858e75f744SArnaud Giersch { 4868e75f744SArnaud Giersch unsigned long flags; 4878e75f744SArnaud Giersch 4888e75f744SArnaud Giersch spin_lock_irqsave(&parport_ip32_dma.lock, flags); 4898e75f744SArnaud Giersch if (parport_ip32_dma.left > 0) { 4908e75f744SArnaud Giersch /* Note: ctxreg is "volatile" here only because 4918e75f744SArnaud Giersch * mace->perif.ctrl.parport.context_a and context_b are 4928e75f744SArnaud Giersch * "volatile". */ 4938e75f744SArnaud Giersch volatile u64 __iomem *ctxreg = (parport_ip32_dma.ctx == 0) ? 4948e75f744SArnaud Giersch &mace->perif.ctrl.parport.context_a : 4958e75f744SArnaud Giersch &mace->perif.ctrl.parport.context_b; 4968e75f744SArnaud Giersch u64 count; 4978e75f744SArnaud Giersch u64 ctxval; 4988e75f744SArnaud Giersch if (parport_ip32_dma.left <= limit) { 4998e75f744SArnaud Giersch count = parport_ip32_dma.left; 5008e75f744SArnaud Giersch ctxval = MACEPAR_CONTEXT_LASTFLAG; 5018e75f744SArnaud Giersch } else { 5028e75f744SArnaud Giersch count = limit; 5038e75f744SArnaud Giersch ctxval = 0; 5048e75f744SArnaud Giersch } 5058e75f744SArnaud Giersch 5068e75f744SArnaud Giersch pr_trace(NULL, 5078e75f744SArnaud Giersch "(%u): 0x%04x:0x%04x, %u -> %u%s", 5088e75f744SArnaud Giersch limit, 5098e75f744SArnaud Giersch (unsigned int)parport_ip32_dma.buf, 5108e75f744SArnaud Giersch (unsigned int)parport_ip32_dma.next, 5118e75f744SArnaud Giersch (unsigned int)count, 5128e75f744SArnaud Giersch parport_ip32_dma.ctx, ctxval ? "*" : ""); 5138e75f744SArnaud Giersch 5148e75f744SArnaud Giersch ctxval |= parport_ip32_dma.next & 5158e75f744SArnaud Giersch MACEPAR_CONTEXT_BASEADDR_MASK; 5168e75f744SArnaud Giersch ctxval |= ((count - 1) << MACEPAR_CONTEXT_DATALEN_SHIFT) & 5178e75f744SArnaud Giersch MACEPAR_CONTEXT_DATALEN_MASK; 5188e75f744SArnaud Giersch writeq(ctxval, ctxreg); 5198e75f744SArnaud Giersch parport_ip32_dma.next += count; 5208e75f744SArnaud Giersch parport_ip32_dma.left -= count; 5218e75f744SArnaud Giersch parport_ip32_dma.ctx ^= 1U; 5228e75f744SArnaud Giersch } 5238e75f744SArnaud Giersch /* If there is nothing more to send, disable IRQs to avoid to 5248e75f744SArnaud Giersch * face an IRQ storm which can lock the machine. Disable them 5258e75f744SArnaud Giersch * only once. */ 5268e75f744SArnaud Giersch if (parport_ip32_dma.left == 0 && parport_ip32_dma.irq_on) { 5278e75f744SArnaud Giersch pr_debug(PPIP32 "IRQ off (ctx)\n"); 5288e75f744SArnaud Giersch disable_irq_nosync(MACEISA_PAR_CTXA_IRQ); 5298e75f744SArnaud Giersch disable_irq_nosync(MACEISA_PAR_CTXB_IRQ); 5308e75f744SArnaud Giersch parport_ip32_dma.irq_on = 0; 5318e75f744SArnaud Giersch } 5328e75f744SArnaud Giersch spin_unlock_irqrestore(&parport_ip32_dma.lock, flags); 5338e75f744SArnaud Giersch } 5348e75f744SArnaud Giersch 5358e75f744SArnaud Giersch /** 5368e75f744SArnaud Giersch * parport_ip32_dma_interrupt - DMA interrupt handler 5378e75f744SArnaud Giersch * @irq: interrupt number 5388e75f744SArnaud Giersch * @dev_id: unused 5398e75f744SArnaud Giersch */ 5407d12e780SDavid Howells static irqreturn_t parport_ip32_dma_interrupt(int irq, void *dev_id) 5418e75f744SArnaud Giersch { 5428e75f744SArnaud Giersch if (parport_ip32_dma.left) 5438e75f744SArnaud Giersch pr_trace(NULL, "(%d): ctx=%d", irq, parport_ip32_dma.ctx); 5448e75f744SArnaud Giersch parport_ip32_dma_setup_context(MACEPAR_CONTEXT_DATA_BOUND); 5458e75f744SArnaud Giersch return IRQ_HANDLED; 5468e75f744SArnaud Giersch } 5478e75f744SArnaud Giersch 5488e75f744SArnaud Giersch #if DEBUG_PARPORT_IP32 5497d12e780SDavid Howells static irqreturn_t parport_ip32_merr_interrupt(int irq, void *dev_id) 5508e75f744SArnaud Giersch { 5518e75f744SArnaud Giersch pr_trace1(NULL, "(%d)", irq); 5528e75f744SArnaud Giersch return IRQ_HANDLED; 5538e75f744SArnaud Giersch } 5548e75f744SArnaud Giersch #endif 5558e75f744SArnaud Giersch 5568e75f744SArnaud Giersch /** 5578e75f744SArnaud Giersch * parport_ip32_dma_start - begins a DMA transfer 5584217efa3SChristoph Hellwig * @p: partport to work on 5598e75f744SArnaud Giersch * @dir: DMA direction: DMA_TO_DEVICE or DMA_FROM_DEVICE 5608e75f744SArnaud Giersch * @addr: pointer to data buffer 5618e75f744SArnaud Giersch * @count: buffer size 5628e75f744SArnaud Giersch * 5638e75f744SArnaud Giersch * Calls to parport_ip32_dma_start() and parport_ip32_dma_stop() must be 5648e75f744SArnaud Giersch * correctly balanced. 5658e75f744SArnaud Giersch */ 5664217efa3SChristoph Hellwig static int parport_ip32_dma_start(struct parport *p, 5674217efa3SChristoph Hellwig enum dma_data_direction dir, void *addr, size_t count) 5688e75f744SArnaud Giersch { 5698e75f744SArnaud Giersch unsigned int limit; 5708e75f744SArnaud Giersch u64 ctrl; 5718e75f744SArnaud Giersch 5728e75f744SArnaud Giersch pr_trace(NULL, "(%d, %lu)", dir, (unsigned long)count); 5738e75f744SArnaud Giersch 5748e75f744SArnaud Giersch /* FIXME - add support for DMA_FROM_DEVICE. In this case, buffer must 5758e75f744SArnaud Giersch * be 64 bytes aligned. */ 5768e75f744SArnaud Giersch BUG_ON(dir != DMA_TO_DEVICE); 5778e75f744SArnaud Giersch 5788e75f744SArnaud Giersch /* Reset DMA controller */ 5798e75f744SArnaud Giersch ctrl = MACEPAR_CTLSTAT_RESET; 5808e75f744SArnaud Giersch writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); 5818e75f744SArnaud Giersch 5828e75f744SArnaud Giersch /* DMA IRQs should normally be enabled */ 5838e75f744SArnaud Giersch if (!parport_ip32_dma.irq_on) { 5848e75f744SArnaud Giersch WARN_ON(1); 5858e75f744SArnaud Giersch enable_irq(MACEISA_PAR_CTXA_IRQ); 5868e75f744SArnaud Giersch enable_irq(MACEISA_PAR_CTXB_IRQ); 5878e75f744SArnaud Giersch parport_ip32_dma.irq_on = 1; 5888e75f744SArnaud Giersch } 5898e75f744SArnaud Giersch 5908e75f744SArnaud Giersch /* Prepare DMA pointers */ 5918e75f744SArnaud Giersch parport_ip32_dma.dir = dir; 5924217efa3SChristoph Hellwig parport_ip32_dma.buf = dma_map_single(&p->bus_dev, addr, count, dir); 5938e75f744SArnaud Giersch parport_ip32_dma.len = count; 5948e75f744SArnaud Giersch parport_ip32_dma.next = parport_ip32_dma.buf; 5958e75f744SArnaud Giersch parport_ip32_dma.left = parport_ip32_dma.len; 5968e75f744SArnaud Giersch parport_ip32_dma.ctx = 0; 5978e75f744SArnaud Giersch 5988e75f744SArnaud Giersch /* Setup DMA direction and first two contexts */ 5998e75f744SArnaud Giersch ctrl = (dir == DMA_TO_DEVICE) ? 0 : MACEPAR_CTLSTAT_DIRECTION; 6008e75f744SArnaud Giersch writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); 6018e75f744SArnaud Giersch /* Single transfer should not cross a 4K page boundary */ 6028e75f744SArnaud Giersch limit = MACEPAR_CONTEXT_DATA_BOUND - 6038e75f744SArnaud Giersch (parport_ip32_dma.next & (MACEPAR_CONTEXT_DATA_BOUND - 1)); 6048e75f744SArnaud Giersch parport_ip32_dma_setup_context(limit); 6058e75f744SArnaud Giersch parport_ip32_dma_setup_context(MACEPAR_CONTEXT_DATA_BOUND); 6068e75f744SArnaud Giersch 6078e75f744SArnaud Giersch /* Real start of DMA transfer */ 6088e75f744SArnaud Giersch ctrl |= MACEPAR_CTLSTAT_ENABLE; 6098e75f744SArnaud Giersch writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); 6108e75f744SArnaud Giersch 6118e75f744SArnaud Giersch return 0; 6128e75f744SArnaud Giersch } 6138e75f744SArnaud Giersch 6148e75f744SArnaud Giersch /** 6158e75f744SArnaud Giersch * parport_ip32_dma_stop - ends a running DMA transfer 6164217efa3SChristoph Hellwig * @p: partport to work on 6178e75f744SArnaud Giersch * 6188e75f744SArnaud Giersch * Calls to parport_ip32_dma_start() and parport_ip32_dma_stop() must be 6198e75f744SArnaud Giersch * correctly balanced. 6208e75f744SArnaud Giersch */ 6214217efa3SChristoph Hellwig static void parport_ip32_dma_stop(struct parport *p) 6228e75f744SArnaud Giersch { 6238e75f744SArnaud Giersch u64 ctx_a; 6248e75f744SArnaud Giersch u64 ctx_b; 6258e75f744SArnaud Giersch u64 ctrl; 6268e75f744SArnaud Giersch u64 diag; 6278e75f744SArnaud Giersch size_t res[2]; /* {[0] = res_a, [1] = res_b} */ 6288e75f744SArnaud Giersch 6298e75f744SArnaud Giersch pr_trace(NULL, "()"); 6308e75f744SArnaud Giersch 6318e75f744SArnaud Giersch /* Disable IRQs */ 6328e75f744SArnaud Giersch spin_lock_irq(&parport_ip32_dma.lock); 6338e75f744SArnaud Giersch if (parport_ip32_dma.irq_on) { 6348e75f744SArnaud Giersch pr_debug(PPIP32 "IRQ off (stop)\n"); 6358e75f744SArnaud Giersch disable_irq_nosync(MACEISA_PAR_CTXA_IRQ); 6368e75f744SArnaud Giersch disable_irq_nosync(MACEISA_PAR_CTXB_IRQ); 6378e75f744SArnaud Giersch parport_ip32_dma.irq_on = 0; 6388e75f744SArnaud Giersch } 6398e75f744SArnaud Giersch spin_unlock_irq(&parport_ip32_dma.lock); 6408e75f744SArnaud Giersch /* Force IRQ synchronization, even if the IRQs were disabled 6418e75f744SArnaud Giersch * elsewhere. */ 6428e75f744SArnaud Giersch synchronize_irq(MACEISA_PAR_CTXA_IRQ); 6438e75f744SArnaud Giersch synchronize_irq(MACEISA_PAR_CTXB_IRQ); 6448e75f744SArnaud Giersch 6458e75f744SArnaud Giersch /* Stop DMA transfer */ 6468e75f744SArnaud Giersch ctrl = readq(&mace->perif.ctrl.parport.cntlstat); 6478e75f744SArnaud Giersch ctrl &= ~MACEPAR_CTLSTAT_ENABLE; 6488e75f744SArnaud Giersch writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); 6498e75f744SArnaud Giersch 6508e75f744SArnaud Giersch /* Adjust residue (parport_ip32_dma.left) */ 6518e75f744SArnaud Giersch ctx_a = readq(&mace->perif.ctrl.parport.context_a); 6528e75f744SArnaud Giersch ctx_b = readq(&mace->perif.ctrl.parport.context_b); 6538e75f744SArnaud Giersch ctrl = readq(&mace->perif.ctrl.parport.cntlstat); 6548e75f744SArnaud Giersch diag = readq(&mace->perif.ctrl.parport.diagnostic); 6558e75f744SArnaud Giersch res[0] = (ctrl & MACEPAR_CTLSTAT_CTXA_VALID) ? 6568e75f744SArnaud Giersch 1 + ((ctx_a & MACEPAR_CONTEXT_DATALEN_MASK) >> 6578e75f744SArnaud Giersch MACEPAR_CONTEXT_DATALEN_SHIFT) : 6588e75f744SArnaud Giersch 0; 6598e75f744SArnaud Giersch res[1] = (ctrl & MACEPAR_CTLSTAT_CTXB_VALID) ? 6608e75f744SArnaud Giersch 1 + ((ctx_b & MACEPAR_CONTEXT_DATALEN_MASK) >> 6618e75f744SArnaud Giersch MACEPAR_CONTEXT_DATALEN_SHIFT) : 6628e75f744SArnaud Giersch 0; 6638e75f744SArnaud Giersch if (diag & MACEPAR_DIAG_DMACTIVE) 6648e75f744SArnaud Giersch res[(diag & MACEPAR_DIAG_CTXINUSE) != 0] = 6658e75f744SArnaud Giersch 1 + ((diag & MACEPAR_DIAG_CTRMASK) >> 6668e75f744SArnaud Giersch MACEPAR_DIAG_CTRSHIFT); 6678e75f744SArnaud Giersch parport_ip32_dma.left += res[0] + res[1]; 6688e75f744SArnaud Giersch 6698e75f744SArnaud Giersch /* Reset DMA controller, and re-enable IRQs */ 6708e75f744SArnaud Giersch ctrl = MACEPAR_CTLSTAT_RESET; 6718e75f744SArnaud Giersch writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); 6728e75f744SArnaud Giersch pr_debug(PPIP32 "IRQ on (stop)\n"); 6738e75f744SArnaud Giersch enable_irq(MACEISA_PAR_CTXA_IRQ); 6748e75f744SArnaud Giersch enable_irq(MACEISA_PAR_CTXB_IRQ); 6758e75f744SArnaud Giersch parport_ip32_dma.irq_on = 1; 6768e75f744SArnaud Giersch 6774217efa3SChristoph Hellwig dma_unmap_single(&p->bus_dev, parport_ip32_dma.buf, 6784217efa3SChristoph Hellwig parport_ip32_dma.len, parport_ip32_dma.dir); 6798e75f744SArnaud Giersch } 6808e75f744SArnaud Giersch 6818e75f744SArnaud Giersch /** 6828e75f744SArnaud Giersch * parport_ip32_dma_get_residue - get residue from last DMA transfer 6838e75f744SArnaud Giersch * 6848e75f744SArnaud Giersch * Returns the number of bytes remaining from last DMA transfer. 6858e75f744SArnaud Giersch */ 6868e75f744SArnaud Giersch static inline size_t parport_ip32_dma_get_residue(void) 6878e75f744SArnaud Giersch { 6888e75f744SArnaud Giersch return parport_ip32_dma.left; 6898e75f744SArnaud Giersch } 6908e75f744SArnaud Giersch 6918e75f744SArnaud Giersch /** 6928e75f744SArnaud Giersch * parport_ip32_dma_register - initialize DMA engine 6938e75f744SArnaud Giersch * 6948e75f744SArnaud Giersch * Returns zero for success. 6958e75f744SArnaud Giersch */ 6968e75f744SArnaud Giersch static int parport_ip32_dma_register(void) 6978e75f744SArnaud Giersch { 6988e75f744SArnaud Giersch int err; 6998e75f744SArnaud Giersch 7008e75f744SArnaud Giersch spin_lock_init(&parport_ip32_dma.lock); 7018e75f744SArnaud Giersch parport_ip32_dma.irq_on = 1; 7028e75f744SArnaud Giersch 7038e75f744SArnaud Giersch /* Reset DMA controller */ 7048e75f744SArnaud Giersch writeq(MACEPAR_CTLSTAT_RESET, &mace->perif.ctrl.parport.cntlstat); 7058e75f744SArnaud Giersch 7068e75f744SArnaud Giersch /* Request IRQs */ 7078e75f744SArnaud Giersch err = request_irq(MACEISA_PAR_CTXA_IRQ, parport_ip32_dma_interrupt, 7088e75f744SArnaud Giersch 0, "parport_ip32", NULL); 7098e75f744SArnaud Giersch if (err) 7108e75f744SArnaud Giersch goto fail_a; 7118e75f744SArnaud Giersch err = request_irq(MACEISA_PAR_CTXB_IRQ, parport_ip32_dma_interrupt, 7128e75f744SArnaud Giersch 0, "parport_ip32", NULL); 7138e75f744SArnaud Giersch if (err) 7148e75f744SArnaud Giersch goto fail_b; 7158e75f744SArnaud Giersch #if DEBUG_PARPORT_IP32 7168e75f744SArnaud Giersch /* FIXME - what is this IRQ for? */ 7178e75f744SArnaud Giersch err = request_irq(MACEISA_PAR_MERR_IRQ, parport_ip32_merr_interrupt, 7188e75f744SArnaud Giersch 0, "parport_ip32", NULL); 7198e75f744SArnaud Giersch if (err) 7208e75f744SArnaud Giersch goto fail_merr; 7218e75f744SArnaud Giersch #endif 7228e75f744SArnaud Giersch return 0; 7238e75f744SArnaud Giersch 7248e75f744SArnaud Giersch #if DEBUG_PARPORT_IP32 7258e75f744SArnaud Giersch fail_merr: 7268e75f744SArnaud Giersch free_irq(MACEISA_PAR_CTXB_IRQ, NULL); 7278e75f744SArnaud Giersch #endif 7288e75f744SArnaud Giersch fail_b: 7298e75f744SArnaud Giersch free_irq(MACEISA_PAR_CTXA_IRQ, NULL); 7308e75f744SArnaud Giersch fail_a: 7318e75f744SArnaud Giersch return err; 7328e75f744SArnaud Giersch } 7338e75f744SArnaud Giersch 7348e75f744SArnaud Giersch /** 7358e75f744SArnaud Giersch * parport_ip32_dma_unregister - release and free resources for DMA engine 7368e75f744SArnaud Giersch */ 7378e75f744SArnaud Giersch static void parport_ip32_dma_unregister(void) 7388e75f744SArnaud Giersch { 7398e75f744SArnaud Giersch #if DEBUG_PARPORT_IP32 7408e75f744SArnaud Giersch free_irq(MACEISA_PAR_MERR_IRQ, NULL); 7418e75f744SArnaud Giersch #endif 7428e75f744SArnaud Giersch free_irq(MACEISA_PAR_CTXB_IRQ, NULL); 7438e75f744SArnaud Giersch free_irq(MACEISA_PAR_CTXA_IRQ, NULL); 7448e75f744SArnaud Giersch } 7458e75f744SArnaud Giersch 7468e75f744SArnaud Giersch /*--- Interrupt handlers and associates --------------------------------*/ 7478e75f744SArnaud Giersch 7488e75f744SArnaud Giersch /** 7498e75f744SArnaud Giersch * parport_ip32_wakeup - wakes up code waiting for an interrupt 7508e75f744SArnaud Giersch * @p: pointer to &struct parport 7518e75f744SArnaud Giersch */ 7528e75f744SArnaud Giersch static inline void parport_ip32_wakeup(struct parport *p) 7538e75f744SArnaud Giersch { 7548e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 7558e75f744SArnaud Giersch complete(&priv->irq_complete); 7568e75f744SArnaud Giersch } 7578e75f744SArnaud Giersch 7588e75f744SArnaud Giersch /** 7598e75f744SArnaud Giersch * parport_ip32_interrupt - interrupt handler 7608e75f744SArnaud Giersch * @irq: interrupt number 7618e75f744SArnaud Giersch * @dev_id: pointer to &struct parport 7628e75f744SArnaud Giersch * 7638e75f744SArnaud Giersch * Caught interrupts are forwarded to the upper parport layer if IRQ_mode is 7648e75f744SArnaud Giersch * %PARPORT_IP32_IRQ_FWD. 7658e75f744SArnaud Giersch */ 7667d12e780SDavid Howells static irqreturn_t parport_ip32_interrupt(int irq, void *dev_id) 7678e75f744SArnaud Giersch { 7688e75f744SArnaud Giersch struct parport * const p = dev_id; 7698e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 7708e75f744SArnaud Giersch enum parport_ip32_irq_mode irq_mode = priv->irq_mode; 7713f2e40dfSJeff Garzik 7728e75f744SArnaud Giersch switch (irq_mode) { 7738e75f744SArnaud Giersch case PARPORT_IP32_IRQ_FWD: 7743f2e40dfSJeff Garzik return parport_irq_handler(irq, dev_id); 7753f2e40dfSJeff Garzik 7768e75f744SArnaud Giersch case PARPORT_IP32_IRQ_HERE: 7778e75f744SArnaud Giersch parport_ip32_wakeup(p); 7788e75f744SArnaud Giersch break; 7798e75f744SArnaud Giersch } 7803f2e40dfSJeff Garzik 7818e75f744SArnaud Giersch return IRQ_HANDLED; 7828e75f744SArnaud Giersch } 7838e75f744SArnaud Giersch 7848e75f744SArnaud Giersch /*--- Some utility function to manipulate ECR register -----------------*/ 7858e75f744SArnaud Giersch 7868e75f744SArnaud Giersch /** 7878e75f744SArnaud Giersch * parport_ip32_read_econtrol - read contents of the ECR register 7888e75f744SArnaud Giersch * @p: pointer to &struct parport 7898e75f744SArnaud Giersch */ 7908e75f744SArnaud Giersch static inline unsigned int parport_ip32_read_econtrol(struct parport *p) 7918e75f744SArnaud Giersch { 7928e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 7938e75f744SArnaud Giersch return readb(priv->regs.ecr); 7948e75f744SArnaud Giersch } 7958e75f744SArnaud Giersch 7968e75f744SArnaud Giersch /** 7978e75f744SArnaud Giersch * parport_ip32_write_econtrol - write new contents to the ECR register 7988e75f744SArnaud Giersch * @p: pointer to &struct parport 7998e75f744SArnaud Giersch * @c: new value to write 8008e75f744SArnaud Giersch */ 8018e75f744SArnaud Giersch static inline void parport_ip32_write_econtrol(struct parport *p, 8028e75f744SArnaud Giersch unsigned int c) 8038e75f744SArnaud Giersch { 8048e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 8058e75f744SArnaud Giersch writeb(c, priv->regs.ecr); 8068e75f744SArnaud Giersch } 8078e75f744SArnaud Giersch 8088e75f744SArnaud Giersch /** 8098e75f744SArnaud Giersch * parport_ip32_frob_econtrol - change bits from the ECR register 8108e75f744SArnaud Giersch * @p: pointer to &struct parport 8118e75f744SArnaud Giersch * @mask: bit mask of bits to change 8128e75f744SArnaud Giersch * @val: new value for changed bits 8138e75f744SArnaud Giersch * 8148e75f744SArnaud Giersch * Read from the ECR, mask out the bits in @mask, exclusive-or with the bits 8158e75f744SArnaud Giersch * in @val, and write the result to the ECR. 8168e75f744SArnaud Giersch */ 8178e75f744SArnaud Giersch static inline void parport_ip32_frob_econtrol(struct parport *p, 8188e75f744SArnaud Giersch unsigned int mask, 8198e75f744SArnaud Giersch unsigned int val) 8208e75f744SArnaud Giersch { 8218e75f744SArnaud Giersch unsigned int c; 8228e75f744SArnaud Giersch c = (parport_ip32_read_econtrol(p) & ~mask) ^ val; 8238e75f744SArnaud Giersch parport_ip32_write_econtrol(p, c); 8248e75f744SArnaud Giersch } 8258e75f744SArnaud Giersch 8268e75f744SArnaud Giersch /** 8278e75f744SArnaud Giersch * parport_ip32_set_mode - change mode of ECP port 8288e75f744SArnaud Giersch * @p: pointer to &struct parport 8298e75f744SArnaud Giersch * @mode: new mode to write in ECR 8308e75f744SArnaud Giersch * 8318e75f744SArnaud Giersch * ECR is reset in a sane state (interrupts and DMA disabled), and placed in 8328e75f744SArnaud Giersch * mode @mode. Go through PS2 mode if needed. 8338e75f744SArnaud Giersch */ 8348e75f744SArnaud Giersch static void parport_ip32_set_mode(struct parport *p, unsigned int mode) 8358e75f744SArnaud Giersch { 8368e75f744SArnaud Giersch unsigned int omode; 8378e75f744SArnaud Giersch 8388e75f744SArnaud Giersch mode &= ECR_MODE_MASK; 8398e75f744SArnaud Giersch omode = parport_ip32_read_econtrol(p) & ECR_MODE_MASK; 8408e75f744SArnaud Giersch 8418e75f744SArnaud Giersch if (!(mode == ECR_MODE_SPP || mode == ECR_MODE_PS2 8428e75f744SArnaud Giersch || omode == ECR_MODE_SPP || omode == ECR_MODE_PS2)) { 8438e75f744SArnaud Giersch /* We have to go through PS2 mode */ 8448e75f744SArnaud Giersch unsigned int ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR; 8458e75f744SArnaud Giersch parport_ip32_write_econtrol(p, ecr); 8468e75f744SArnaud Giersch } 8478e75f744SArnaud Giersch parport_ip32_write_econtrol(p, mode | ECR_nERRINTR | ECR_SERVINTR); 8488e75f744SArnaud Giersch } 8498e75f744SArnaud Giersch 8508e75f744SArnaud Giersch /*--- Basic functions needed for parport -------------------------------*/ 8518e75f744SArnaud Giersch 8528e75f744SArnaud Giersch /** 8538e75f744SArnaud Giersch * parport_ip32_read_data - return current contents of the DATA register 8548e75f744SArnaud Giersch * @p: pointer to &struct parport 8558e75f744SArnaud Giersch */ 8568e75f744SArnaud Giersch static inline unsigned char parport_ip32_read_data(struct parport *p) 8578e75f744SArnaud Giersch { 8588e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 8598e75f744SArnaud Giersch return readb(priv->regs.data); 8608e75f744SArnaud Giersch } 8618e75f744SArnaud Giersch 8628e75f744SArnaud Giersch /** 8638e75f744SArnaud Giersch * parport_ip32_write_data - set new contents for the DATA register 8648e75f744SArnaud Giersch * @p: pointer to &struct parport 8658e75f744SArnaud Giersch * @d: new value to write 8668e75f744SArnaud Giersch */ 8678e75f744SArnaud Giersch static inline void parport_ip32_write_data(struct parport *p, unsigned char d) 8688e75f744SArnaud Giersch { 8698e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 8708e75f744SArnaud Giersch writeb(d, priv->regs.data); 8718e75f744SArnaud Giersch } 8728e75f744SArnaud Giersch 8738e75f744SArnaud Giersch /** 8748e75f744SArnaud Giersch * parport_ip32_read_status - return current contents of the DSR register 8758e75f744SArnaud Giersch * @p: pointer to &struct parport 8768e75f744SArnaud Giersch */ 8778e75f744SArnaud Giersch static inline unsigned char parport_ip32_read_status(struct parport *p) 8788e75f744SArnaud Giersch { 8798e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 8808e75f744SArnaud Giersch return readb(priv->regs.dsr); 8818e75f744SArnaud Giersch } 8828e75f744SArnaud Giersch 8838e75f744SArnaud Giersch /** 8848e75f744SArnaud Giersch * __parport_ip32_read_control - return cached contents of the DCR register 8858e75f744SArnaud Giersch * @p: pointer to &struct parport 8868e75f744SArnaud Giersch */ 8878e75f744SArnaud Giersch static inline unsigned int __parport_ip32_read_control(struct parport *p) 8888e75f744SArnaud Giersch { 8898e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 8908e75f744SArnaud Giersch return priv->dcr_cache; /* use soft copy */ 8918e75f744SArnaud Giersch } 8928e75f744SArnaud Giersch 8938e75f744SArnaud Giersch /** 8948e75f744SArnaud Giersch * __parport_ip32_write_control - set new contents for the DCR register 8958e75f744SArnaud Giersch * @p: pointer to &struct parport 8968e75f744SArnaud Giersch * @c: new value to write 8978e75f744SArnaud Giersch */ 8988e75f744SArnaud Giersch static inline void __parport_ip32_write_control(struct parport *p, 8998e75f744SArnaud Giersch unsigned int c) 9008e75f744SArnaud Giersch { 9018e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 9028e75f744SArnaud Giersch CHECK_EXTRA_BITS(p, c, priv->dcr_writable); 9038e75f744SArnaud Giersch c &= priv->dcr_writable; /* only writable bits */ 9048e75f744SArnaud Giersch writeb(c, priv->regs.dcr); 9058e75f744SArnaud Giersch priv->dcr_cache = c; /* update soft copy */ 9068e75f744SArnaud Giersch } 9078e75f744SArnaud Giersch 9088e75f744SArnaud Giersch /** 9098e75f744SArnaud Giersch * __parport_ip32_frob_control - change bits from the DCR register 9108e75f744SArnaud Giersch * @p: pointer to &struct parport 9118e75f744SArnaud Giersch * @mask: bit mask of bits to change 9128e75f744SArnaud Giersch * @val: new value for changed bits 9138e75f744SArnaud Giersch * 9148e75f744SArnaud Giersch * This is equivalent to read from the DCR, mask out the bits in @mask, 9158e75f744SArnaud Giersch * exclusive-or with the bits in @val, and write the result to the DCR. 9168e75f744SArnaud Giersch * Actually, the cached contents of the DCR is used. 9178e75f744SArnaud Giersch */ 9188e75f744SArnaud Giersch static inline void __parport_ip32_frob_control(struct parport *p, 9198e75f744SArnaud Giersch unsigned int mask, 9208e75f744SArnaud Giersch unsigned int val) 9218e75f744SArnaud Giersch { 9228e75f744SArnaud Giersch unsigned int c; 9238e75f744SArnaud Giersch c = (__parport_ip32_read_control(p) & ~mask) ^ val; 9248e75f744SArnaud Giersch __parport_ip32_write_control(p, c); 9258e75f744SArnaud Giersch } 9268e75f744SArnaud Giersch 9278e75f744SArnaud Giersch /** 9288e75f744SArnaud Giersch * parport_ip32_read_control - return cached contents of the DCR register 9298e75f744SArnaud Giersch * @p: pointer to &struct parport 9308e75f744SArnaud Giersch * 9318e75f744SArnaud Giersch * The return value is masked so as to only return the value of %DCR_STROBE, 9328e75f744SArnaud Giersch * %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT. 9338e75f744SArnaud Giersch */ 9348e75f744SArnaud Giersch static inline unsigned char parport_ip32_read_control(struct parport *p) 9358e75f744SArnaud Giersch { 9368e75f744SArnaud Giersch const unsigned int rm = 9378e75f744SArnaud Giersch DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT; 9388e75f744SArnaud Giersch return __parport_ip32_read_control(p) & rm; 9398e75f744SArnaud Giersch } 9408e75f744SArnaud Giersch 9418e75f744SArnaud Giersch /** 9428e75f744SArnaud Giersch * parport_ip32_write_control - set new contents for the DCR register 9438e75f744SArnaud Giersch * @p: pointer to &struct parport 9448e75f744SArnaud Giersch * @c: new value to write 9458e75f744SArnaud Giersch * 9468e75f744SArnaud Giersch * The value is masked so as to only change the value of %DCR_STROBE, 9478e75f744SArnaud Giersch * %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT. 9488e75f744SArnaud Giersch */ 9498e75f744SArnaud Giersch static inline void parport_ip32_write_control(struct parport *p, 9508e75f744SArnaud Giersch unsigned char c) 9518e75f744SArnaud Giersch { 9528e75f744SArnaud Giersch const unsigned int wm = 9538e75f744SArnaud Giersch DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT; 9548e75f744SArnaud Giersch CHECK_EXTRA_BITS(p, c, wm); 9558e75f744SArnaud Giersch __parport_ip32_frob_control(p, wm, c & wm); 9568e75f744SArnaud Giersch } 9578e75f744SArnaud Giersch 9588e75f744SArnaud Giersch /** 9598e75f744SArnaud Giersch * parport_ip32_frob_control - change bits from the DCR register 9608e75f744SArnaud Giersch * @p: pointer to &struct parport 9618e75f744SArnaud Giersch * @mask: bit mask of bits to change 9628e75f744SArnaud Giersch * @val: new value for changed bits 9638e75f744SArnaud Giersch * 9648e75f744SArnaud Giersch * This differs from __parport_ip32_frob_control() in that it only allows to 9658e75f744SArnaud Giersch * change the value of %DCR_STROBE, %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT. 9668e75f744SArnaud Giersch */ 9678e75f744SArnaud Giersch static inline unsigned char parport_ip32_frob_control(struct parport *p, 9688e75f744SArnaud Giersch unsigned char mask, 9698e75f744SArnaud Giersch unsigned char val) 9708e75f744SArnaud Giersch { 9718e75f744SArnaud Giersch const unsigned int wm = 9728e75f744SArnaud Giersch DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT; 9738e75f744SArnaud Giersch CHECK_EXTRA_BITS(p, mask, wm); 9748e75f744SArnaud Giersch CHECK_EXTRA_BITS(p, val, wm); 9758e75f744SArnaud Giersch __parport_ip32_frob_control(p, mask & wm, val & wm); 9768e75f744SArnaud Giersch return parport_ip32_read_control(p); 9778e75f744SArnaud Giersch } 9788e75f744SArnaud Giersch 9798e75f744SArnaud Giersch /** 9808e75f744SArnaud Giersch * parport_ip32_disable_irq - disable interrupts on the rising edge of nACK 9818e75f744SArnaud Giersch * @p: pointer to &struct parport 9828e75f744SArnaud Giersch */ 9838e75f744SArnaud Giersch static inline void parport_ip32_disable_irq(struct parport *p) 9848e75f744SArnaud Giersch { 9858e75f744SArnaud Giersch __parport_ip32_frob_control(p, DCR_IRQ, 0); 9868e75f744SArnaud Giersch } 9878e75f744SArnaud Giersch 9888e75f744SArnaud Giersch /** 9898e75f744SArnaud Giersch * parport_ip32_enable_irq - enable interrupts on the rising edge of nACK 9908e75f744SArnaud Giersch * @p: pointer to &struct parport 9918e75f744SArnaud Giersch */ 9928e75f744SArnaud Giersch static inline void parport_ip32_enable_irq(struct parport *p) 9938e75f744SArnaud Giersch { 9948e75f744SArnaud Giersch __parport_ip32_frob_control(p, DCR_IRQ, DCR_IRQ); 9958e75f744SArnaud Giersch } 9968e75f744SArnaud Giersch 9978e75f744SArnaud Giersch /** 9988e75f744SArnaud Giersch * parport_ip32_data_forward - enable host-to-peripheral communications 9998e75f744SArnaud Giersch * @p: pointer to &struct parport 10008e75f744SArnaud Giersch * 10018e75f744SArnaud Giersch * Enable the data line drivers, for 8-bit host-to-peripheral communications. 10028e75f744SArnaud Giersch */ 10038e75f744SArnaud Giersch static inline void parport_ip32_data_forward(struct parport *p) 10048e75f744SArnaud Giersch { 10058e75f744SArnaud Giersch __parport_ip32_frob_control(p, DCR_DIR, 0); 10068e75f744SArnaud Giersch } 10078e75f744SArnaud Giersch 10088e75f744SArnaud Giersch /** 10098e75f744SArnaud Giersch * parport_ip32_data_reverse - enable peripheral-to-host communications 10108e75f744SArnaud Giersch * @p: pointer to &struct parport 10118e75f744SArnaud Giersch * 10128e75f744SArnaud Giersch * Place the data bus in a high impedance state, if @p->modes has the 10138e75f744SArnaud Giersch * PARPORT_MODE_TRISTATE bit set. 10148e75f744SArnaud Giersch */ 10158e75f744SArnaud Giersch static inline void parport_ip32_data_reverse(struct parport *p) 10168e75f744SArnaud Giersch { 10178e75f744SArnaud Giersch __parport_ip32_frob_control(p, DCR_DIR, DCR_DIR); 10188e75f744SArnaud Giersch } 10198e75f744SArnaud Giersch 10208e75f744SArnaud Giersch /** 10218e75f744SArnaud Giersch * parport_ip32_init_state - for core parport code 10228e75f744SArnaud Giersch * @dev: pointer to &struct pardevice 10238e75f744SArnaud Giersch * @s: pointer to &struct parport_state to initialize 10248e75f744SArnaud Giersch */ 10258e75f744SArnaud Giersch static void parport_ip32_init_state(struct pardevice *dev, 10268e75f744SArnaud Giersch struct parport_state *s) 10278e75f744SArnaud Giersch { 10288e75f744SArnaud Giersch s->u.ip32.dcr = DCR_SELECT | DCR_nINIT; 10298e75f744SArnaud Giersch s->u.ip32.ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR; 10308e75f744SArnaud Giersch } 10318e75f744SArnaud Giersch 10328e75f744SArnaud Giersch /** 10338e75f744SArnaud Giersch * parport_ip32_save_state - for core parport code 10348e75f744SArnaud Giersch * @p: pointer to &struct parport 10358e75f744SArnaud Giersch * @s: pointer to &struct parport_state to save state to 10368e75f744SArnaud Giersch */ 10378e75f744SArnaud Giersch static void parport_ip32_save_state(struct parport *p, 10388e75f744SArnaud Giersch struct parport_state *s) 10398e75f744SArnaud Giersch { 10408e75f744SArnaud Giersch s->u.ip32.dcr = __parport_ip32_read_control(p); 10418e75f744SArnaud Giersch s->u.ip32.ecr = parport_ip32_read_econtrol(p); 10428e75f744SArnaud Giersch } 10438e75f744SArnaud Giersch 10448e75f744SArnaud Giersch /** 10458e75f744SArnaud Giersch * parport_ip32_restore_state - for core parport code 10468e75f744SArnaud Giersch * @p: pointer to &struct parport 10478e75f744SArnaud Giersch * @s: pointer to &struct parport_state to restore state from 10488e75f744SArnaud Giersch */ 10498e75f744SArnaud Giersch static void parport_ip32_restore_state(struct parport *p, 10508e75f744SArnaud Giersch struct parport_state *s) 10518e75f744SArnaud Giersch { 10528e75f744SArnaud Giersch parport_ip32_set_mode(p, s->u.ip32.ecr & ECR_MODE_MASK); 10538e75f744SArnaud Giersch parport_ip32_write_econtrol(p, s->u.ip32.ecr); 10548e75f744SArnaud Giersch __parport_ip32_write_control(p, s->u.ip32.dcr); 10558e75f744SArnaud Giersch } 10568e75f744SArnaud Giersch 10578e75f744SArnaud Giersch /*--- EPP mode functions -----------------------------------------------*/ 10588e75f744SArnaud Giersch 10598e75f744SArnaud Giersch /** 10608e75f744SArnaud Giersch * parport_ip32_clear_epp_timeout - clear Timeout bit in EPP mode 10618e75f744SArnaud Giersch * @p: pointer to &struct parport 10628e75f744SArnaud Giersch * 10638e75f744SArnaud Giersch * Returns 1 if the Timeout bit is clear, and 0 otherwise. 10648e75f744SArnaud Giersch */ 10658e75f744SArnaud Giersch static unsigned int parport_ip32_clear_epp_timeout(struct parport *p) 10668e75f744SArnaud Giersch { 10678e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 10688e75f744SArnaud Giersch unsigned int cleared; 10698e75f744SArnaud Giersch 10708e75f744SArnaud Giersch if (!(parport_ip32_read_status(p) & DSR_TIMEOUT)) 10718e75f744SArnaud Giersch cleared = 1; 10728e75f744SArnaud Giersch else { 10738e75f744SArnaud Giersch unsigned int r; 10748e75f744SArnaud Giersch /* To clear timeout some chips require double read */ 10758e75f744SArnaud Giersch parport_ip32_read_status(p); 10768e75f744SArnaud Giersch r = parport_ip32_read_status(p); 10778e75f744SArnaud Giersch /* Some reset by writing 1 */ 10788e75f744SArnaud Giersch writeb(r | DSR_TIMEOUT, priv->regs.dsr); 10798e75f744SArnaud Giersch /* Others by writing 0 */ 10808e75f744SArnaud Giersch writeb(r & ~DSR_TIMEOUT, priv->regs.dsr); 10818e75f744SArnaud Giersch 10828e75f744SArnaud Giersch r = parport_ip32_read_status(p); 10838e75f744SArnaud Giersch cleared = !(r & DSR_TIMEOUT); 10848e75f744SArnaud Giersch } 10858e75f744SArnaud Giersch 10868e75f744SArnaud Giersch pr_trace(p, "(): %s", cleared ? "cleared" : "failed"); 10878e75f744SArnaud Giersch return cleared; 10888e75f744SArnaud Giersch } 10898e75f744SArnaud Giersch 10908e75f744SArnaud Giersch /** 10918e75f744SArnaud Giersch * parport_ip32_epp_read - generic EPP read function 10928e75f744SArnaud Giersch * @eppreg: I/O register to read from 10938e75f744SArnaud Giersch * @p: pointer to &struct parport 10948e75f744SArnaud Giersch * @buf: buffer to store read data 10958e75f744SArnaud Giersch * @len: length of buffer @buf 10968e75f744SArnaud Giersch * @flags: may be PARPORT_EPP_FAST 10978e75f744SArnaud Giersch */ 10988e75f744SArnaud Giersch static size_t parport_ip32_epp_read(void __iomem *eppreg, 10998e75f744SArnaud Giersch struct parport *p, void *buf, 11008e75f744SArnaud Giersch size_t len, int flags) 11018e75f744SArnaud Giersch { 11028e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 11038e75f744SArnaud Giersch size_t got; 11048e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_EPP); 11058e75f744SArnaud Giersch parport_ip32_data_reverse(p); 11068e75f744SArnaud Giersch parport_ip32_write_control(p, DCR_nINIT); 11078e75f744SArnaud Giersch if ((flags & PARPORT_EPP_FAST) && (len > 1)) { 11088e75f744SArnaud Giersch readsb(eppreg, buf, len); 11098e75f744SArnaud Giersch if (readb(priv->regs.dsr) & DSR_TIMEOUT) { 11108e75f744SArnaud Giersch parport_ip32_clear_epp_timeout(p); 11118e75f744SArnaud Giersch return -EIO; 11128e75f744SArnaud Giersch } 11138e75f744SArnaud Giersch got = len; 11148e75f744SArnaud Giersch } else { 11158e75f744SArnaud Giersch u8 *bufp = buf; 11168e75f744SArnaud Giersch for (got = 0; got < len; got++) { 11178e75f744SArnaud Giersch *bufp++ = readb(eppreg); 11188e75f744SArnaud Giersch if (readb(priv->regs.dsr) & DSR_TIMEOUT) { 11198e75f744SArnaud Giersch parport_ip32_clear_epp_timeout(p); 11208e75f744SArnaud Giersch break; 11218e75f744SArnaud Giersch } 11228e75f744SArnaud Giersch } 11238e75f744SArnaud Giersch } 11248e75f744SArnaud Giersch parport_ip32_data_forward(p); 11258e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 11268e75f744SArnaud Giersch return got; 11278e75f744SArnaud Giersch } 11288e75f744SArnaud Giersch 11298e75f744SArnaud Giersch /** 11308e75f744SArnaud Giersch * parport_ip32_epp_write - generic EPP write function 11318e75f744SArnaud Giersch * @eppreg: I/O register to write to 11328e75f744SArnaud Giersch * @p: pointer to &struct parport 11338e75f744SArnaud Giersch * @buf: buffer of data to write 11348e75f744SArnaud Giersch * @len: length of buffer @buf 11358e75f744SArnaud Giersch * @flags: may be PARPORT_EPP_FAST 11368e75f744SArnaud Giersch */ 11378e75f744SArnaud Giersch static size_t parport_ip32_epp_write(void __iomem *eppreg, 11388e75f744SArnaud Giersch struct parport *p, const void *buf, 11398e75f744SArnaud Giersch size_t len, int flags) 11408e75f744SArnaud Giersch { 11418e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 11428e75f744SArnaud Giersch size_t written; 11438e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_EPP); 11448e75f744SArnaud Giersch parport_ip32_data_forward(p); 11458e75f744SArnaud Giersch parport_ip32_write_control(p, DCR_nINIT); 11468e75f744SArnaud Giersch if ((flags & PARPORT_EPP_FAST) && (len > 1)) { 11478e75f744SArnaud Giersch writesb(eppreg, buf, len); 11488e75f744SArnaud Giersch if (readb(priv->regs.dsr) & DSR_TIMEOUT) { 11498e75f744SArnaud Giersch parport_ip32_clear_epp_timeout(p); 11508e75f744SArnaud Giersch return -EIO; 11518e75f744SArnaud Giersch } 11528e75f744SArnaud Giersch written = len; 11538e75f744SArnaud Giersch } else { 11548e75f744SArnaud Giersch const u8 *bufp = buf; 11558e75f744SArnaud Giersch for (written = 0; written < len; written++) { 11568e75f744SArnaud Giersch writeb(*bufp++, eppreg); 11578e75f744SArnaud Giersch if (readb(priv->regs.dsr) & DSR_TIMEOUT) { 11588e75f744SArnaud Giersch parport_ip32_clear_epp_timeout(p); 11598e75f744SArnaud Giersch break; 11608e75f744SArnaud Giersch } 11618e75f744SArnaud Giersch } 11628e75f744SArnaud Giersch } 11638e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 11648e75f744SArnaud Giersch return written; 11658e75f744SArnaud Giersch } 11668e75f744SArnaud Giersch 11678e75f744SArnaud Giersch /** 11688e75f744SArnaud Giersch * parport_ip32_epp_read_data - read a block of data in EPP mode 11698e75f744SArnaud Giersch * @p: pointer to &struct parport 11708e75f744SArnaud Giersch * @buf: buffer to store read data 11718e75f744SArnaud Giersch * @len: length of buffer @buf 11728e75f744SArnaud Giersch * @flags: may be PARPORT_EPP_FAST 11738e75f744SArnaud Giersch */ 11748e75f744SArnaud Giersch static size_t parport_ip32_epp_read_data(struct parport *p, void *buf, 11758e75f744SArnaud Giersch size_t len, int flags) 11768e75f744SArnaud Giersch { 11778e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 11788e75f744SArnaud Giersch return parport_ip32_epp_read(priv->regs.eppData0, p, buf, len, flags); 11798e75f744SArnaud Giersch } 11808e75f744SArnaud Giersch 11818e75f744SArnaud Giersch /** 11828e75f744SArnaud Giersch * parport_ip32_epp_write_data - write a block of data in EPP mode 11838e75f744SArnaud Giersch * @p: pointer to &struct parport 11848e75f744SArnaud Giersch * @buf: buffer of data to write 11858e75f744SArnaud Giersch * @len: length of buffer @buf 11868e75f744SArnaud Giersch * @flags: may be PARPORT_EPP_FAST 11878e75f744SArnaud Giersch */ 11888e75f744SArnaud Giersch static size_t parport_ip32_epp_write_data(struct parport *p, const void *buf, 11898e75f744SArnaud Giersch size_t len, int flags) 11908e75f744SArnaud Giersch { 11918e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 11928e75f744SArnaud Giersch return parport_ip32_epp_write(priv->regs.eppData0, p, buf, len, flags); 11938e75f744SArnaud Giersch } 11948e75f744SArnaud Giersch 11958e75f744SArnaud Giersch /** 11968e75f744SArnaud Giersch * parport_ip32_epp_read_addr - read a block of addresses in EPP mode 11978e75f744SArnaud Giersch * @p: pointer to &struct parport 11988e75f744SArnaud Giersch * @buf: buffer to store read data 11998e75f744SArnaud Giersch * @len: length of buffer @buf 12008e75f744SArnaud Giersch * @flags: may be PARPORT_EPP_FAST 12018e75f744SArnaud Giersch */ 12028e75f744SArnaud Giersch static size_t parport_ip32_epp_read_addr(struct parport *p, void *buf, 12038e75f744SArnaud Giersch size_t len, int flags) 12048e75f744SArnaud Giersch { 12058e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 12068e75f744SArnaud Giersch return parport_ip32_epp_read(priv->regs.eppAddr, p, buf, len, flags); 12078e75f744SArnaud Giersch } 12088e75f744SArnaud Giersch 12098e75f744SArnaud Giersch /** 12108e75f744SArnaud Giersch * parport_ip32_epp_write_addr - write a block of addresses in EPP mode 12118e75f744SArnaud Giersch * @p: pointer to &struct parport 12128e75f744SArnaud Giersch * @buf: buffer of data to write 12138e75f744SArnaud Giersch * @len: length of buffer @buf 12148e75f744SArnaud Giersch * @flags: may be PARPORT_EPP_FAST 12158e75f744SArnaud Giersch */ 12168e75f744SArnaud Giersch static size_t parport_ip32_epp_write_addr(struct parport *p, const void *buf, 12178e75f744SArnaud Giersch size_t len, int flags) 12188e75f744SArnaud Giersch { 12198e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 12208e75f744SArnaud Giersch return parport_ip32_epp_write(priv->regs.eppAddr, p, buf, len, flags); 12218e75f744SArnaud Giersch } 12228e75f744SArnaud Giersch 12238e75f744SArnaud Giersch /*--- ECP mode functions (FIFO) ----------------------------------------*/ 12248e75f744SArnaud Giersch 12258e75f744SArnaud Giersch /** 12268e75f744SArnaud Giersch * parport_ip32_fifo_wait_break - check if the waiting function should return 12278e75f744SArnaud Giersch * @p: pointer to &struct parport 12288e75f744SArnaud Giersch * @expire: timeout expiring date, in jiffies 12298e75f744SArnaud Giersch * 12308e75f744SArnaud Giersch * parport_ip32_fifo_wait_break() checks if the waiting function should return 12318e75f744SArnaud Giersch * immediately or not. The break conditions are: 12328e75f744SArnaud Giersch * - expired timeout; 12338e75f744SArnaud Giersch * - a pending signal; 12348e75f744SArnaud Giersch * - nFault asserted low. 12358e75f744SArnaud Giersch * This function also calls cond_resched(). 12368e75f744SArnaud Giersch */ 12378e75f744SArnaud Giersch static unsigned int parport_ip32_fifo_wait_break(struct parport *p, 12388e75f744SArnaud Giersch unsigned long expire) 12398e75f744SArnaud Giersch { 12408e75f744SArnaud Giersch cond_resched(); 12418e75f744SArnaud Giersch if (time_after(jiffies, expire)) { 12428e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: FIFO write timed out\n", p->name); 12438e75f744SArnaud Giersch return 1; 12448e75f744SArnaud Giersch } 12458e75f744SArnaud Giersch if (signal_pending(current)) { 12468e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: Signal pending\n", p->name); 12478e75f744SArnaud Giersch return 1; 12488e75f744SArnaud Giersch } 12498e75f744SArnaud Giersch if (!(parport_ip32_read_status(p) & DSR_nFAULT)) { 12508e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: nFault asserted low\n", p->name); 12518e75f744SArnaud Giersch return 1; 12528e75f744SArnaud Giersch } 12538e75f744SArnaud Giersch return 0; 12548e75f744SArnaud Giersch } 12558e75f744SArnaud Giersch 12568e75f744SArnaud Giersch /** 12578e75f744SArnaud Giersch * parport_ip32_fwp_wait_polling - wait for FIFO to empty (polling) 12588e75f744SArnaud Giersch * @p: pointer to &struct parport 12598e75f744SArnaud Giersch * 12608e75f744SArnaud Giersch * Returns the number of bytes that can safely be written in the FIFO. A 12618e75f744SArnaud Giersch * return value of zero means that the calling function should terminate as 12628e75f744SArnaud Giersch * fast as possible. 12638e75f744SArnaud Giersch */ 12648e75f744SArnaud Giersch static unsigned int parport_ip32_fwp_wait_polling(struct parport *p) 12658e75f744SArnaud Giersch { 12668e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 12678e75f744SArnaud Giersch struct parport * const physport = p->physport; 12688e75f744SArnaud Giersch unsigned long expire; 12698e75f744SArnaud Giersch unsigned int count; 12708e75f744SArnaud Giersch unsigned int ecr; 12718e75f744SArnaud Giersch 12728e75f744SArnaud Giersch expire = jiffies + physport->cad->timeout; 12738e75f744SArnaud Giersch count = 0; 12748e75f744SArnaud Giersch while (1) { 12758e75f744SArnaud Giersch if (parport_ip32_fifo_wait_break(p, expire)) 12768e75f744SArnaud Giersch break; 12778e75f744SArnaud Giersch 12788e75f744SArnaud Giersch /* Check FIFO state. We do nothing when the FIFO is nor full, 12798e75f744SArnaud Giersch * nor empty. It appears that the FIFO full bit is not always 12808e75f744SArnaud Giersch * reliable, the FIFO state is sometimes wrongly reported, and 12818e75f744SArnaud Giersch * the chip gets confused if we give it another byte. */ 12828e75f744SArnaud Giersch ecr = parport_ip32_read_econtrol(p); 12838e75f744SArnaud Giersch if (ecr & ECR_F_EMPTY) { 12848e75f744SArnaud Giersch /* FIFO is empty, fill it up */ 12858e75f744SArnaud Giersch count = priv->fifo_depth; 12868e75f744SArnaud Giersch break; 12878e75f744SArnaud Giersch } 12888e75f744SArnaud Giersch 12898e75f744SArnaud Giersch /* Wait a moment... */ 12908e75f744SArnaud Giersch udelay(FIFO_POLLING_INTERVAL); 12918e75f744SArnaud Giersch } /* while (1) */ 12928e75f744SArnaud Giersch 12938e75f744SArnaud Giersch return count; 12948e75f744SArnaud Giersch } 12958e75f744SArnaud Giersch 12968e75f744SArnaud Giersch /** 12978e75f744SArnaud Giersch * parport_ip32_fwp_wait_interrupt - wait for FIFO to empty (interrupt-driven) 12988e75f744SArnaud Giersch * @p: pointer to &struct parport 12998e75f744SArnaud Giersch * 13008e75f744SArnaud Giersch * Returns the number of bytes that can safely be written in the FIFO. A 13018e75f744SArnaud Giersch * return value of zero means that the calling function should terminate as 13028e75f744SArnaud Giersch * fast as possible. 13038e75f744SArnaud Giersch */ 13048e75f744SArnaud Giersch static unsigned int parport_ip32_fwp_wait_interrupt(struct parport *p) 13058e75f744SArnaud Giersch { 13068e75f744SArnaud Giersch static unsigned int lost_interrupt = 0; 13078e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 13088e75f744SArnaud Giersch struct parport * const physport = p->physport; 13098e75f744SArnaud Giersch unsigned long nfault_timeout; 13108e75f744SArnaud Giersch unsigned long expire; 13118e75f744SArnaud Giersch unsigned int count; 13128e75f744SArnaud Giersch unsigned int ecr; 13138e75f744SArnaud Giersch 13148e75f744SArnaud Giersch nfault_timeout = min((unsigned long)physport->cad->timeout, 13158e75f744SArnaud Giersch msecs_to_jiffies(FIFO_NFAULT_TIMEOUT)); 13168e75f744SArnaud Giersch expire = jiffies + physport->cad->timeout; 13178e75f744SArnaud Giersch count = 0; 13188e75f744SArnaud Giersch while (1) { 13198e75f744SArnaud Giersch if (parport_ip32_fifo_wait_break(p, expire)) 13208e75f744SArnaud Giersch break; 13218e75f744SArnaud Giersch 13228e75f744SArnaud Giersch /* Initialize mutex used to take interrupts into account */ 132316735d02SWolfram Sang reinit_completion(&priv->irq_complete); 13248e75f744SArnaud Giersch 13258e75f744SArnaud Giersch /* Enable serviceIntr */ 13268e75f744SArnaud Giersch parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0); 13278e75f744SArnaud Giersch 13288e75f744SArnaud Giersch /* Enabling serviceIntr while the FIFO is empty does not 13298e75f744SArnaud Giersch * always generate an interrupt, so check for emptiness 13308e75f744SArnaud Giersch * now. */ 13318e75f744SArnaud Giersch ecr = parport_ip32_read_econtrol(p); 13328e75f744SArnaud Giersch if (!(ecr & ECR_F_EMPTY)) { 13338e75f744SArnaud Giersch /* FIFO is not empty: wait for an interrupt or a 13348e75f744SArnaud Giersch * timeout to occur */ 13358e75f744SArnaud Giersch wait_for_completion_interruptible_timeout( 13368e75f744SArnaud Giersch &priv->irq_complete, nfault_timeout); 13378e75f744SArnaud Giersch ecr = parport_ip32_read_econtrol(p); 13388e75f744SArnaud Giersch if ((ecr & ECR_F_EMPTY) && !(ecr & ECR_SERVINTR) 13398e75f744SArnaud Giersch && !lost_interrupt) { 13408e75f744SArnaud Giersch printk(KERN_WARNING PPIP32 13418e75f744SArnaud Giersch "%s: lost interrupt in %s\n", 13428e75f744SArnaud Giersch p->name, __func__); 13438e75f744SArnaud Giersch lost_interrupt = 1; 13448e75f744SArnaud Giersch } 13458e75f744SArnaud Giersch } 13468e75f744SArnaud Giersch 13478e75f744SArnaud Giersch /* Disable serviceIntr */ 13488e75f744SArnaud Giersch parport_ip32_frob_econtrol(p, ECR_SERVINTR, ECR_SERVINTR); 13498e75f744SArnaud Giersch 13508e75f744SArnaud Giersch /* Check FIFO state */ 13518e75f744SArnaud Giersch if (ecr & ECR_F_EMPTY) { 13528e75f744SArnaud Giersch /* FIFO is empty, fill it up */ 13538e75f744SArnaud Giersch count = priv->fifo_depth; 13548e75f744SArnaud Giersch break; 13558e75f744SArnaud Giersch } else if (ecr & ECR_SERVINTR) { 13568e75f744SArnaud Giersch /* FIFO is not empty, but we know that can safely push 13578e75f744SArnaud Giersch * writeIntrThreshold bytes into it */ 13588e75f744SArnaud Giersch count = priv->writeIntrThreshold; 13598e75f744SArnaud Giersch break; 13608e75f744SArnaud Giersch } 13618e75f744SArnaud Giersch /* FIFO is not empty, and we did not get any interrupt. 13628e75f744SArnaud Giersch * Either it's time to check for nFault, or a signal is 13638e75f744SArnaud Giersch * pending. This is verified in 13648e75f744SArnaud Giersch * parport_ip32_fifo_wait_break(), so we continue the loop. */ 13658e75f744SArnaud Giersch } /* while (1) */ 13668e75f744SArnaud Giersch 13678e75f744SArnaud Giersch return count; 13688e75f744SArnaud Giersch } 13698e75f744SArnaud Giersch 13708e75f744SArnaud Giersch /** 13718e75f744SArnaud Giersch * parport_ip32_fifo_write_block_pio - write a block of data (PIO mode) 13728e75f744SArnaud Giersch * @p: pointer to &struct parport 13738e75f744SArnaud Giersch * @buf: buffer of data to write 13748e75f744SArnaud Giersch * @len: length of buffer @buf 13758e75f744SArnaud Giersch * 13768e75f744SArnaud Giersch * Uses PIO to write the contents of the buffer @buf into the parallel port 13778e75f744SArnaud Giersch * FIFO. Returns the number of bytes that were actually written. It can work 13788e75f744SArnaud Giersch * with or without the help of interrupts. The parallel port must be 13798e75f744SArnaud Giersch * correctly initialized before calling parport_ip32_fifo_write_block_pio(). 13808e75f744SArnaud Giersch */ 13818e75f744SArnaud Giersch static size_t parport_ip32_fifo_write_block_pio(struct parport *p, 13828e75f744SArnaud Giersch const void *buf, size_t len) 13838e75f744SArnaud Giersch { 13848e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 13858e75f744SArnaud Giersch const u8 *bufp = buf; 13868e75f744SArnaud Giersch size_t left = len; 13878e75f744SArnaud Giersch 13888e75f744SArnaud Giersch priv->irq_mode = PARPORT_IP32_IRQ_HERE; 13898e75f744SArnaud Giersch 13908e75f744SArnaud Giersch while (left > 0) { 13918e75f744SArnaud Giersch unsigned int count; 13928e75f744SArnaud Giersch 13938e75f744SArnaud Giersch count = (p->irq == PARPORT_IRQ_NONE) ? 13948e75f744SArnaud Giersch parport_ip32_fwp_wait_polling(p) : 13958e75f744SArnaud Giersch parport_ip32_fwp_wait_interrupt(p); 13968e75f744SArnaud Giersch if (count == 0) 13978e75f744SArnaud Giersch break; /* Transmission should be stopped */ 13988e75f744SArnaud Giersch if (count > left) 13998e75f744SArnaud Giersch count = left; 14008e75f744SArnaud Giersch if (count == 1) { 14018e75f744SArnaud Giersch writeb(*bufp, priv->regs.fifo); 14028e75f744SArnaud Giersch bufp++, left--; 14038e75f744SArnaud Giersch } else { 14048e75f744SArnaud Giersch writesb(priv->regs.fifo, bufp, count); 14058e75f744SArnaud Giersch bufp += count, left -= count; 14068e75f744SArnaud Giersch } 14078e75f744SArnaud Giersch } 14088e75f744SArnaud Giersch 14098e75f744SArnaud Giersch priv->irq_mode = PARPORT_IP32_IRQ_FWD; 14108e75f744SArnaud Giersch 14118e75f744SArnaud Giersch return len - left; 14128e75f744SArnaud Giersch } 14138e75f744SArnaud Giersch 14148e75f744SArnaud Giersch /** 14158e75f744SArnaud Giersch * parport_ip32_fifo_write_block_dma - write a block of data (DMA mode) 14168e75f744SArnaud Giersch * @p: pointer to &struct parport 14178e75f744SArnaud Giersch * @buf: buffer of data to write 14188e75f744SArnaud Giersch * @len: length of buffer @buf 14198e75f744SArnaud Giersch * 14208e75f744SArnaud Giersch * Uses DMA to write the contents of the buffer @buf into the parallel port 14218e75f744SArnaud Giersch * FIFO. Returns the number of bytes that were actually written. The 14228e75f744SArnaud Giersch * parallel port must be correctly initialized before calling 14238e75f744SArnaud Giersch * parport_ip32_fifo_write_block_dma(). 14248e75f744SArnaud Giersch */ 14258e75f744SArnaud Giersch static size_t parport_ip32_fifo_write_block_dma(struct parport *p, 14268e75f744SArnaud Giersch const void *buf, size_t len) 14278e75f744SArnaud Giersch { 14288e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 14298e75f744SArnaud Giersch struct parport * const physport = p->physport; 14308e75f744SArnaud Giersch unsigned long nfault_timeout; 14318e75f744SArnaud Giersch unsigned long expire; 14328e75f744SArnaud Giersch size_t written; 14338e75f744SArnaud Giersch unsigned int ecr; 14348e75f744SArnaud Giersch 14358e75f744SArnaud Giersch priv->irq_mode = PARPORT_IP32_IRQ_HERE; 14368e75f744SArnaud Giersch 14374217efa3SChristoph Hellwig parport_ip32_dma_start(p, DMA_TO_DEVICE, (void *)buf, len); 143816735d02SWolfram Sang reinit_completion(&priv->irq_complete); 14398e75f744SArnaud Giersch parport_ip32_frob_econtrol(p, ECR_DMAEN | ECR_SERVINTR, ECR_DMAEN); 14408e75f744SArnaud Giersch 14418e75f744SArnaud Giersch nfault_timeout = min((unsigned long)physport->cad->timeout, 14428e75f744SArnaud Giersch msecs_to_jiffies(FIFO_NFAULT_TIMEOUT)); 14438e75f744SArnaud Giersch expire = jiffies + physport->cad->timeout; 14448e75f744SArnaud Giersch while (1) { 14458e75f744SArnaud Giersch if (parport_ip32_fifo_wait_break(p, expire)) 14468e75f744SArnaud Giersch break; 14478e75f744SArnaud Giersch wait_for_completion_interruptible_timeout(&priv->irq_complete, 14488e75f744SArnaud Giersch nfault_timeout); 14498e75f744SArnaud Giersch ecr = parport_ip32_read_econtrol(p); 14508e75f744SArnaud Giersch if (ecr & ECR_SERVINTR) 14518e75f744SArnaud Giersch break; /* DMA transfer just finished */ 14528e75f744SArnaud Giersch } 14534217efa3SChristoph Hellwig parport_ip32_dma_stop(p); 14548e75f744SArnaud Giersch written = len - parport_ip32_dma_get_residue(); 14558e75f744SArnaud Giersch 14568e75f744SArnaud Giersch priv->irq_mode = PARPORT_IP32_IRQ_FWD; 14578e75f744SArnaud Giersch 14588e75f744SArnaud Giersch return written; 14598e75f744SArnaud Giersch } 14608e75f744SArnaud Giersch 14618e75f744SArnaud Giersch /** 14628e75f744SArnaud Giersch * parport_ip32_fifo_write_block - write a block of data 14638e75f744SArnaud Giersch * @p: pointer to &struct parport 14648e75f744SArnaud Giersch * @buf: buffer of data to write 14658e75f744SArnaud Giersch * @len: length of buffer @buf 14668e75f744SArnaud Giersch * 14678e75f744SArnaud Giersch * Uses PIO or DMA to write the contents of the buffer @buf into the parallel 14688e75f744SArnaud Giersch * p FIFO. Returns the number of bytes that were actually written. 14698e75f744SArnaud Giersch */ 14708e75f744SArnaud Giersch static size_t parport_ip32_fifo_write_block(struct parport *p, 14718e75f744SArnaud Giersch const void *buf, size_t len) 14728e75f744SArnaud Giersch { 14738e75f744SArnaud Giersch size_t written = 0; 14748e75f744SArnaud Giersch if (len) 14758e75f744SArnaud Giersch /* FIXME - Maybe some threshold value should be set for @len 14768e75f744SArnaud Giersch * under which we revert to PIO mode? */ 14778e75f744SArnaud Giersch written = (p->modes & PARPORT_MODE_DMA) ? 14788e75f744SArnaud Giersch parport_ip32_fifo_write_block_dma(p, buf, len) : 14798e75f744SArnaud Giersch parport_ip32_fifo_write_block_pio(p, buf, len); 14808e75f744SArnaud Giersch return written; 14818e75f744SArnaud Giersch } 14828e75f744SArnaud Giersch 14838e75f744SArnaud Giersch /** 14848e75f744SArnaud Giersch * parport_ip32_drain_fifo - wait for FIFO to empty 14858e75f744SArnaud Giersch * @p: pointer to &struct parport 14868e75f744SArnaud Giersch * @timeout: timeout, in jiffies 14878e75f744SArnaud Giersch * 14888e75f744SArnaud Giersch * This function waits for FIFO to empty. It returns 1 when FIFO is empty, or 14898e75f744SArnaud Giersch * 0 if the timeout @timeout is reached before, or if a signal is pending. 14908e75f744SArnaud Giersch */ 14918e75f744SArnaud Giersch static unsigned int parport_ip32_drain_fifo(struct parport *p, 14928e75f744SArnaud Giersch unsigned long timeout) 14938e75f744SArnaud Giersch { 14948e75f744SArnaud Giersch unsigned long expire = jiffies + timeout; 14958e75f744SArnaud Giersch unsigned int polling_interval; 14968e75f744SArnaud Giersch unsigned int counter; 14978e75f744SArnaud Giersch 14988e75f744SArnaud Giersch /* Busy wait for approx. 200us */ 14998e75f744SArnaud Giersch for (counter = 0; counter < 40; counter++) { 15008e75f744SArnaud Giersch if (parport_ip32_read_econtrol(p) & ECR_F_EMPTY) 15018e75f744SArnaud Giersch break; 15028e75f744SArnaud Giersch if (time_after(jiffies, expire)) 15038e75f744SArnaud Giersch break; 15048e75f744SArnaud Giersch if (signal_pending(current)) 15058e75f744SArnaud Giersch break; 15068e75f744SArnaud Giersch udelay(5); 15078e75f744SArnaud Giersch } 15088e75f744SArnaud Giersch /* Poll slowly. Polling interval starts with 1 millisecond, and is 15098e75f744SArnaud Giersch * increased exponentially until 128. */ 15108e75f744SArnaud Giersch polling_interval = 1; /* msecs */ 15118e75f744SArnaud Giersch while (!(parport_ip32_read_econtrol(p) & ECR_F_EMPTY)) { 15128e75f744SArnaud Giersch if (time_after_eq(jiffies, expire)) 15138e75f744SArnaud Giersch break; 15148e75f744SArnaud Giersch msleep_interruptible(polling_interval); 15158e75f744SArnaud Giersch if (signal_pending(current)) 15168e75f744SArnaud Giersch break; 15178e75f744SArnaud Giersch if (polling_interval < 128) 15188e75f744SArnaud Giersch polling_interval *= 2; 15198e75f744SArnaud Giersch } 15208e75f744SArnaud Giersch 15218e75f744SArnaud Giersch return !!(parport_ip32_read_econtrol(p) & ECR_F_EMPTY); 15228e75f744SArnaud Giersch } 15238e75f744SArnaud Giersch 15248e75f744SArnaud Giersch /** 15258e75f744SArnaud Giersch * parport_ip32_get_fifo_residue - reset FIFO 15268e75f744SArnaud Giersch * @p: pointer to &struct parport 15278e75f744SArnaud Giersch * @mode: current operation mode (ECR_MODE_PPF or ECR_MODE_ECP) 15288e75f744SArnaud Giersch * 15298e75f744SArnaud Giersch * This function resets FIFO, and returns the number of bytes remaining in it. 15308e75f744SArnaud Giersch */ 15318e75f744SArnaud Giersch static unsigned int parport_ip32_get_fifo_residue(struct parport *p, 15328e75f744SArnaud Giersch unsigned int mode) 15338e75f744SArnaud Giersch { 15348e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 15358e75f744SArnaud Giersch unsigned int residue; 15368e75f744SArnaud Giersch unsigned int cnfga; 15378e75f744SArnaud Giersch 15388e75f744SArnaud Giersch /* FIXME - We are missing one byte if the printer is off-line. I 15398e75f744SArnaud Giersch * don't know how to detect this. It looks that the full bit is not 15408e75f744SArnaud Giersch * always reliable. For the moment, the problem is avoided in most 15418e75f744SArnaud Giersch * cases by testing for BUSY in parport_ip32_compat_write_data(). 15428e75f744SArnaud Giersch */ 15438e75f744SArnaud Giersch if (parport_ip32_read_econtrol(p) & ECR_F_EMPTY) 15448e75f744SArnaud Giersch residue = 0; 15458e75f744SArnaud Giersch else { 15468e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: FIFO is stuck\n", p->name); 15478e75f744SArnaud Giersch 15488e75f744SArnaud Giersch /* Stop all transfers. 15498e75f744SArnaud Giersch * 15508e75f744SArnaud Giersch * Microsoft's document instructs to drive DCR_STROBE to 0, 15518e75f744SArnaud Giersch * but it doesn't work (at least in Compatibility mode, not 15528e75f744SArnaud Giersch * tested in ECP mode). Switching directly to Test mode (as 15538e75f744SArnaud Giersch * in parport_pc) is not an option: it does confuse the port, 15548e75f744SArnaud Giersch * ECP service interrupts are no more working after that. A 15558e75f744SArnaud Giersch * hard reset is then needed to revert to a sane state. 15568e75f744SArnaud Giersch * 15578e75f744SArnaud Giersch * Let's hope that the FIFO is really stuck and that the 15588e75f744SArnaud Giersch * peripheral doesn't wake up now. 15598e75f744SArnaud Giersch */ 15608e75f744SArnaud Giersch parport_ip32_frob_control(p, DCR_STROBE, 0); 15618e75f744SArnaud Giersch 15628e75f744SArnaud Giersch /* Fill up FIFO */ 15638e75f744SArnaud Giersch for (residue = priv->fifo_depth; residue > 0; residue--) { 15648e75f744SArnaud Giersch if (parport_ip32_read_econtrol(p) & ECR_F_FULL) 15658e75f744SArnaud Giersch break; 15668e75f744SArnaud Giersch writeb(0x00, priv->regs.fifo); 15678e75f744SArnaud Giersch } 15688e75f744SArnaud Giersch } 15698e75f744SArnaud Giersch if (residue) 15708e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: %d PWord%s left in FIFO\n", 15718e75f744SArnaud Giersch p->name, residue, 15728e75f744SArnaud Giersch (residue == 1) ? " was" : "s were"); 15738e75f744SArnaud Giersch 15748e75f744SArnaud Giersch /* Now reset the FIFO */ 15758e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 15768e75f744SArnaud Giersch 15778e75f744SArnaud Giersch /* Host recovery for ECP mode */ 15788e75f744SArnaud Giersch if (mode == ECR_MODE_ECP) { 15798e75f744SArnaud Giersch parport_ip32_data_reverse(p); 15808e75f744SArnaud Giersch parport_ip32_frob_control(p, DCR_nINIT, 0); 15818e75f744SArnaud Giersch if (parport_wait_peripheral(p, DSR_PERROR, 0)) 15828e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: PEerror timeout 1 in %s\n", 15838e75f744SArnaud Giersch p->name, __func__); 15848e75f744SArnaud Giersch parport_ip32_frob_control(p, DCR_STROBE, DCR_STROBE); 15858e75f744SArnaud Giersch parport_ip32_frob_control(p, DCR_nINIT, DCR_nINIT); 15868e75f744SArnaud Giersch if (parport_wait_peripheral(p, DSR_PERROR, DSR_PERROR)) 15878e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: PEerror timeout 2 in %s\n", 15888e75f744SArnaud Giersch p->name, __func__); 15898e75f744SArnaud Giersch } 15908e75f744SArnaud Giersch 15918e75f744SArnaud Giersch /* Adjust residue if needed */ 15928e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_CFG); 15938e75f744SArnaud Giersch cnfga = readb(priv->regs.cnfgA); 15948e75f744SArnaud Giersch if (!(cnfga & CNFGA_nBYTEINTRANS)) { 15958e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: cnfgA contains 0x%02x\n", 15968e75f744SArnaud Giersch p->name, cnfga); 15978e75f744SArnaud Giersch pr_debug1(PPIP32 "%s: Accounting for extra byte\n", 15988e75f744SArnaud Giersch p->name); 15998e75f744SArnaud Giersch residue++; 16008e75f744SArnaud Giersch } 16018e75f744SArnaud Giersch 16028e75f744SArnaud Giersch /* Don't care about partial PWords since we do not support 16038e75f744SArnaud Giersch * PWord != 1 byte. */ 16048e75f744SArnaud Giersch 16058e75f744SArnaud Giersch /* Back to forward PS2 mode. */ 16068e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 16078e75f744SArnaud Giersch parport_ip32_data_forward(p); 16088e75f744SArnaud Giersch 16098e75f744SArnaud Giersch return residue; 16108e75f744SArnaud Giersch } 16118e75f744SArnaud Giersch 16128e75f744SArnaud Giersch /** 16138e75f744SArnaud Giersch * parport_ip32_compat_write_data - write a block of data in SPP mode 16148e75f744SArnaud Giersch * @p: pointer to &struct parport 16158e75f744SArnaud Giersch * @buf: buffer of data to write 16168e75f744SArnaud Giersch * @len: length of buffer @buf 16178e75f744SArnaud Giersch * @flags: ignored 16188e75f744SArnaud Giersch */ 16198e75f744SArnaud Giersch static size_t parport_ip32_compat_write_data(struct parport *p, 16208e75f744SArnaud Giersch const void *buf, size_t len, 16218e75f744SArnaud Giersch int flags) 16228e75f744SArnaud Giersch { 16238e75f744SArnaud Giersch static unsigned int ready_before = 1; 16248e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 16258e75f744SArnaud Giersch struct parport * const physport = p->physport; 16268e75f744SArnaud Giersch size_t written = 0; 16278e75f744SArnaud Giersch 16288e75f744SArnaud Giersch /* Special case: a timeout of zero means we cannot call schedule(). 16298e75f744SArnaud Giersch * Also if O_NONBLOCK is set then use the default implementation. */ 16308e75f744SArnaud Giersch if (physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK) 16318e75f744SArnaud Giersch return parport_ieee1284_write_compat(p, buf, len, flags); 16328e75f744SArnaud Giersch 16338e75f744SArnaud Giersch /* Reset FIFO, go in forward mode, and disable ackIntEn */ 16348e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 16358e75f744SArnaud Giersch parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT); 16368e75f744SArnaud Giersch parport_ip32_data_forward(p); 16378e75f744SArnaud Giersch parport_ip32_disable_irq(p); 16388e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PPF); 16398e75f744SArnaud Giersch physport->ieee1284.phase = IEEE1284_PH_FWD_DATA; 16408e75f744SArnaud Giersch 16418e75f744SArnaud Giersch /* Wait for peripheral to become ready */ 16428e75f744SArnaud Giersch if (parport_wait_peripheral(p, DSR_nBUSY | DSR_nFAULT, 16438e75f744SArnaud Giersch DSR_nBUSY | DSR_nFAULT)) { 16448e75f744SArnaud Giersch /* Avoid to flood the logs */ 16458e75f744SArnaud Giersch if (ready_before) 16468e75f744SArnaud Giersch printk(KERN_INFO PPIP32 "%s: not ready in %s\n", 16478e75f744SArnaud Giersch p->name, __func__); 16488e75f744SArnaud Giersch ready_before = 0; 16498e75f744SArnaud Giersch goto stop; 16508e75f744SArnaud Giersch } 16518e75f744SArnaud Giersch ready_before = 1; 16528e75f744SArnaud Giersch 16538e75f744SArnaud Giersch written = parport_ip32_fifo_write_block(p, buf, len); 16548e75f744SArnaud Giersch 16558e75f744SArnaud Giersch /* Wait FIFO to empty. Timeout is proportional to FIFO_depth. */ 16568e75f744SArnaud Giersch parport_ip32_drain_fifo(p, physport->cad->timeout * priv->fifo_depth); 16578e75f744SArnaud Giersch 16588e75f744SArnaud Giersch /* Check for a potential residue */ 16598e75f744SArnaud Giersch written -= parport_ip32_get_fifo_residue(p, ECR_MODE_PPF); 16608e75f744SArnaud Giersch 16618e75f744SArnaud Giersch /* Then, wait for BUSY to get low. */ 16628e75f744SArnaud Giersch if (parport_wait_peripheral(p, DSR_nBUSY, DSR_nBUSY)) 16638e75f744SArnaud Giersch printk(KERN_DEBUG PPIP32 "%s: BUSY timeout in %s\n", 16648e75f744SArnaud Giersch p->name, __func__); 16658e75f744SArnaud Giersch 16668e75f744SArnaud Giersch stop: 16678e75f744SArnaud Giersch /* Reset FIFO */ 16688e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 16698e75f744SArnaud Giersch physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE; 16708e75f744SArnaud Giersch 16718e75f744SArnaud Giersch return written; 16728e75f744SArnaud Giersch } 16738e75f744SArnaud Giersch 16748e75f744SArnaud Giersch /* 16758e75f744SArnaud Giersch * FIXME - Insert here parport_ip32_ecp_read_data(). 16768e75f744SArnaud Giersch */ 16778e75f744SArnaud Giersch 16788e75f744SArnaud Giersch /** 16798e75f744SArnaud Giersch * parport_ip32_ecp_write_data - write a block of data in ECP mode 16808e75f744SArnaud Giersch * @p: pointer to &struct parport 16818e75f744SArnaud Giersch * @buf: buffer of data to write 16828e75f744SArnaud Giersch * @len: length of buffer @buf 16838e75f744SArnaud Giersch * @flags: ignored 16848e75f744SArnaud Giersch */ 16858e75f744SArnaud Giersch static size_t parport_ip32_ecp_write_data(struct parport *p, 16868e75f744SArnaud Giersch const void *buf, size_t len, 16878e75f744SArnaud Giersch int flags) 16888e75f744SArnaud Giersch { 16898e75f744SArnaud Giersch static unsigned int ready_before = 1; 16908e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 16918e75f744SArnaud Giersch struct parport * const physport = p->physport; 16928e75f744SArnaud Giersch size_t written = 0; 16938e75f744SArnaud Giersch 16948e75f744SArnaud Giersch /* Special case: a timeout of zero means we cannot call schedule(). 16958e75f744SArnaud Giersch * Also if O_NONBLOCK is set then use the default implementation. */ 16968e75f744SArnaud Giersch if (physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK) 16978e75f744SArnaud Giersch return parport_ieee1284_ecp_write_data(p, buf, len, flags); 16988e75f744SArnaud Giersch 16998e75f744SArnaud Giersch /* Negotiate to forward mode if necessary. */ 17008e75f744SArnaud Giersch if (physport->ieee1284.phase != IEEE1284_PH_FWD_IDLE) { 17018e75f744SArnaud Giersch /* Event 47: Set nInit high. */ 17028e75f744SArnaud Giersch parport_ip32_frob_control(p, DCR_nINIT | DCR_AUTOFD, 17038e75f744SArnaud Giersch DCR_nINIT | DCR_AUTOFD); 17048e75f744SArnaud Giersch 17058e75f744SArnaud Giersch /* Event 49: PError goes high. */ 17068e75f744SArnaud Giersch if (parport_wait_peripheral(p, DSR_PERROR, DSR_PERROR)) { 17078e75f744SArnaud Giersch printk(KERN_DEBUG PPIP32 "%s: PError timeout in %s", 17088e75f744SArnaud Giersch p->name, __func__); 17098e75f744SArnaud Giersch physport->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN; 17108e75f744SArnaud Giersch return 0; 17118e75f744SArnaud Giersch } 17128e75f744SArnaud Giersch } 17138e75f744SArnaud Giersch 17148e75f744SArnaud Giersch /* Reset FIFO, go in forward mode, and disable ackIntEn */ 17158e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 17168e75f744SArnaud Giersch parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT); 17178e75f744SArnaud Giersch parport_ip32_data_forward(p); 17188e75f744SArnaud Giersch parport_ip32_disable_irq(p); 17198e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_ECP); 17208e75f744SArnaud Giersch physport->ieee1284.phase = IEEE1284_PH_FWD_DATA; 17218e75f744SArnaud Giersch 17228e75f744SArnaud Giersch /* Wait for peripheral to become ready */ 17238e75f744SArnaud Giersch if (parport_wait_peripheral(p, DSR_nBUSY | DSR_nFAULT, 17248e75f744SArnaud Giersch DSR_nBUSY | DSR_nFAULT)) { 17258e75f744SArnaud Giersch /* Avoid to flood the logs */ 17268e75f744SArnaud Giersch if (ready_before) 17278e75f744SArnaud Giersch printk(KERN_INFO PPIP32 "%s: not ready in %s\n", 17288e75f744SArnaud Giersch p->name, __func__); 17298e75f744SArnaud Giersch ready_before = 0; 17308e75f744SArnaud Giersch goto stop; 17318e75f744SArnaud Giersch } 17328e75f744SArnaud Giersch ready_before = 1; 17338e75f744SArnaud Giersch 17348e75f744SArnaud Giersch written = parport_ip32_fifo_write_block(p, buf, len); 17358e75f744SArnaud Giersch 17368e75f744SArnaud Giersch /* Wait FIFO to empty. Timeout is proportional to FIFO_depth. */ 17378e75f744SArnaud Giersch parport_ip32_drain_fifo(p, physport->cad->timeout * priv->fifo_depth); 17388e75f744SArnaud Giersch 17398e75f744SArnaud Giersch /* Check for a potential residue */ 17408e75f744SArnaud Giersch written -= parport_ip32_get_fifo_residue(p, ECR_MODE_ECP); 17418e75f744SArnaud Giersch 17428e75f744SArnaud Giersch /* Then, wait for BUSY to get low. */ 17438e75f744SArnaud Giersch if (parport_wait_peripheral(p, DSR_nBUSY, DSR_nBUSY)) 17448e75f744SArnaud Giersch printk(KERN_DEBUG PPIP32 "%s: BUSY timeout in %s\n", 17458e75f744SArnaud Giersch p->name, __func__); 17468e75f744SArnaud Giersch 17478e75f744SArnaud Giersch stop: 17488e75f744SArnaud Giersch /* Reset FIFO */ 17498e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 17508e75f744SArnaud Giersch physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE; 17518e75f744SArnaud Giersch 17528e75f744SArnaud Giersch return written; 17538e75f744SArnaud Giersch } 17548e75f744SArnaud Giersch 17558e75f744SArnaud Giersch /* 17568e75f744SArnaud Giersch * FIXME - Insert here parport_ip32_ecp_write_addr(). 17578e75f744SArnaud Giersch */ 17588e75f744SArnaud Giersch 17598e75f744SArnaud Giersch /*--- Default parport operations ---------------------------------------*/ 17608e75f744SArnaud Giersch 1761c932806cSBhumika Goyal static const struct parport_operations parport_ip32_ops __initconst = { 17628e75f744SArnaud Giersch .write_data = parport_ip32_write_data, 17638e75f744SArnaud Giersch .read_data = parport_ip32_read_data, 17648e75f744SArnaud Giersch 17658e75f744SArnaud Giersch .write_control = parport_ip32_write_control, 17668e75f744SArnaud Giersch .read_control = parport_ip32_read_control, 17678e75f744SArnaud Giersch .frob_control = parport_ip32_frob_control, 17688e75f744SArnaud Giersch 17698e75f744SArnaud Giersch .read_status = parport_ip32_read_status, 17708e75f744SArnaud Giersch 17718e75f744SArnaud Giersch .enable_irq = parport_ip32_enable_irq, 17728e75f744SArnaud Giersch .disable_irq = parport_ip32_disable_irq, 17738e75f744SArnaud Giersch 17748e75f744SArnaud Giersch .data_forward = parport_ip32_data_forward, 17758e75f744SArnaud Giersch .data_reverse = parport_ip32_data_reverse, 17768e75f744SArnaud Giersch 17778e75f744SArnaud Giersch .init_state = parport_ip32_init_state, 17788e75f744SArnaud Giersch .save_state = parport_ip32_save_state, 17798e75f744SArnaud Giersch .restore_state = parport_ip32_restore_state, 17808e75f744SArnaud Giersch 17818e75f744SArnaud Giersch .epp_write_data = parport_ieee1284_epp_write_data, 17828e75f744SArnaud Giersch .epp_read_data = parport_ieee1284_epp_read_data, 17838e75f744SArnaud Giersch .epp_write_addr = parport_ieee1284_epp_write_addr, 17848e75f744SArnaud Giersch .epp_read_addr = parport_ieee1284_epp_read_addr, 17858e75f744SArnaud Giersch 17868e75f744SArnaud Giersch .ecp_write_data = parport_ieee1284_ecp_write_data, 17878e75f744SArnaud Giersch .ecp_read_data = parport_ieee1284_ecp_read_data, 17888e75f744SArnaud Giersch .ecp_write_addr = parport_ieee1284_ecp_write_addr, 17898e75f744SArnaud Giersch 17908e75f744SArnaud Giersch .compat_write_data = parport_ieee1284_write_compat, 17918e75f744SArnaud Giersch .nibble_read_data = parport_ieee1284_read_nibble, 17928e75f744SArnaud Giersch .byte_read_data = parport_ieee1284_read_byte, 17938e75f744SArnaud Giersch 17948e75f744SArnaud Giersch .owner = THIS_MODULE, 17958e75f744SArnaud Giersch }; 17968e75f744SArnaud Giersch 17978e75f744SArnaud Giersch /*--- Device detection -------------------------------------------------*/ 17988e75f744SArnaud Giersch 17998e75f744SArnaud Giersch /** 18008e75f744SArnaud Giersch * parport_ip32_ecp_supported - check for an ECP port 18018e75f744SArnaud Giersch * @p: pointer to the &parport structure 18028e75f744SArnaud Giersch * 18038e75f744SArnaud Giersch * Returns 1 if an ECP port is found, and 0 otherwise. This function actually 18048e75f744SArnaud Giersch * checks if an Extended Control Register seems to be present. On successful 18058e75f744SArnaud Giersch * return, the port is placed in SPP mode. 18068e75f744SArnaud Giersch */ 18078e75f744SArnaud Giersch static __init unsigned int parport_ip32_ecp_supported(struct parport *p) 18088e75f744SArnaud Giersch { 18098e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 18108e75f744SArnaud Giersch unsigned int ecr; 18118e75f744SArnaud Giersch 18128e75f744SArnaud Giersch ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR; 18138e75f744SArnaud Giersch writeb(ecr, priv->regs.ecr); 18148e75f744SArnaud Giersch if (readb(priv->regs.ecr) != (ecr | ECR_F_EMPTY)) 18158e75f744SArnaud Giersch goto fail; 18168e75f744SArnaud Giersch 18178e75f744SArnaud Giersch pr_probe(p, "Found working ECR register\n"); 18188e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_SPP); 18198e75f744SArnaud Giersch parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT); 18208e75f744SArnaud Giersch return 1; 18218e75f744SArnaud Giersch 18228e75f744SArnaud Giersch fail: 18238e75f744SArnaud Giersch pr_probe(p, "ECR register not found\n"); 18248e75f744SArnaud Giersch return 0; 18258e75f744SArnaud Giersch } 18268e75f744SArnaud Giersch 18278e75f744SArnaud Giersch /** 18288e75f744SArnaud Giersch * parport_ip32_fifo_supported - check for FIFO parameters 18298e75f744SArnaud Giersch * @p: pointer to the &parport structure 18308e75f744SArnaud Giersch * 18318e75f744SArnaud Giersch * Check for FIFO parameters of an Extended Capabilities Port. Returns 1 on 18328e75f744SArnaud Giersch * success, and 0 otherwise. Adjust FIFO parameters in the parport structure. 18338e75f744SArnaud Giersch * On return, the port is placed in SPP mode. 18348e75f744SArnaud Giersch */ 18358e75f744SArnaud Giersch static __init unsigned int parport_ip32_fifo_supported(struct parport *p) 18368e75f744SArnaud Giersch { 18378e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 18388e75f744SArnaud Giersch unsigned int configa, configb; 18398e75f744SArnaud Giersch unsigned int pword; 18408e75f744SArnaud Giersch unsigned int i; 18418e75f744SArnaud Giersch 18428e75f744SArnaud Giersch /* Configuration mode */ 18438e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_CFG); 18448e75f744SArnaud Giersch configa = readb(priv->regs.cnfgA); 18458e75f744SArnaud Giersch configb = readb(priv->regs.cnfgB); 18468e75f744SArnaud Giersch 18478e75f744SArnaud Giersch /* Find out PWord size */ 18488e75f744SArnaud Giersch switch (configa & CNFGA_ID_MASK) { 18498e75f744SArnaud Giersch case CNFGA_ID_8: 18508e75f744SArnaud Giersch pword = 1; 18518e75f744SArnaud Giersch break; 18528e75f744SArnaud Giersch case CNFGA_ID_16: 18538e75f744SArnaud Giersch pword = 2; 18548e75f744SArnaud Giersch break; 18558e75f744SArnaud Giersch case CNFGA_ID_32: 18568e75f744SArnaud Giersch pword = 4; 18578e75f744SArnaud Giersch break; 18588e75f744SArnaud Giersch default: 18598e75f744SArnaud Giersch pr_probe(p, "Unknown implementation ID: 0x%0x\n", 18608e75f744SArnaud Giersch (configa & CNFGA_ID_MASK) >> CNFGA_ID_SHIFT); 18618e75f744SArnaud Giersch goto fail; 18628e75f744SArnaud Giersch break; 18638e75f744SArnaud Giersch } 18648e75f744SArnaud Giersch if (pword != 1) { 18658e75f744SArnaud Giersch pr_probe(p, "Unsupported PWord size: %u\n", pword); 18668e75f744SArnaud Giersch goto fail; 18678e75f744SArnaud Giersch } 18688e75f744SArnaud Giersch priv->pword = pword; 18698e75f744SArnaud Giersch pr_probe(p, "PWord is %u bits\n", 8 * priv->pword); 18708e75f744SArnaud Giersch 18718e75f744SArnaud Giersch /* Check for compression support */ 18728e75f744SArnaud Giersch writeb(configb | CNFGB_COMPRESS, priv->regs.cnfgB); 18738e75f744SArnaud Giersch if (readb(priv->regs.cnfgB) & CNFGB_COMPRESS) 18748e75f744SArnaud Giersch pr_probe(p, "Hardware compression detected (unsupported)\n"); 18758e75f744SArnaud Giersch writeb(configb & ~CNFGB_COMPRESS, priv->regs.cnfgB); 18768e75f744SArnaud Giersch 18778e75f744SArnaud Giersch /* Reset FIFO and go in test mode (no interrupt, no DMA) */ 18788e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_TST); 18798e75f744SArnaud Giersch 18808e75f744SArnaud Giersch /* FIFO must be empty now */ 18818e75f744SArnaud Giersch if (!(readb(priv->regs.ecr) & ECR_F_EMPTY)) { 18828e75f744SArnaud Giersch pr_probe(p, "FIFO not reset\n"); 18838e75f744SArnaud Giersch goto fail; 18848e75f744SArnaud Giersch } 18858e75f744SArnaud Giersch 18868e75f744SArnaud Giersch /* Find out FIFO depth. */ 18878e75f744SArnaud Giersch priv->fifo_depth = 0; 18888e75f744SArnaud Giersch for (i = 0; i < 1024; i++) { 18898e75f744SArnaud Giersch if (readb(priv->regs.ecr) & ECR_F_FULL) { 18908e75f744SArnaud Giersch /* FIFO full */ 18918e75f744SArnaud Giersch priv->fifo_depth = i; 18928e75f744SArnaud Giersch break; 18938e75f744SArnaud Giersch } 18948e75f744SArnaud Giersch writeb((u8)i, priv->regs.fifo); 18958e75f744SArnaud Giersch } 18968e75f744SArnaud Giersch if (i >= 1024) { 18978e75f744SArnaud Giersch pr_probe(p, "Can't fill FIFO\n"); 18988e75f744SArnaud Giersch goto fail; 18998e75f744SArnaud Giersch } 19008e75f744SArnaud Giersch if (!priv->fifo_depth) { 19018e75f744SArnaud Giersch pr_probe(p, "Can't get FIFO depth\n"); 19028e75f744SArnaud Giersch goto fail; 19038e75f744SArnaud Giersch } 19048e75f744SArnaud Giersch pr_probe(p, "FIFO is %u PWords deep\n", priv->fifo_depth); 19058e75f744SArnaud Giersch 19068e75f744SArnaud Giersch /* Enable interrupts */ 19078e75f744SArnaud Giersch parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0); 19088e75f744SArnaud Giersch 19098e75f744SArnaud Giersch /* Find out writeIntrThreshold: number of PWords we know we can write 19108e75f744SArnaud Giersch * if we get an interrupt. */ 19118e75f744SArnaud Giersch priv->writeIntrThreshold = 0; 19128e75f744SArnaud Giersch for (i = 0; i < priv->fifo_depth; i++) { 19138e75f744SArnaud Giersch if (readb(priv->regs.fifo) != (u8)i) { 19148e75f744SArnaud Giersch pr_probe(p, "Invalid data in FIFO\n"); 19158e75f744SArnaud Giersch goto fail; 19168e75f744SArnaud Giersch } 19178e75f744SArnaud Giersch if (!priv->writeIntrThreshold 19188e75f744SArnaud Giersch && readb(priv->regs.ecr) & ECR_SERVINTR) 19198e75f744SArnaud Giersch /* writeIntrThreshold reached */ 19208e75f744SArnaud Giersch priv->writeIntrThreshold = i + 1; 19218e75f744SArnaud Giersch if (i + 1 < priv->fifo_depth 19228e75f744SArnaud Giersch && readb(priv->regs.ecr) & ECR_F_EMPTY) { 19238e75f744SArnaud Giersch /* FIFO empty before the last byte? */ 19248e75f744SArnaud Giersch pr_probe(p, "Data lost in FIFO\n"); 19258e75f744SArnaud Giersch goto fail; 19268e75f744SArnaud Giersch } 19278e75f744SArnaud Giersch } 19288e75f744SArnaud Giersch if (!priv->writeIntrThreshold) { 19298e75f744SArnaud Giersch pr_probe(p, "Can't get writeIntrThreshold\n"); 19308e75f744SArnaud Giersch goto fail; 19318e75f744SArnaud Giersch } 19328e75f744SArnaud Giersch pr_probe(p, "writeIntrThreshold is %u\n", priv->writeIntrThreshold); 19338e75f744SArnaud Giersch 19348e75f744SArnaud Giersch /* FIFO must be empty now */ 19358e75f744SArnaud Giersch if (!(readb(priv->regs.ecr) & ECR_F_EMPTY)) { 19368e75f744SArnaud Giersch pr_probe(p, "Can't empty FIFO\n"); 19378e75f744SArnaud Giersch goto fail; 19388e75f744SArnaud Giersch } 19398e75f744SArnaud Giersch 19408e75f744SArnaud Giersch /* Reset FIFO */ 19418e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 19428e75f744SArnaud Giersch /* Set reverse direction (must be in PS2 mode) */ 19438e75f744SArnaud Giersch parport_ip32_data_reverse(p); 19448e75f744SArnaud Giersch /* Test FIFO, no interrupt, no DMA */ 19458e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_TST); 19468e75f744SArnaud Giersch /* Enable interrupts */ 19478e75f744SArnaud Giersch parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0); 19488e75f744SArnaud Giersch 19498e75f744SArnaud Giersch /* Find out readIntrThreshold: number of PWords we can read if we get 19508e75f744SArnaud Giersch * an interrupt. */ 19518e75f744SArnaud Giersch priv->readIntrThreshold = 0; 19528e75f744SArnaud Giersch for (i = 0; i < priv->fifo_depth; i++) { 19538e75f744SArnaud Giersch writeb(0xaa, priv->regs.fifo); 19548e75f744SArnaud Giersch if (readb(priv->regs.ecr) & ECR_SERVINTR) { 19558e75f744SArnaud Giersch /* readIntrThreshold reached */ 19568e75f744SArnaud Giersch priv->readIntrThreshold = i + 1; 19578e75f744SArnaud Giersch break; 19588e75f744SArnaud Giersch } 19598e75f744SArnaud Giersch } 19608e75f744SArnaud Giersch if (!priv->readIntrThreshold) { 19618e75f744SArnaud Giersch pr_probe(p, "Can't get readIntrThreshold\n"); 19628e75f744SArnaud Giersch goto fail; 19638e75f744SArnaud Giersch } 19648e75f744SArnaud Giersch pr_probe(p, "readIntrThreshold is %u\n", priv->readIntrThreshold); 19658e75f744SArnaud Giersch 19668e75f744SArnaud Giersch /* Reset ECR */ 19678e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 19688e75f744SArnaud Giersch parport_ip32_data_forward(p); 19698e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_SPP); 19708e75f744SArnaud Giersch return 1; 19718e75f744SArnaud Giersch 19728e75f744SArnaud Giersch fail: 19738e75f744SArnaud Giersch priv->fifo_depth = 0; 19748e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_SPP); 19758e75f744SArnaud Giersch return 0; 19768e75f744SArnaud Giersch } 19778e75f744SArnaud Giersch 19788e75f744SArnaud Giersch /*--- Initialization code ----------------------------------------------*/ 19798e75f744SArnaud Giersch 19808e75f744SArnaud Giersch /** 19818e75f744SArnaud Giersch * parport_ip32_make_isa_registers - compute (ISA) register addresses 19828e75f744SArnaud Giersch * @regs: pointer to &struct parport_ip32_regs to fill 19838e75f744SArnaud Giersch * @base: base address of standard and EPP registers 19848e75f744SArnaud Giersch * @base_hi: base address of ECP registers 19858e75f744SArnaud Giersch * @regshift: how much to shift register offset by 19868e75f744SArnaud Giersch * 19878e75f744SArnaud Giersch * Compute register addresses, according to the ISA standard. The addresses 19888e75f744SArnaud Giersch * of the standard and EPP registers are computed from address @base. The 19898e75f744SArnaud Giersch * addresses of the ECP registers are computed from address @base_hi. 19908e75f744SArnaud Giersch */ 19918e75f744SArnaud Giersch static void __init 19928e75f744SArnaud Giersch parport_ip32_make_isa_registers(struct parport_ip32_regs *regs, 19938e75f744SArnaud Giersch void __iomem *base, void __iomem *base_hi, 19948e75f744SArnaud Giersch unsigned int regshift) 19958e75f744SArnaud Giersch { 19968e75f744SArnaud Giersch #define r_base(offset) ((u8 __iomem *)base + ((offset) << regshift)) 19978e75f744SArnaud Giersch #define r_base_hi(offset) ((u8 __iomem *)base_hi + ((offset) << regshift)) 19988e75f744SArnaud Giersch *regs = (struct parport_ip32_regs){ 19998e75f744SArnaud Giersch .data = r_base(0), 20008e75f744SArnaud Giersch .dsr = r_base(1), 20018e75f744SArnaud Giersch .dcr = r_base(2), 20028e75f744SArnaud Giersch .eppAddr = r_base(3), 20038e75f744SArnaud Giersch .eppData0 = r_base(4), 20048e75f744SArnaud Giersch .eppData1 = r_base(5), 20058e75f744SArnaud Giersch .eppData2 = r_base(6), 20068e75f744SArnaud Giersch .eppData3 = r_base(7), 20078e75f744SArnaud Giersch .ecpAFifo = r_base(0), 20088e75f744SArnaud Giersch .fifo = r_base_hi(0), 20098e75f744SArnaud Giersch .cnfgA = r_base_hi(0), 20108e75f744SArnaud Giersch .cnfgB = r_base_hi(1), 20118e75f744SArnaud Giersch .ecr = r_base_hi(2) 20128e75f744SArnaud Giersch }; 20138e75f744SArnaud Giersch #undef r_base_hi 20148e75f744SArnaud Giersch #undef r_base 20158e75f744SArnaud Giersch } 20168e75f744SArnaud Giersch 20178e75f744SArnaud Giersch /** 20188e75f744SArnaud Giersch * parport_ip32_probe_port - probe and register IP32 built-in parallel port 20198e75f744SArnaud Giersch * 20208e75f744SArnaud Giersch * Returns the new allocated &parport structure. On error, an error code is 20218e75f744SArnaud Giersch * encoded in return value with the ERR_PTR function. 20228e75f744SArnaud Giersch */ 20238e75f744SArnaud Giersch static __init struct parport *parport_ip32_probe_port(void) 20248e75f744SArnaud Giersch { 20258e75f744SArnaud Giersch struct parport_ip32_regs regs; 20268e75f744SArnaud Giersch struct parport_ip32_private *priv = NULL; 20278e75f744SArnaud Giersch struct parport_operations *ops = NULL; 20288e75f744SArnaud Giersch struct parport *p = NULL; 20298e75f744SArnaud Giersch int err; 20308e75f744SArnaud Giersch 20318e75f744SArnaud Giersch parport_ip32_make_isa_registers(®s, &mace->isa.parallel, 20328e75f744SArnaud Giersch &mace->isa.ecp1284, 8 /* regshift */); 20338e75f744SArnaud Giersch 20348e75f744SArnaud Giersch ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); 20358e75f744SArnaud Giersch priv = kmalloc(sizeof(struct parport_ip32_private), GFP_KERNEL); 20368e75f744SArnaud Giersch p = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, ops); 20378e75f744SArnaud Giersch if (ops == NULL || priv == NULL || p == NULL) { 20388e75f744SArnaud Giersch err = -ENOMEM; 20398e75f744SArnaud Giersch goto fail; 20408e75f744SArnaud Giersch } 20418e75f744SArnaud Giersch p->base = MACE_BASE + offsetof(struct sgi_mace, isa.parallel); 20428e75f744SArnaud Giersch p->base_hi = MACE_BASE + offsetof(struct sgi_mace, isa.ecp1284); 20438e75f744SArnaud Giersch p->private_data = priv; 20448e75f744SArnaud Giersch 20458e75f744SArnaud Giersch *ops = parport_ip32_ops; 20468e75f744SArnaud Giersch *priv = (struct parport_ip32_private){ 20478e75f744SArnaud Giersch .regs = regs, 20488e75f744SArnaud Giersch .dcr_writable = DCR_DIR | DCR_SELECT | DCR_nINIT | 20498e75f744SArnaud Giersch DCR_AUTOFD | DCR_STROBE, 20508e75f744SArnaud Giersch .irq_mode = PARPORT_IP32_IRQ_FWD, 20518e75f744SArnaud Giersch }; 20528e75f744SArnaud Giersch init_completion(&priv->irq_complete); 20538e75f744SArnaud Giersch 20548e75f744SArnaud Giersch /* Probe port. */ 20558e75f744SArnaud Giersch if (!parport_ip32_ecp_supported(p)) { 20568e75f744SArnaud Giersch err = -ENODEV; 20578e75f744SArnaud Giersch goto fail; 20588e75f744SArnaud Giersch } 20598e75f744SArnaud Giersch parport_ip32_dump_state(p, "begin init", 0); 20608e75f744SArnaud Giersch 20618e75f744SArnaud Giersch /* We found what looks like a working ECR register. Simply assume 20628e75f744SArnaud Giersch * that all modes are correctly supported. Enable basic modes. */ 20638e75f744SArnaud Giersch p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; 20648e75f744SArnaud Giersch p->modes |= PARPORT_MODE_TRISTATE; 20658e75f744SArnaud Giersch 20668e75f744SArnaud Giersch if (!parport_ip32_fifo_supported(p)) { 20678e75f744SArnaud Giersch printk(KERN_WARNING PPIP32 20688e75f744SArnaud Giersch "%s: error: FIFO disabled\n", p->name); 20698e75f744SArnaud Giersch /* Disable hardware modes depending on a working FIFO. */ 20708e75f744SArnaud Giersch features &= ~PARPORT_IP32_ENABLE_SPP; 20718e75f744SArnaud Giersch features &= ~PARPORT_IP32_ENABLE_ECP; 20728e75f744SArnaud Giersch /* DMA is not needed if FIFO is not supported. */ 20738e75f744SArnaud Giersch features &= ~PARPORT_IP32_ENABLE_DMA; 20748e75f744SArnaud Giersch } 20758e75f744SArnaud Giersch 20768e75f744SArnaud Giersch /* Request IRQ */ 20778e75f744SArnaud Giersch if (features & PARPORT_IP32_ENABLE_IRQ) { 20788e75f744SArnaud Giersch int irq = MACEISA_PARALLEL_IRQ; 20798e75f744SArnaud Giersch if (request_irq(irq, parport_ip32_interrupt, 0, p->name, p)) { 20808e75f744SArnaud Giersch printk(KERN_WARNING PPIP32 20818e75f744SArnaud Giersch "%s: error: IRQ disabled\n", p->name); 20828e75f744SArnaud Giersch /* DMA cannot work without interrupts. */ 20838e75f744SArnaud Giersch features &= ~PARPORT_IP32_ENABLE_DMA; 20848e75f744SArnaud Giersch } else { 20858e75f744SArnaud Giersch pr_probe(p, "Interrupt support enabled\n"); 20868e75f744SArnaud Giersch p->irq = irq; 20878e75f744SArnaud Giersch priv->dcr_writable |= DCR_IRQ; 20888e75f744SArnaud Giersch } 20898e75f744SArnaud Giersch } 20908e75f744SArnaud Giersch 20918e75f744SArnaud Giersch /* Allocate DMA resources */ 20928e75f744SArnaud Giersch if (features & PARPORT_IP32_ENABLE_DMA) { 20938e75f744SArnaud Giersch if (parport_ip32_dma_register()) 20948e75f744SArnaud Giersch printk(KERN_WARNING PPIP32 20958e75f744SArnaud Giersch "%s: error: DMA disabled\n", p->name); 20968e75f744SArnaud Giersch else { 20978e75f744SArnaud Giersch pr_probe(p, "DMA support enabled\n"); 20988e75f744SArnaud Giersch p->dma = 0; /* arbitrary value != PARPORT_DMA_NONE */ 20998e75f744SArnaud Giersch p->modes |= PARPORT_MODE_DMA; 21008e75f744SArnaud Giersch } 21018e75f744SArnaud Giersch } 21028e75f744SArnaud Giersch 21038e75f744SArnaud Giersch if (features & PARPORT_IP32_ENABLE_SPP) { 21048e75f744SArnaud Giersch /* Enable compatibility FIFO mode */ 21058e75f744SArnaud Giersch p->ops->compat_write_data = parport_ip32_compat_write_data; 21068e75f744SArnaud Giersch p->modes |= PARPORT_MODE_COMPAT; 21078e75f744SArnaud Giersch pr_probe(p, "Hardware support for SPP mode enabled\n"); 21088e75f744SArnaud Giersch } 21098e75f744SArnaud Giersch if (features & PARPORT_IP32_ENABLE_EPP) { 21108e75f744SArnaud Giersch /* Set up access functions to use EPP hardware. */ 21118e75f744SArnaud Giersch p->ops->epp_read_data = parport_ip32_epp_read_data; 21128e75f744SArnaud Giersch p->ops->epp_write_data = parport_ip32_epp_write_data; 21138e75f744SArnaud Giersch p->ops->epp_read_addr = parport_ip32_epp_read_addr; 21148e75f744SArnaud Giersch p->ops->epp_write_addr = parport_ip32_epp_write_addr; 21158e75f744SArnaud Giersch p->modes |= PARPORT_MODE_EPP; 21168e75f744SArnaud Giersch pr_probe(p, "Hardware support for EPP mode enabled\n"); 21178e75f744SArnaud Giersch } 21188e75f744SArnaud Giersch if (features & PARPORT_IP32_ENABLE_ECP) { 21198e75f744SArnaud Giersch /* Enable ECP FIFO mode */ 21208e75f744SArnaud Giersch p->ops->ecp_write_data = parport_ip32_ecp_write_data; 21218e75f744SArnaud Giersch /* FIXME - not implemented */ 21228e75f744SArnaud Giersch /* p->ops->ecp_read_data = parport_ip32_ecp_read_data; */ 21238e75f744SArnaud Giersch /* p->ops->ecp_write_addr = parport_ip32_ecp_write_addr; */ 21248e75f744SArnaud Giersch p->modes |= PARPORT_MODE_ECP; 21258e75f744SArnaud Giersch pr_probe(p, "Hardware support for ECP mode enabled\n"); 21268e75f744SArnaud Giersch } 21278e75f744SArnaud Giersch 21288e75f744SArnaud Giersch /* Initialize the port with sensible values */ 21298e75f744SArnaud Giersch parport_ip32_set_mode(p, ECR_MODE_PS2); 21308e75f744SArnaud Giersch parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT); 21318e75f744SArnaud Giersch parport_ip32_data_forward(p); 21328e75f744SArnaud Giersch parport_ip32_disable_irq(p); 21338e75f744SArnaud Giersch parport_ip32_write_data(p, 0x00); 21348e75f744SArnaud Giersch parport_ip32_dump_state(p, "end init", 0); 21358e75f744SArnaud Giersch 21368e75f744SArnaud Giersch /* Print out what we found */ 21378e75f744SArnaud Giersch printk(KERN_INFO "%s: SGI IP32 at 0x%lx (0x%lx)", 21388e75f744SArnaud Giersch p->name, p->base, p->base_hi); 21398e75f744SArnaud Giersch if (p->irq != PARPORT_IRQ_NONE) 21408e75f744SArnaud Giersch printk(", irq %d", p->irq); 21418e75f744SArnaud Giersch printk(" ["); 21428e75f744SArnaud Giersch #define printmode(x) if (p->modes & PARPORT_MODE_##x) \ 21438e75f744SArnaud Giersch printk("%s%s", f++ ? "," : "", #x) 21448e75f744SArnaud Giersch { 21458e75f744SArnaud Giersch unsigned int f = 0; 21468e75f744SArnaud Giersch printmode(PCSPP); 21478e75f744SArnaud Giersch printmode(TRISTATE); 21488e75f744SArnaud Giersch printmode(COMPAT); 21498e75f744SArnaud Giersch printmode(EPP); 21508e75f744SArnaud Giersch printmode(ECP); 21518e75f744SArnaud Giersch printmode(DMA); 21528e75f744SArnaud Giersch } 21538e75f744SArnaud Giersch #undef printmode 21548e75f744SArnaud Giersch printk("]\n"); 21558e75f744SArnaud Giersch 21568e75f744SArnaud Giersch parport_announce_port(p); 21578e75f744SArnaud Giersch return p; 21588e75f744SArnaud Giersch 21598e75f744SArnaud Giersch fail: 21608e75f744SArnaud Giersch if (p) 21618e75f744SArnaud Giersch parport_put_port(p); 21628e75f744SArnaud Giersch kfree(priv); 21638e75f744SArnaud Giersch kfree(ops); 21648e75f744SArnaud Giersch return ERR_PTR(err); 21658e75f744SArnaud Giersch } 21668e75f744SArnaud Giersch 21678e75f744SArnaud Giersch /** 21688e75f744SArnaud Giersch * parport_ip32_unregister_port - unregister a parallel port 21698e75f744SArnaud Giersch * @p: pointer to the &struct parport 21708e75f744SArnaud Giersch * 21718e75f744SArnaud Giersch * Unregisters a parallel port and free previously allocated resources 21728e75f744SArnaud Giersch * (memory, IRQ, ...). 21738e75f744SArnaud Giersch */ 21748e75f744SArnaud Giersch static __exit void parport_ip32_unregister_port(struct parport *p) 21758e75f744SArnaud Giersch { 21768e75f744SArnaud Giersch struct parport_ip32_private * const priv = p->physport->private_data; 21778e75f744SArnaud Giersch struct parport_operations *ops = p->ops; 21788e75f744SArnaud Giersch 21798e75f744SArnaud Giersch parport_remove_port(p); 21808e75f744SArnaud Giersch if (p->modes & PARPORT_MODE_DMA) 21818e75f744SArnaud Giersch parport_ip32_dma_unregister(); 21828e75f744SArnaud Giersch if (p->irq != PARPORT_IRQ_NONE) 21838e75f744SArnaud Giersch free_irq(p->irq, p); 21848e75f744SArnaud Giersch parport_put_port(p); 21858e75f744SArnaud Giersch kfree(priv); 21868e75f744SArnaud Giersch kfree(ops); 21878e75f744SArnaud Giersch } 21888e75f744SArnaud Giersch 21898e75f744SArnaud Giersch /** 21908e75f744SArnaud Giersch * parport_ip32_init - module initialization function 21918e75f744SArnaud Giersch */ 21928e75f744SArnaud Giersch static int __init parport_ip32_init(void) 21938e75f744SArnaud Giersch { 21948e75f744SArnaud Giersch pr_info(PPIP32 "SGI IP32 built-in parallel port driver v0.6\n"); 21958e75f744SArnaud Giersch this_port = parport_ip32_probe_port(); 2196340f365dSFabian Frederick return PTR_ERR_OR_ZERO(this_port); 21978e75f744SArnaud Giersch } 21988e75f744SArnaud Giersch 21998e75f744SArnaud Giersch /** 22008e75f744SArnaud Giersch * parport_ip32_exit - module termination function 22018e75f744SArnaud Giersch */ 22028e75f744SArnaud Giersch static void __exit parport_ip32_exit(void) 22038e75f744SArnaud Giersch { 22048e75f744SArnaud Giersch parport_ip32_unregister_port(this_port); 22058e75f744SArnaud Giersch } 22068e75f744SArnaud Giersch 22078e75f744SArnaud Giersch /*--- Module stuff -----------------------------------------------------*/ 22088e75f744SArnaud Giersch 22098e75f744SArnaud Giersch MODULE_AUTHOR("Arnaud Giersch <arnaud.giersch@free.fr>"); 22108e75f744SArnaud Giersch MODULE_DESCRIPTION("SGI IP32 built-in parallel port driver"); 22118e75f744SArnaud Giersch MODULE_LICENSE("GPL"); 22128e75f744SArnaud Giersch MODULE_VERSION("0.6"); /* update in parport_ip32_init() too */ 22138e75f744SArnaud Giersch 22148e75f744SArnaud Giersch module_init(parport_ip32_init); 22158e75f744SArnaud Giersch module_exit(parport_ip32_exit); 22168e75f744SArnaud Giersch 22178e75f744SArnaud Giersch module_param(verbose_probing, bool, S_IRUGO); 22188e75f744SArnaud Giersch MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialization"); 22198e75f744SArnaud Giersch 22208e75f744SArnaud Giersch module_param(features, uint, S_IRUGO); 22218e75f744SArnaud Giersch MODULE_PARM_DESC(features, 22228e75f744SArnaud Giersch "Bit mask of features to enable" 22238e75f744SArnaud Giersch ", bit 0: IRQ support" 22248e75f744SArnaud Giersch ", bit 1: DMA support" 22258e75f744SArnaud Giersch ", bit 2: hardware SPP mode" 22268e75f744SArnaud Giersch ", bit 3: hardware EPP mode" 22278e75f744SArnaud Giersch ", bit 4: hardware ECP mode"); 22288e75f744SArnaud Giersch 22298e75f744SArnaud Giersch /*--- Inform (X)Emacs about preferred coding style ---------------------*/ 22308e75f744SArnaud Giersch /* 22318e75f744SArnaud Giersch * Local Variables: 22328e75f744SArnaud Giersch * mode: c 22338e75f744SArnaud Giersch * c-file-style: "linux" 22348e75f744SArnaud Giersch * indent-tabs-mode: t 22358e75f744SArnaud Giersch * tab-width: 8 22368e75f744SArnaud Giersch * fill-column: 78 22378e75f744SArnaud Giersch * ispell-local-dictionary: "american" 22388e75f744SArnaud Giersch * End: 22398e75f744SArnaud Giersch */ 2240