Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  *  linux/arch/m68k/atari/stmda.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *  Copyright (C) 1994 Roman Hodek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * License.  See the file COPYING in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) /* This file contains some function for controlling the access to the  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) /* ST-DMA chip that may be shared between devices. Currently we have:  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) /*   TT:     Floppy and ACSI bus                                       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) /*   Falcon: Floppy and SCSI                                           */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) /*                                                                     */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /* The controlling functions set up a wait queue for access to the     */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /* ST-DMA chip. Callers to stdma_lock() that cannot granted access are */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) /* put onto a queue and waked up later if the owner calls              */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) /* stdma_release(). Additionally, the caller gives his interrupt       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /* service routine to stdma_lock().                                    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /*                                                                     */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) /* On the Falcon, the IDE bus uses just the ACSI/Floppy interrupt, but */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) /* not the ST-DMA chip itself. So falhd.c needs not to lock the        */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /* chip. The interrupt is routed to falhd.c if IDE is configured, the  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /* model is a Falcon and the interrupt was caused by the HD controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /* (can be determined by looking at its status register).              */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/kdev_t.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/genhd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <asm/atari_stdma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <asm/atariints.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <asm/atarihw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static int stdma_locked;			/* the semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 						/* int func to be called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static irq_handler_t stdma_isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static void *stdma_isr_data;			/* data passed to isr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static DECLARE_WAIT_QUEUE_HEAD(stdma_wait);	/* wait queue for ST-DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) /***************************** Prototypes *****************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) static irqreturn_t stdma_int (int irq, void *dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) /************************* End of Prototypes **************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * stdma_try_lock - attempt to acquire ST DMA interrupt "lock"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * @handler: interrupt handler to use after acquisition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * Returns !0 if lock was acquired; otherwise 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) int stdma_try_lock(irq_handler_t handler, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (stdma_locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	stdma_locked   = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	stdma_isr      = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	stdma_isr_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) EXPORT_SYMBOL(stdma_try_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * Function: void stdma_lock( isrfunc isr, void *data )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * Purpose: Tries to get a lock on the ST-DMA chip that is used by more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  *   then one device driver. Waits on stdma_wait until lock is free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  *   stdma_lock() may not be called from an interrupt! You have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  *   get the lock in your main routine and release it when your
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  *   request is finished.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  * Inputs: A interrupt function that is called until the lock is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  *   released.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * Returns: nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) void stdma_lock(irq_handler_t handler, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	/* Since the DMA is used for file system purposes, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	 have to sleep uninterruptible (there may be locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	 buffers) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	wait_event(stdma_wait, stdma_try_lock(handler, data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) EXPORT_SYMBOL(stdma_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * Function: void stdma_release( void )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * Purpose: Releases the lock on the ST-DMA chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * Inputs: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * Returns: nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) void stdma_release(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	stdma_locked   = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	stdma_isr      = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	stdma_isr_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	wake_up(&stdma_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) EXPORT_SYMBOL(stdma_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * stdma_is_locked_by - allow lock holder to check whether it needs to release.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * @handler: interrupt handler previously used to acquire lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * Returns !0 if locked for the given handler; 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int stdma_is_locked_by(irq_handler_t handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	result = stdma_locked && (stdma_isr == handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) EXPORT_SYMBOL(stdma_is_locked_by);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * Function: int stdma_islocked( void )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  * Purpose: Check if the ST-DMA is currently locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * Note: Returned status is only valid if ints are disabled while calling and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  *       as long as they remain disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  *       If called with ints enabled, status can change only from locked to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  *       unlocked, because ints may not lock the ST-DMA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  * Inputs: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * Returns: != 0 if locked, 0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int stdma_islocked(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	return stdma_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) EXPORT_SYMBOL(stdma_islocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * Function: void stdma_init( void )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * Purpose: Initialize the ST-DMA chip access controlling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  *   It sets up the interrupt and its service routine. The int is registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  *   as slow int, client devices have to live with that (no problem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  *   currently).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * Inputs: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * Return: nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) void __init stdma_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	stdma_isr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (request_irq(IRQ_MFP_FDC, stdma_int, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			"ST-DMA floppy,ACSI,IDE,Falcon-SCSI", stdma_int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		pr_err("Couldn't register ST-DMA interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * Function: void stdma_int()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * Purpose: The interrupt routine for the ST-DMA. It calls the isr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  *   registered by stdma_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static irqreturn_t stdma_int(int irq, void *dummy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)   if (stdma_isr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)       (*stdma_isr)(irq, stdma_isr_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)   return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }