^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/drivers/pcmcia/sa1111_generic.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * We implement the generic parts of a SA1111 PCMCIA driver. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * basically means we handle everything except controlling the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * power. Power is machine specific...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.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/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <pcmcia/ss.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <mach/hardware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/hardware/sa1111.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/mach-types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "sa1111_generic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * These are offsets from the above base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PCCR 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PCSSR 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PCSR 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PCSR_S0_READY (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PCSR_S1_READY (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PCSR_S0_DETECT (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PCSR_S1_DETECT (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define PCSR_S0_VS1 (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PCSR_S0_VS2 (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PCSR_S1_VS1 (1<<6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define PCSR_S1_VS2 (1<<7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define PCSR_S0_WP (1<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define PCSR_S1_WP (1<<9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define PCSR_S0_BVD1 (1<<10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PCSR_S0_BVD2 (1<<11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PCSR_S1_BVD1 (1<<12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PCSR_S1_BVD2 (1<<13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define PCCR_S0_RST (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define PCCR_S1_RST (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define PCCR_S0_FLT (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PCCR_S1_FLT (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PCCR_S0_PWAITEN (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PCCR_S1_PWAITEN (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define PCCR_S0_PSE (1<<6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PCCR_S1_PSE (1<<7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define PCSSR_S0_SLEEP (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PCSSR_S1_SLEEP (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define IDX_IRQ_S0_READY_NINT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define IDX_IRQ_S0_CD_VALID (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define IDX_IRQ_S0_BVD1_STSCHG (2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define IDX_IRQ_S1_READY_NINT (3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define IDX_IRQ_S1_CD_VALID (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define IDX_IRQ_S1_BVD1_STSCHG (5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define NUM_IRQS (6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct sa1111_pcmcia_socket *s = to_skt(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) u32 status = readl_relaxed(s->dev->mapbase + PCSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) switch (skt->nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) state->detect = status & PCSR_S0_DETECT ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) state->ready = status & PCSR_S0_READY ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) state->bvd1 = status & PCSR_S0_BVD1 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) state->bvd2 = status & PCSR_S0_BVD2 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) state->wrprot = status & PCSR_S0_WP ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) state->vs_3v = status & PCSR_S0_VS1 ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) state->vs_Xv = status & PCSR_S0_VS2 ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) state->detect = status & PCSR_S1_DETECT ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) state->ready = status & PCSR_S1_READY ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) state->bvd1 = status & PCSR_S1_BVD1 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) state->bvd2 = status & PCSR_S1_BVD2 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) state->wrprot = status & PCSR_S1_WP ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) state->vs_3v = status & PCSR_S1_VS1 ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) state->vs_Xv = status & PCSR_S1_VS2 ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct sa1111_pcmcia_socket *s = to_skt(skt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u32 pccr_skt_mask, pccr_set_mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) switch (skt->nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) pccr_skt_mask = PCCR_S0_RST|PCCR_S0_FLT|PCCR_S0_PWAITEN|PCCR_S0_PSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) pccr_skt_mask = PCCR_S1_RST|PCCR_S1_FLT|PCCR_S1_PWAITEN|PCCR_S1_PSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) pccr_set_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (state->Vcc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) pccr_set_mask |= PCCR_S0_PWAITEN|PCCR_S1_PWAITEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (state->Vcc == 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pccr_set_mask |= PCCR_S0_PSE|PCCR_S1_PSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (state->flags & SS_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) pccr_set_mask |= PCCR_S0_RST|PCCR_S1_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (state->flags & SS_OUTPUT_ENA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) val = readl_relaxed(s->dev->mapbase + PCCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) val &= ~pccr_skt_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) val |= pccr_set_mask & pccr_skt_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) writel_relaxed(val, s->dev->mapbase + PCCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int (*add)(struct soc_pcmcia_socket *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct sa1111_pcmcia_socket *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int i, ret = 0, irqs[NUM_IRQS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) clk = devm_clk_get(&dev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) for (i = 0; i < NUM_IRQS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) irqs[i] = sa1111_get_irq(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (irqs[i] <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return irqs[i] ? : -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ops->socket_state = sa1111_pcmcia_socket_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) for (i = 0; i < ops->nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) s = kzalloc(sizeof(*s), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) s->soc.nr = ops->first + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) s->soc.clk = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) soc_pcmcia_init_one(&s->soc, ops, &dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) s->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (s->soc.nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) s->soc.socket.pci_irq = irqs[IDX_IRQ_S1_READY_NINT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) s->soc.stat[SOC_STAT_CD].irq = irqs[IDX_IRQ_S1_CD_VALID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) s->soc.stat[SOC_STAT_CD].name = "SA1111 CF card detect";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) s->soc.stat[SOC_STAT_BVD1].irq = irqs[IDX_IRQ_S1_BVD1_STSCHG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) s->soc.stat[SOC_STAT_BVD1].name = "SA1111 CF BVD1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) s->soc.socket.pci_irq = irqs[IDX_IRQ_S0_READY_NINT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) s->soc.stat[SOC_STAT_CD].irq = irqs[IDX_IRQ_S0_CD_VALID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) s->soc.stat[SOC_STAT_CD].name = "SA1111 PCMCIA card detect";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) s->soc.stat[SOC_STAT_BVD1].irq = irqs[IDX_IRQ_S0_BVD1_STSCHG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) s->soc.stat[SOC_STAT_BVD1].name = "SA1111 PCMCIA BVD1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ret = add(&s->soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) s->next = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) dev_set_drvdata(&dev->dev, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) kfree(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int pcmcia_probe(struct sa1111_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ret = sa1111_enable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) dev_set_drvdata(&dev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sa1111_disable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return -EBUSY;
^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) base = dev->mapbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Initialise the suspend state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) writel_relaxed(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) writel_relaxed(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #ifdef CONFIG_SA1100_BADGE4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (machine_is_badge4())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ret = pcmcia_badge4_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #ifdef CONFIG_SA1100_JORNADA720
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (machine_is_jornada720())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ret = pcmcia_jornada720_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #ifdef CONFIG_ARCH_LUBBOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (machine_is_lubbock())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ret = pcmcia_lubbock_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #ifdef CONFIG_ASSABET_NEPONSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (machine_is_assabet())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ret = pcmcia_neponset_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) release_mem_region(dev->res.start, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) sa1111_disable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int pcmcia_remove(struct sa1111_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) dev_set_drvdata(&dev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) for (; s; s = next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) next = s->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) soc_pcmcia_remove_one(&s->soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) kfree(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) release_mem_region(dev->res.start, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) sa1111_disable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static struct sa1111_driver pcmcia_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .name = "sa1111-pcmcia",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .devid = SA1111_DEVID_PCMCIA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .probe = pcmcia_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .remove = pcmcia_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static int __init sa1111_drv_pcmcia_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return sa1111_driver_register(&pcmcia_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static void __exit sa1111_drv_pcmcia_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) sa1111_driver_unregister(&pcmcia_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) fs_initcall(sa1111_drv_pcmcia_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) module_exit(sa1111_drv_pcmcia_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) MODULE_DESCRIPTION("SA1111 PCMCIA card socket driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) MODULE_LICENSE("GPL");