diff options
Diffstat (limited to 'drivers/pcmcia/sa1111_generic.c')
| -rw-r--r-- | drivers/pcmcia/sa1111_generic.c | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 65b02c3e14ce..2a67e33fb5f0 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * linux/drivers/pcmcia/sa1111_generic.c * @@ -16,8 +17,8 @@ #include <pcmcia/ss.h> -#include <mach/hardware.h> #include <asm/hardware/sa1111.h> +#include <asm/mach-types.h> #include <asm/irq.h> #include "sa1111_generic.h" @@ -62,11 +63,12 @@ #define IDX_IRQ_S1_READY_NINT (3) #define IDX_IRQ_S1_CD_VALID (4) #define IDX_IRQ_S1_BVD1_STSCHG (5) +#define NUM_IRQS (6) void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { struct sa1111_pcmcia_socket *s = to_skt(skt); - unsigned long status = sa1111_readl(s->dev->mapbase + PCSR); + u32 status = readl_relaxed(s->dev->mapbase + PCSR); switch (skt->nr) { case 0: @@ -94,7 +96,7 @@ void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_sta int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) { struct sa1111_pcmcia_socket *s = to_skt(skt); - unsigned int pccr_skt_mask, pccr_set_mask, val; + u32 pccr_skt_mask, pccr_set_mask, val; unsigned long flags; switch (skt->nr) { @@ -122,10 +124,10 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; local_irq_save(flags); - val = sa1111_readl(s->dev->mapbase + PCCR); + val = readl_relaxed(s->dev->mapbase + PCCR); val &= ~pccr_skt_mask; val |= pccr_set_mask & pccr_skt_mask; - sa1111_writel(val, s->dev->mapbase + PCCR); + writel_relaxed(val, s->dev->mapbase + PCCR); local_irq_restore(flags); return 0; @@ -135,7 +137,18 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, int (*add)(struct soc_pcmcia_socket *)) { struct sa1111_pcmcia_socket *s; - int i, ret = 0; + struct clk *clk; + int i, ret = 0, irqs[NUM_IRQS]; + + clk = devm_clk_get(&dev->dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + for (i = 0; i < NUM_IRQS; i++) { + irqs[i] = sa1111_get_irq(dev, i); + if (irqs[i] <= 0) + return irqs[i] ? : -ENXIO; + } ops->socket_state = sa1111_pcmcia_socket_state; @@ -145,19 +158,21 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, return -ENOMEM; s->soc.nr = ops->first + i; + s->soc.clk = clk; + soc_pcmcia_init_one(&s->soc, ops, &dev->dev); s->dev = dev; if (s->soc.nr) { - s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S1_READY_NINT]; - s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S1_CD_VALID]; + s->soc.socket.pci_irq = irqs[IDX_IRQ_S1_READY_NINT]; + s->soc.stat[SOC_STAT_CD].irq = irqs[IDX_IRQ_S1_CD_VALID]; s->soc.stat[SOC_STAT_CD].name = "SA1111 CF card detect"; - s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG]; + s->soc.stat[SOC_STAT_BVD1].irq = irqs[IDX_IRQ_S1_BVD1_STSCHG]; s->soc.stat[SOC_STAT_BVD1].name = "SA1111 CF BVD1"; } else { - s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S0_READY_NINT]; - s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S0_CD_VALID]; + s->soc.socket.pci_irq = irqs[IDX_IRQ_S0_READY_NINT]; + s->soc.stat[SOC_STAT_CD].irq = irqs[IDX_IRQ_S0_CD_VALID]; s->soc.stat[SOC_STAT_CD].name = "SA1111 PCMCIA card detect"; - s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG]; + s->soc.stat[SOC_STAT_BVD1].irq = irqs[IDX_IRQ_S0_BVD1_STSCHG]; s->soc.stat[SOC_STAT_BVD1].name = "SA1111 PCMCIA BVD1"; } @@ -193,25 +208,28 @@ static int pcmcia_probe(struct sa1111_dev *dev) /* * Initialise the suspend state. */ - sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR); - sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); + writel_relaxed(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR); + writel_relaxed(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); -#ifdef CONFIG_SA1100_BADGE4 - pcmcia_badge4_init(&dev->dev); -#endif + ret = -ENODEV; #ifdef CONFIG_SA1100_JORNADA720 - pcmcia_jornada720_init(&dev->dev); -#endif -#ifdef CONFIG_ARCH_LUBBOCK - pcmcia_lubbock_init(dev); + if (machine_is_jornada720()) + ret = pcmcia_jornada720_init(dev); #endif #ifdef CONFIG_ASSABET_NEPONSET - pcmcia_neponset_init(dev); + if (machine_is_assabet()) + ret = pcmcia_neponset_init(dev); #endif - return 0; + + if (ret) { + release_mem_region(dev->res.start, 512); + sa1111_disable_device(dev); + } + + return ret; } -static int pcmcia_remove(struct sa1111_dev *dev) +static void pcmcia_remove(struct sa1111_dev *dev) { struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev); @@ -225,7 +243,6 @@ static int pcmcia_remove(struct sa1111_dev *dev) release_mem_region(dev->res.start, 512); sa1111_disable_device(dev); - return 0; } static struct sa1111_driver pcmcia_driver = { |
