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)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <bcm63xx_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <bcm63xx_io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "bcm63xx_pcmcia.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define PFX	"bcm63xx_pcmcia: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #ifdef CONFIG_CARDBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /* if cardbus is used, platform device needs reference to actual pci
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static struct pci_dev *bcm63xx_cb_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * read/write helper for pcmcia regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static inline u32 pcmcia_readl(struct bcm63xx_pcmcia_socket *skt, u32 off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	return bcm_readl(skt->base + off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static inline void pcmcia_writel(struct bcm63xx_pcmcia_socket *skt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 				 u32 val, u32 off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	bcm_writel(val, skt->base + off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * This callback should (re-)initialise the socket, turn on status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * interrupts and PCMCIA bus, and wait for power to stabilise so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * the card status signals report correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * Hardware cannot do that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static int bcm63xx_pcmcia_sock_init(struct pcmcia_socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * This callback should remove power on the socket, disable IRQs from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * the card, turn off status interrupts, and disable the PCMCIA bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * Hardware cannot do that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) static int bcm63xx_pcmcia_suspend(struct pcmcia_socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) }
^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)  * Implements the set_socket() operation for the in-kernel PCMCIA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * service (formerly SS_SetSocket in Card Services). We more or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * less punt all of this work and let the kernel handle the details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * of power configuration, reset, &c. We also record the value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * `state' in order to regurgitate it to the PCMCIA core later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static int bcm63xx_pcmcia_set_socket(struct pcmcia_socket *sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 				     socket_state_t *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct bcm63xx_pcmcia_socket *skt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	skt = sock->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	spin_lock_irqsave(&skt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	/* note: hardware cannot control socket power, so we will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	 * always report SS_POWERON */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	/* apply socket reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	val = pcmcia_readl(skt, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (state->flags & SS_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		val |= PCMCIA_C1_RESET_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		val &= ~PCMCIA_C1_RESET_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	/* reverse reset logic for cardbus card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (skt->card_detected && (skt->card_type & CARD_CARDBUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		val ^= PCMCIA_C1_RESET_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	pcmcia_writel(skt, val, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	/* keep requested state for event reporting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	skt->requested_state = *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	spin_unlock_irqrestore(&skt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * identity cardtype from VS[12] input, CD[12] input while only VS2 is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * floating, and CD[12] input while only VS1 is floating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	IN_VS1 = (1 << 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	IN_VS2 = (1 << 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	IN_CD1_VS2H = (1 << 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	IN_CD2_VS2H = (1 << 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	IN_CD1_VS1H = (1 << 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	IN_CD2_VS1H = (1 << 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static const u8 vscd_to_cardtype[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	/* VS1 float, VS2 float */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	[IN_VS1 | IN_VS2] = (CARD_PCCARD | CARD_5V),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	/* VS1 grounded, VS2 float */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	[IN_VS2] = (CARD_PCCARD | CARD_5V | CARD_3V),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/* VS1 grounded, VS2 grounded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	[0] = (CARD_PCCARD | CARD_5V | CARD_3V | CARD_XV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	/* VS1 tied to CD1, VS2 float */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	[IN_VS1 | IN_VS2 | IN_CD1_VS1H] = (CARD_CARDBUS | CARD_3V),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	/* VS1 grounded, VS2 tied to CD2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	[IN_VS2 | IN_CD2_VS2H] = (CARD_CARDBUS | CARD_3V | CARD_XV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	/* VS1 tied to CD2, VS2 grounded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	[IN_VS1 | IN_CD2_VS1H] = (CARD_CARDBUS | CARD_3V | CARD_XV | CARD_YV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	/* VS1 float, VS2 grounded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	[IN_VS1] = (CARD_PCCARD | CARD_XV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	/* VS1 float, VS2 tied to CD2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	[IN_VS1 | IN_VS2 | IN_CD2_VS2H] = (CARD_CARDBUS | CARD_3V),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	/* VS1 float, VS2 tied to CD1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	[IN_VS1 | IN_VS2 | IN_CD1_VS2H] = (CARD_CARDBUS | CARD_XV | CARD_YV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	/* VS1 tied to CD2, VS2 float */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	[IN_VS1 | IN_VS2 | IN_CD2_VS1H] = (CARD_CARDBUS | CARD_YV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	/* VS2 grounded, VS1 is tied to CD1, CD2 is grounded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	[IN_VS1 | IN_CD1_VS1H] = 0, /* ignore cardbay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * poll hardware to check card insertion status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static unsigned int __get_socket_status(struct bcm63xx_pcmcia_socket *skt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	unsigned int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	/* check CD for card presence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	val = pcmcia_readl(skt, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (!(val & PCMCIA_C1_CD1_MASK) && !(val & PCMCIA_C1_CD2_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		stat |= SS_DETECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	/* if new insertion, detect cardtype */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	if ((stat & SS_DETECT) && !skt->card_detected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		unsigned int stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		/* float VS1, float VS2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		val |= PCMCIA_C1_VS1OE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		val |= PCMCIA_C1_VS2OE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		pcmcia_writel(skt, val, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		/* wait for output to stabilize and read VS[12] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		val = pcmcia_readl(skt, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		stat |= (val & PCMCIA_C1_VS1_MASK) ? IN_VS1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		stat |= (val & PCMCIA_C1_VS2_MASK) ? IN_VS2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		/* drive VS1 low, float VS2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		val &= ~PCMCIA_C1_VS1OE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		val |= PCMCIA_C1_VS2OE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		pcmcia_writel(skt, val, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		/* wait for output to stabilize and read CD[12] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		val = pcmcia_readl(skt, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS2H : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS2H : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		/* float VS1, drive VS2 low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		val |= PCMCIA_C1_VS1OE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		val &= ~PCMCIA_C1_VS2OE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		pcmcia_writel(skt, val, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		/* wait for output to stabilize and read CD[12] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		val = pcmcia_readl(skt, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS1H : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS1H : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		/* guess cardtype from all this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		skt->card_type = vscd_to_cardtype[stat];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		if (!skt->card_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			dev_err(&skt->socket.dev, "unsupported card type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		/* drive both VS pin to 0 again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		val &= ~(PCMCIA_C1_VS1OE_MASK | PCMCIA_C1_VS2OE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		/* enable correct logic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		val &= ~(PCMCIA_C1_EN_PCMCIA_MASK | PCMCIA_C1_EN_CARDBUS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		if (skt->card_type & CARD_PCCARD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			val |= PCMCIA_C1_EN_PCMCIA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			val |= PCMCIA_C1_EN_CARDBUS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		pcmcia_writel(skt, val, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	skt->card_detected = (stat & SS_DETECT) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	/* report card type/voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (skt->card_type & CARD_CARDBUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		stat |= SS_CARDBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (skt->card_type & CARD_3V)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		stat |= SS_3VCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (skt->card_type & CARD_XV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		stat |= SS_XVCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	stat |= SS_POWERON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (gpio_get_value(skt->pd->ready_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		stat |= SS_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * core request to get current socket status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int bcm63xx_pcmcia_get_status(struct pcmcia_socket *sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				     unsigned int *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	struct bcm63xx_pcmcia_socket *skt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	skt = sock->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	spin_lock_bh(&skt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	*status = __get_socket_status(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	spin_unlock_bh(&skt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  * socket polling timer callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static void bcm63xx_pcmcia_poll(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	struct bcm63xx_pcmcia_socket *skt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	unsigned int stat, events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	skt = from_timer(skt, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	spin_lock_bh(&skt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	stat = __get_socket_status(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	/* keep only changed bits, and mask with required one from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	 * core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	events = (stat ^ skt->old_status) & skt->requested_state.csc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	skt->old_status = stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	spin_unlock_bh(&skt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		pcmcia_parse_events(&skt->socket, events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	mod_timer(&skt->timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		  jiffies + msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int bcm63xx_pcmcia_set_io_map(struct pcmcia_socket *sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 				     struct pccard_io_map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	/* this doesn't seem to be called by pcmcia layer if static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	 * mapping is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int bcm63xx_pcmcia_set_mem_map(struct pcmcia_socket *sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 				      struct pccard_mem_map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	struct bcm63xx_pcmcia_socket *skt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	skt = sock->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	if (map->flags & MAP_ATTRIB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		res = skt->attr_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		res = skt->common_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	map->static_start = res->start + map->card_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static struct pccard_operations bcm63xx_pcmcia_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	.init			= bcm63xx_pcmcia_sock_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	.suspend		= bcm63xx_pcmcia_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	.get_status		= bcm63xx_pcmcia_get_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	.set_socket		= bcm63xx_pcmcia_set_socket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	.set_io_map		= bcm63xx_pcmcia_set_io_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	.set_mem_map		= bcm63xx_pcmcia_set_mem_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  * register pcmcia socket to core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static int bcm63xx_drv_pcmcia_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	struct bcm63xx_pcmcia_socket *skt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	struct pcmcia_socket *sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	struct resource *res, *irq_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	unsigned int regmem_size = 0, iomem_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	skt = kzalloc(sizeof(*skt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (!skt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	spin_lock_init(&skt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	sock = &skt->socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	sock->driver_data = skt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	/* make sure we have all resources we need */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	skt->common_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	skt->attr_res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	skt->pd = pdev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	if (!skt->common_res || !skt->attr_res || !irq_res || !skt->pd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	/* remap pcmcia registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	regmem_size = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if (!request_mem_region(res->start, regmem_size, "bcm63xx_pcmcia")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	skt->reg_res = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	skt->base = ioremap(res->start, regmem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	if (!skt->base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	/* remap io registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	iomem_size = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	skt->io_base = ioremap(res->start, iomem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (!skt->io_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	/* resources are static */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	sock->resource_ops = &pccard_static_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	sock->ops = &bcm63xx_pcmcia_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	sock->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	sock->dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	sock->features = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	sock->io_offset = (unsigned long)skt->io_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	sock->pci_irq = irq_res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #ifdef CONFIG_CARDBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	sock->cb_dev = bcm63xx_cb_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	if (bcm63xx_cb_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		sock->features |= SS_CAP_CARDBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	/* assume common & attribute memory have the same size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	sock->map_size = resource_size(skt->common_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	/* initialize polling timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	timer_setup(&skt->timer, bcm63xx_pcmcia_poll, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	/* initialize  pcmcia  control register,  drive  VS[12] to  0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	 * leave CB IDSEL to the old  value since it is set by the PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	 * layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	val = pcmcia_readl(skt, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	val &= PCMCIA_C1_CBIDSEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	val |= PCMCIA_C1_EN_PCMCIA_GPIO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	pcmcia_writel(skt, val, PCMCIA_C1_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	 * Hardware has only one set of timings registers, not one for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	 * each memory access type, so we configure them for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	 * slowest one: attribute memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	val = PCMCIA_C2_DATA16_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	val |= 10 << PCMCIA_C2_RWCOUNT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	val |= 6 << PCMCIA_C2_INACTIVE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	val |= 3 << PCMCIA_C2_SETUP_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	val |= 3 << PCMCIA_C2_HOLD_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	pcmcia_writel(skt, val, PCMCIA_C2_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	ret = pcmcia_register_socket(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	/* start polling socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	mod_timer(&skt->timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		  jiffies + msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	platform_set_drvdata(pdev, skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (skt->io_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		iounmap(skt->io_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	if (skt->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		iounmap(skt->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	if (skt->reg_res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		release_mem_region(skt->reg_res->start, regmem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	kfree(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static int bcm63xx_drv_pcmcia_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	struct bcm63xx_pcmcia_socket *skt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	skt = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	del_timer_sync(&skt->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	iounmap(skt->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	iounmap(skt->io_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	res = skt->reg_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	release_mem_region(res->start, resource_size(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	kfree(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct platform_driver bcm63xx_pcmcia_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	.probe	= bcm63xx_drv_pcmcia_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	.remove	= bcm63xx_drv_pcmcia_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	.driver	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		.name	= "bcm63xx_pcmcia",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		.owner  = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) #ifdef CONFIG_CARDBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static int bcm63xx_cb_probe(struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 				      const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	/* keep pci device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	bcm63xx_cb_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	return platform_driver_register(&bcm63xx_pcmcia_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static void bcm63xx_cb_exit(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	platform_driver_unregister(&bcm63xx_pcmcia_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	bcm63xx_cb_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static const struct pci_device_id bcm63xx_cb_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		.vendor		= PCI_VENDOR_ID_BROADCOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		.device		= BCM6348_CPU_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		.subvendor	= PCI_VENDOR_ID_BROADCOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		.subdevice	= PCI_ANY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		.class		= PCI_CLASS_BRIDGE_CARDBUS << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		.class_mask	= ~0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		.vendor		= PCI_VENDOR_ID_BROADCOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		.device		= BCM6358_CPU_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		.subvendor	= PCI_VENDOR_ID_BROADCOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		.subdevice	= PCI_ANY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		.class		= PCI_CLASS_BRIDGE_CARDBUS << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		.class_mask	= ~0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) MODULE_DEVICE_TABLE(pci, bcm63xx_cb_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static struct pci_driver bcm63xx_cardbus_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	.name		= "bcm63xx_cardbus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	.id_table	= bcm63xx_cb_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	.probe		= bcm63xx_cb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	.remove		= bcm63xx_cb_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)  * if cardbus support is enabled, register our platform device after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)  * our fake cardbus bridge has been registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static int __init bcm63xx_pcmcia_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) #ifdef CONFIG_CARDBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	return pci_register_driver(&bcm63xx_cardbus_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	return platform_driver_register(&bcm63xx_pcmcia_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static void __exit bcm63xx_pcmcia_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #ifdef CONFIG_CARDBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	return pci_unregister_driver(&bcm63xx_cardbus_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	platform_driver_unregister(&bcm63xx_pcmcia_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) module_init(bcm63xx_pcmcia_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) module_exit(bcm63xx_pcmcia_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm63xx Socket Controller");