--- zzzz-none-000/linux-3.10.107/drivers/pcmcia/at91_cf.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/pcmcia/at91_cf.c 2021-02-04 17:41:59.000000000 +0000 @@ -18,17 +18,17 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include - -#include -#include - - /* * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; * some other bit in {A24,A22..A11} is nREG to flag memory access @@ -39,9 +39,9 @@ #define CF_IO_PHYS (1 << 23) #define CF_MEM_PHYS (0x017ff800) -/*--------------------------------------------------------------------------*/ +struct regmap *mc; -static const char driver_name[] = "at91_cf"; +/*--------------------------------------------------------------------------*/ struct at91_cf_socket { struct pcmcia_socket socket; @@ -76,7 +76,7 @@ /* kick pccard as needed */ if (present != cf->present) { cf->present = present; - pr_debug("%s: card %s\n", driver_name, + dev_dbg(&cf->pdev->dev, "card %s\n", present ? "present" : "gone"); pcmcia_parse_events(&cf->socket, SS_DETECT); } @@ -120,22 +120,22 @@ /* switch Vcc if needed and possible */ if (gpio_is_valid(cf->board->vcc_pin)) { switch (s->Vcc) { - case 0: - gpio_set_value(cf->board->vcc_pin, 0); - break; - case 33: - gpio_set_value(cf->board->vcc_pin, 1); - break; - default: - return -EINVAL; + case 0: + gpio_set_value(cf->board->vcc_pin, 0); + break; + case 33: + gpio_set_value(cf->board->vcc_pin, 1); + break; + default: + return -EINVAL; } } /* toggle reset if needed */ gpio_set_value(cf->board->rst_pin, s->flags & SS_RESET); - pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", - driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); + dev_dbg(&cf->pdev->dev, "Vcc %d, io_irq %d, flags %04x csc %04x\n", + s->Vcc, s->io_irq, s->flags, s->csc_mask); return 0; } @@ -156,10 +156,7 @@ /* * Use 16 bit accesses unless/until we need 8-bit i/o space. - */ - csr = at91_ramc_read(0, AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW; - - /* + * * NOTE: this CF controller ignores IOIS16, so we can't really do * MAP_AUTOSZ. The 16bit mode allows single byte access on either * D0-D7 (even addr) or D8-D15 (odd), so it's close enough for many @@ -170,13 +167,14 @@ * CF 3.0 spec table 35 also giving the D8-D15 option. */ if (!(io->flags & (MAP_16BIT | MAP_AUTOSZ))) { - csr |= AT91_SMC_DBW_8; - pr_debug("%s: 8bit i/o bus\n", driver_name); + csr = AT91_MC_SMC_DBW_8; + dev_dbg(&cf->pdev->dev, "8bit i/o bus\n"); } else { - csr |= AT91_SMC_DBW_16; - pr_debug("%s: 16bit i/o bus\n", driver_name); + csr = AT91_MC_SMC_DBW_16; + dev_dbg(&cf->pdev->dev, "16bit i/o bus\n"); } - at91_ramc_write(0, AT91_SMC_CSR(cf->board->chipselect), csr); + regmap_update_bits(mc, AT91_MC_SMC_CSR(cf->board->chipselect), + AT91_MC_SMC_DBW, csr); io->start = cf->socket.io_offset; io->stop = io->start + SZ_2K - 1; @@ -215,21 +213,64 @@ /*--------------------------------------------------------------------------*/ -static int __init at91_cf_probe(struct platform_device *pdev) +#if defined(CONFIG_OF) +static const struct of_device_id at91_cf_dt_ids[] = { + { .compatible = "atmel,at91rm9200-cf" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, at91_cf_dt_ids); + +static int at91_cf_dt_init(struct platform_device *pdev) +{ + struct at91_cf_data *board; + + board = devm_kzalloc(&pdev->dev, sizeof(*board), GFP_KERNEL); + if (!board) + return -ENOMEM; + + board->irq_pin = of_get_gpio(pdev->dev.of_node, 0); + board->det_pin = of_get_gpio(pdev->dev.of_node, 1); + board->vcc_pin = of_get_gpio(pdev->dev.of_node, 2); + board->rst_pin = of_get_gpio(pdev->dev.of_node, 3); + + pdev->dev.platform_data = board; + + mc = syscon_regmap_lookup_by_compatible("atmel,at91rm9200-sdramc"); + if (IS_ERR(mc)) + return PTR_ERR(mc); + + return 0; +} +#else +static int at91_cf_dt_init(struct platform_device *pdev) +{ + return -ENODEV; +} +#endif + +static int at91_cf_probe(struct platform_device *pdev) { struct at91_cf_socket *cf; struct at91_cf_data *board = pdev->dev.platform_data; struct resource *io; int status; - if (!board || !gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin)) + if (!board) { + status = at91_cf_dt_init(pdev); + if (status) + return status; + + board = pdev->dev.platform_data; + } + + if (!gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin)) return -ENODEV; io = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!io) return -ENODEV; - cf = kzalloc(sizeof *cf, GFP_KERNEL); + cf = devm_kzalloc(&pdev->dev, sizeof(*cf), GFP_KERNEL); if (!cf) return -ENOMEM; @@ -239,22 +280,25 @@ platform_set_drvdata(pdev, cf); /* must be a GPIO; ergo must trigger on both edges */ - status = gpio_request(board->det_pin, "cf_det"); + status = devm_gpio_request(&pdev->dev, board->det_pin, "cf_det"); if (status < 0) - goto fail0; - status = request_irq(gpio_to_irq(board->det_pin), at91_cf_irq, 0, driver_name, cf); + return status; + + status = devm_request_irq(&pdev->dev, gpio_to_irq(board->det_pin), + at91_cf_irq, 0, "at91_cf detect", cf); if (status < 0) - goto fail00; + return status; + device_init_wakeup(&pdev->dev, 1); - status = gpio_request(board->rst_pin, "cf_rst"); + status = devm_gpio_request(&pdev->dev, board->rst_pin, "cf_rst"); if (status < 0) goto fail0a; if (gpio_is_valid(board->vcc_pin)) { - status = gpio_request(board->vcc_pin, "cf_vcc"); + status = devm_gpio_request(&pdev->dev, board->vcc_pin, "cf_vcc"); if (status < 0) - goto fail0b; + goto fail0a; } /* @@ -264,32 +308,34 @@ * (Note: DK board doesn't wire the IRQ pin...) */ if (gpio_is_valid(board->irq_pin)) { - status = gpio_request(board->irq_pin, "cf_irq"); + status = devm_gpio_request(&pdev->dev, board->irq_pin, "cf_irq"); if (status < 0) - goto fail0c; - status = request_irq(gpio_to_irq(board->irq_pin), at91_cf_irq, - IRQF_SHARED, driver_name, cf); + goto fail0a; + + status = devm_request_irq(&pdev->dev, gpio_to_irq(board->irq_pin), + at91_cf_irq, IRQF_SHARED, "at91_cf", cf); if (status < 0) - goto fail0d; + goto fail0a; cf->socket.pci_irq = gpio_to_irq(board->irq_pin); } else cf->socket.pci_irq = nr_irqs + 1; - /* pcmcia layer only remaps "real" memory not iospace */ - cf->socket.io_offset = (unsigned long) - ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K); - if (!cf->socket.io_offset) { - status = -ENXIO; - goto fail1; - } + /* + * pcmcia layer only remaps "real" memory not iospace + * io_offset is set to 0x10000 to avoid the check in static_find_io(). + * */ + cf->socket.io_offset = 0x10000; + status = pci_ioremap_io(0x10000, cf->phys_baseaddr + CF_IO_PHYS); + if (status) + goto fail0a; /* reserve chip-select regions */ - if (!request_mem_region(io->start, resource_size(io), driver_name)) { + if (!devm_request_mem_region(&pdev->dev, io->start, resource_size(io), "at91_cf")) { status = -ENXIO; - goto fail1; + goto fail0a; } - pr_info("%s: irqs det #%d, io #%d\n", driver_name, + dev_info(&pdev->dev, "irqs det #%d, io #%d\n", gpio_to_irq(board->det_pin), gpio_to_irq(board->irq_pin)); cf->socket.owner = THIS_MODULE; @@ -303,55 +349,22 @@ status = pcmcia_register_socket(&cf->socket); if (status < 0) - goto fail2; + goto fail0a; return 0; -fail2: - release_mem_region(io->start, resource_size(io)); -fail1: - if (cf->socket.io_offset) - iounmap((void __iomem *) cf->socket.io_offset); - if (gpio_is_valid(board->irq_pin)) { - free_irq(gpio_to_irq(board->irq_pin), cf); -fail0d: - gpio_free(board->irq_pin); - } -fail0c: - if (gpio_is_valid(board->vcc_pin)) - gpio_free(board->vcc_pin); -fail0b: - gpio_free(board->rst_pin); fail0a: device_init_wakeup(&pdev->dev, 0); - free_irq(gpio_to_irq(board->det_pin), cf); -fail00: - gpio_free(board->det_pin); -fail0: - kfree(cf); return status; } -static int __exit at91_cf_remove(struct platform_device *pdev) +static int at91_cf_remove(struct platform_device *pdev) { struct at91_cf_socket *cf = platform_get_drvdata(pdev); - struct at91_cf_data *board = cf->board; - struct resource *io = cf->socket.io[0].res; pcmcia_unregister_socket(&cf->socket); - release_mem_region(io->start, resource_size(io)); - iounmap((void __iomem *) cf->socket.io_offset); - if (gpio_is_valid(board->irq_pin)) { - free_irq(gpio_to_irq(board->irq_pin), cf); - gpio_free(board->irq_pin); - } - if (gpio_is_valid(board->vcc_pin)) - gpio_free(board->vcc_pin); - gpio_free(board->rst_pin); device_init_wakeup(&pdev->dev, 0); - free_irq(gpio_to_irq(board->det_pin), cf); - gpio_free(board->det_pin); - kfree(cf); + return 0; } @@ -391,27 +404,16 @@ static struct platform_driver at91_cf_driver = { .driver = { - .name = (char *) driver_name, - .owner = THIS_MODULE, + .name = "at91_cf", + .of_match_table = of_match_ptr(at91_cf_dt_ids), }, - .remove = __exit_p(at91_cf_remove), + .probe = at91_cf_probe, + .remove = at91_cf_remove, .suspend = at91_cf_suspend, .resume = at91_cf_resume, }; -/*--------------------------------------------------------------------------*/ - -static int __init at91_cf_init(void) -{ - return platform_driver_probe(&at91_cf_driver, at91_cf_probe); -} -module_init(at91_cf_init); - -static void __exit at91_cf_exit(void) -{ - platform_driver_unregister(&at91_cf_driver); -} -module_exit(at91_cf_exit); +module_platform_driver(at91_cf_driver); MODULE_DESCRIPTION("AT91 Compact Flash Driver"); MODULE_AUTHOR("David Brownell");