diff options
Diffstat (limited to 'drivers/pcmcia/soc_common.c')
| -rw-r--r-- | drivers/pcmcia/soc_common.c | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index b6b316de055c..87aa3f667117 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -46,8 +46,7 @@ #include <linux/regulator/consumer.h> #include <linux/spinlock.h> #include <linux/timer.h> - -#include <mach/hardware.h> +#include <linux/pci.h> #include "soc_common.h" @@ -191,24 +190,22 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret = 0, i; - clk_prepare_enable(skt->clk); + ret = clk_prepare_enable(skt->clk); + if (ret) + return ret; if (skt->ops->hw_init) { ret = skt->ops->hw_init(skt); - if (ret) + if (ret) { + clk_disable_unprepare(skt->clk); return ret; + } } for (i = 0; i < ARRAY_SIZE(skt->stat); i++) { if (gpio_is_valid(skt->stat[i].gpio)) { - unsigned long flags = GPIOF_IN; - - /* CD is active low by default */ - if (i == SOC_STAT_CD) - flags |= GPIOF_ACTIVE_LOW; - ret = devm_gpio_request_one(skt->socket.dev.parent, - skt->stat[i].gpio, flags, + skt->stat[i].gpio, GPIOF_IN, skt->stat[i].name); if (ret) { __soc_pcmcia_hw_shutdown(skt, i); @@ -216,6 +213,10 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) } skt->stat[i].desc = gpio_to_desc(skt->stat[i].gpio); + + /* CD is active low by default */ + if ((i == SOC_STAT_CD) ^ gpiod_is_active_low(skt->stat[i].desc)) + gpiod_toggle_active_low(skt->stat[i].desc); } if (i < SOC_STAT_VS1 && skt->stat[i].desc) { @@ -347,19 +348,20 @@ static int soc_common_pcmcia_config_skt( if (ret == 0) { struct gpio_desc *descs[2]; - int values[2], n = 0; + DECLARE_BITMAP(values, 2); + int n = 0; if (skt->gpio_reset) { descs[n] = skt->gpio_reset; - values[n++] = !!(state->flags & SS_RESET); + __assign_bit(n++, values, state->flags & SS_RESET); } if (skt->gpio_bus_enable) { descs[n] = skt->gpio_bus_enable; - values[n++] = !!(state->flags & SS_OUTPUT_ENA); + __assign_bit(n++, values, state->flags & SS_OUTPUT_ENA); } if (n) - gpiod_set_array_value_cansleep(n, descs, values); + gpiod_set_array_value_cansleep(n, descs, NULL, values); /* * This really needs a better solution. The IRQ @@ -456,9 +458,9 @@ static void soc_common_check_status(struct soc_pcmcia_socket *skt) } /* Let's poll for events in addition to IRQs since IRQ only is unreliable... */ -static void soc_common_pcmcia_poll_event(unsigned long dummy) +static void soc_common_pcmcia_poll_event(struct timer_list *t) { - struct soc_pcmcia_socket *skt = (struct soc_pcmcia_socket *)dummy; + struct soc_pcmcia_socket *skt = timer_container_of(skt, t, poll_timer); debug(skt, 4, "polling for events\n"); mod_timer(&skt->poll_timer, jiffies + SOC_PCMCIA_POLL_PERIOD); @@ -764,7 +766,7 @@ EXPORT_SYMBOL(soc_pcmcia_init_one); void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) { - del_timer_sync(&skt->poll_timer); + timer_delete_sync(&skt->poll_timer); pcmcia_unregister_socket(&skt->socket); @@ -779,8 +781,7 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) /* should not be required; violates some lowlevel drivers */ soc_common_pcmcia_config_skt(skt, &dead_socket); - iounmap(skt->virt_io); - skt->virt_io = NULL; + iounmap(PCI_IOBASE + skt->res_io_io.start); release_resource(&skt->res_attr); release_resource(&skt->res_mem); release_resource(&skt->res_io); @@ -794,8 +795,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) skt->cs_state = dead_socket; - setup_timer(&skt->poll_timer, soc_common_pcmcia_poll_event, - (unsigned long)skt); + timer_setup(&skt->poll_timer, soc_common_pcmcia_poll_event, 0); skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD; ret = request_resource(&iomem_resource, &skt->res_skt); @@ -814,11 +814,12 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) if (ret) goto out_err_4; - skt->virt_io = ioremap(skt->res_io.start, 0x10000); - if (skt->virt_io == NULL) { - ret = -ENOMEM; + skt->res_io_io = (struct resource) + DEFINE_RES_IO_NAMED(skt->nr * 0x1000 + 0x10000, 0x1000, + "PCMCIA I/O"); + ret = pci_remap_iospace(&skt->res_io_io, skt->res_io.start); + if (ret) goto out_err_5; - } /* * We initialize default socket timing here, because @@ -836,7 +837,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) skt->socket.resource_ops = &pccard_static_ops; skt->socket.irq_mask = 0; skt->socket.map_size = PAGE_SIZE; - skt->socket.io_offset = (unsigned long)skt->virt_io; + skt->socket.io_offset = (unsigned long)skt->res_io_io.start; skt->status = soc_common_pcmcia_skt_state(skt); @@ -864,13 +865,13 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) return ret; out_err_8: - del_timer_sync(&skt->poll_timer); + timer_delete_sync(&skt->poll_timer); pcmcia_unregister_socket(&skt->socket); out_err_7: soc_pcmcia_hw_shutdown(skt); out_err_6: - iounmap(skt->virt_io); + iounmap(PCI_IOBASE + skt->res_io_io.start); out_err_5: release_resource(&skt->res_attr); out_err_4: |
