Module Name:    src
Committed By:   jdc
Date:           Fri Jun 11 04:58:30 UTC 2021

Modified Files:
        src/sys/arch/sparc/dev: ts102.c

Log Message:
During slot enable and disable, make sure that the card Access and VCC
controls are enabled and disabled at the same time.
Also remove the software reset during slot enable (we are already in
reset because of the earlier Access and VCC changes).
While here, convert DELAY() to delay() and tsleep(), like nell(4).


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/sparc/dev/ts102.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sparc/dev/ts102.c
diff -u src/sys/arch/sparc/dev/ts102.c:1.19 src/sys/arch/sparc/dev/ts102.c:1.20
--- src/sys/arch/sparc/dev/ts102.c:1.19	Sat Apr 24 23:36:49 2021
+++ src/sys/arch/sparc/dev/ts102.c	Fri Jun 11 04:58:30 2021
@@ -1,5 +1,5 @@
 /*	$OpenBSD: ts102.c,v 1.14 2005/01/27 17:03:23 millert Exp $	*/
-/*	$NetBSD: ts102.c,v 1.19 2021/04/24 23:36:49 thorpej Exp $ */
+/*	$NetBSD: ts102.c,v 1.20 2021/06/11 04:58:30 jdc Exp $ */
 /*
  * Copyright (c) 2003, 2004, Miodrag Vallat.
  * Copyright (c) 2005, Michael Lorenz.
@@ -182,6 +182,7 @@ static void tslot_slot_intr(struct tslot
 static void tslot_slot_settype(pcmcia_chipset_handle_t, int);
 static void tslot_update_lcd(struct tslot_softc *, int, int);
 static void tslot_intr_dispatch(void *arg);
+void tslot_delay(struct tslot_softc *sc, unsigned int ms);
 
 CFATTACH_DECL_NEW(tslot, sizeof(struct tslot_softc),
     tslot_match, tslot_attach, NULL, NULL);
@@ -620,22 +621,35 @@ static void
 tslot_slot_disable(pcmcia_chipset_handle_t pch)
 {
 	struct tslot_data *td = (struct tslot_data *)pch;
+	int status;
+
 #ifdef TSLOT_DEBUG
 	printf("%s: disable slot %d\n",
 	    device_xname(td->td_parent->sc_dev), td->td_slot);
 #endif
 
-	/*
-	 * Disable card access.
-	 */
-	TSLOT_WRITE(td, TS102_REG_CARD_A_STS,
-	    TSLOT_READ(td, TS102_REG_CARD_A_STS) & ~TS102_CARD_STS_ACEN);
+	status = TSLOT_READ(td, TS102_REG_CARD_A_STS);
+
+	status &= ~TS102_CARD_STS_ACEN;
 
 	/*
 	 * Disable interrupts, except for insertion.
 	 */
 	TSLOT_WRITE(td, TS102_REG_CARD_A_INT,
 	    TS102_CARD_INT_MASK_CARDDETECT_STATUS);
+
+	/*
+	 * Power down the socket and disable access
+	 */
+	status &= ~TS102_CARD_STS_ACEN;
+	status &= ~(TS102_CARD_STS_VPP1_MASK | TS102_CARD_STS_VPP2_MASK);
+	status |= TS102_CARD_STS_VCCEN;
+	TSLOT_WRITE(td, TS102_REG_CARD_A_STS, status);
+	
+	/*
+	 * wait 300ms until power fails (Tpf).
+	 */
+	tslot_delay(td->td_parent, 300);
 }
 
 static void
@@ -652,18 +666,23 @@ tslot_slot_enable(pcmcia_chipset_handle_
 	/* Power down the socket to reset it */
 	status = TSLOT_READ(td, TS102_REG_CARD_A_STS);
 	TSPRINTF("status: %x\n", status);
-	TSLOT_WRITE(td, TS102_REG_CARD_A_STS, status | TS102_CARD_STS_VCCEN);
+
+	status &= ~TS102_CARD_STS_ACEN;
+	status &= ~(TS102_CARD_STS_VPP1_MASK | TS102_CARD_STS_VPP2_MASK);
+	status |= TS102_CARD_STS_VCCEN;
+	TSLOT_WRITE(td, TS102_REG_CARD_A_STS, status);
 
 	/*
 	 * wait 300ms until power fails (Tpf).  Then, wait 100ms since we
 	 * are changing Vcc (Toff).
 	 */
-	DELAY((300 + 100) * 1000);
+	tslot_delay(td->td_parent, 300 + 100);
 
 	/*
 	 * Power on the card if not already done, and enable card access
 	 */
 	status |= TS102_CARD_STS_ACEN;
+	status |= TS102_CARD_STS_VPP1_VCC;
 	status &= ~TS102_CARD_STS_VCCEN;
 	TSLOT_WRITE(td, TS102_REG_CARD_A_STS, status);
 
@@ -671,22 +690,18 @@ tslot_slot_enable(pcmcia_chipset_handle_
 	 * wait 100ms until power raise (Tpr) and 20ms to become
 	 * stable (Tsu(Vcc)).
 	 */
-	DELAY((100 + 20) * 1000);
-
-	status &= ~TS102_CARD_STS_VPP1_MASK;
-	status |= TS102_CARD_STS_VPP1_VCC;
-	TSLOT_WRITE(td, TS102_REG_CARD_A_STS, status);
+	tslot_delay(td->td_parent, 100 + 20);
 
 	/*
 	 * hold RESET at least 20us.
 	 */
 	intr = TSLOT_READ(td, TS102_REG_CARD_A_INT);
-	TSLOT_WRITE(td, TS102_REG_CARD_A_INT, TS102_CARD_INT_SOFT_RESET);
-	DELAY(20);
-	TSLOT_WRITE(td, TS102_REG_CARD_A_INT, intr);
+	delay(20);
+	TSLOT_WRITE(td, TS102_REG_CARD_A_INT,
+	    intr & ~TS102_CARD_INT_SOFT_RESET);
 
 	/* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
-	DELAY(20 * 1000);
+	tslot_delay(td->td_parent, 20);
 
 	/* We need level-triggered interrupts for PC Card hardware */
 	TSLOT_WRITE(td, TS102_REG_CARD_A_STS,
@@ -709,7 +724,7 @@ tslot_slot_enable(pcmcia_chipset_handle_
 		if (status & TS102_CARD_STS_RDY)
 			break;
 		else
-			DELAY(100);
+			delay(100);
 	}
 
 	if (i == 0) {
@@ -1020,3 +1035,24 @@ tslot_update_lcd(struct tslot_softc *sc,
 	}
 #endif
 }
+
+/*
+ * Delay and possibly yield CPU.
+ * XXX - assumes a context
+ */
+void
+tslot_delay(struct tslot_softc *sc, unsigned int ms)
+{
+	unsigned int ticks = mstohz(ms);
+
+	if (cold || ticks == 0) {
+		delay(ms);
+		return;
+	}
+
+#ifdef DIAGNOSTIC
+	if (ticks > 60*hz)
+		panic("tslot: preposterous delay: %u", ticks);
+#endif
+	tsleep(sc, 0, "tslotdel", ticks);
+}

Reply via email to