diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-25 12:49:46 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-25 12:49:46 -0800 |
commit | eaa76499711535fd64d747cc4ef0d78ab0fd41c6 (patch) | |
tree | c4f06fd4553802da56621e59ad106857875fdb02 /drivers/mtd/maps/gpio-addr-flash.c | |
parent | b3cc2bfe7244e848f5e8caa77bbdc72c04abd17c (diff) | |
parent | f366d3854ec0fec0f9949dac46431598614a956b (diff) | |
download | linux-eaa76499711535fd64d747cc4ef0d78ab0fd41c6.tar.gz linux-eaa76499711535fd64d747cc4ef0d78ab0fd41c6.tar.bz2 linux-eaa76499711535fd64d747cc4ef0d78ab0fd41c6.zip |
Merge tag 'mtd/for-4.21' of git://git.infradead.org/linux-mtd
Pull mtd updates from Boris Brezillon:
"SPI NOR Core changes:
- Parse the 4BAIT SFDP section
- Add a bunch of SPI NOR entries to the flash_info table
- Add the concept of SFDP fixups and use it to fix a bug on MX25L25635F
- A bunch of minor cleanups/comestic changes
NAND core changes:
- kernel-doc miscellaneous fixes.
- Third batch of fixes/cleanup to the raw NAND core impacting various
controller drivers (ams-delta, marvell, fsmc, denali, tegra,
vf610):
* Stop to pass mtd_info objects to internal functions
* Reorganize code to avoid forward declarations
* Drop useless test in nand_legacy_set_defaults()
* Move nand_exec_op() to internal.h
* Add nand_[de]select_target() helpers
* Pass the CS line to be selected in struct nand_operation
* Make ->select_chip() optional when ->exec_op() is implemented
* Deprecate the ->select_chip() hook
* Move the ->exec_op() method to nand_controller_ops
* Move ->setup_data_interface() to nand_controller_ops
* Deprecate the dummy_controller field
* Fix JEDEC detection
* Provide a helper for polling GPIO R/B pin
Raw NAND chip drivers changes:
- Macronix:
* Flag 1.8V AC chips with a broken GET_FEATURES(TIMINGS)
Raw NAND controllers drivers changes:
- Ams-delta:
* Fix the error path
* SPDX tag added
* May be compiled with COMPILE_TEST=y
* Conversion to ->exec_op() interface
* Drop .IOADDR_R/W use
* Use GPIO API for data I/O
- Denali:
* Remove denali_reset_banks()
* Remove ->dev_ready() hook
* Include <linux/bits.h> instead of <linux/bitops.h>
* Changes to comply with the above fixes/cleanup done in the core.
- FSMC:
* Add an SPDX tag to replace the license text
* Make conversion from chip to fsmc consistent
* Fix unchecked return value in fsmc_read_page_hwecc
* Changes to comply with the above fixes/cleanup done in the core.
- Marvell:
* Prevent timeouts on a loaded machine (fix)
* Changes to comply with the above fixes/cleanup done in the core.
- OMAP2:
* Pass the parent of pdev to dma_request_chan() (fix)
- R852:
* Use generic DMA API
- sh_flctl:
* Convert to SPDX identifiers
- Sunxi:
* Write pageprog related opcodes to the right register: WCMD_SET (fix)
- Tegra:
* Stop implementing ->select_chip()
- VF610:
* Add an SPDX tag to replace the license text
* Changes to comply with the above fixes/cleanup done in the core.
- Various trivial/spelling/coding style fixes.
SPI-NAND drivers changes:
- Remove the depreacated mt29f_spinand driver from staging.
- Add support for:
* Toshiba TC58CVG2S0H
* GigaDevice GD5FxGQ4xA
* Winbond W25N01GV
JFFS2 changes:
- Fix a lockdep issue
MTD changes:
- Rework the physmap driver to merge gpio-addr-flash and physmap_of
in it
- Add a new compatible for RedBoot partitions
- Make sub-partitions RW if the parent partition was RO because of a
mis-alignment
- Add pinctrl support to the
- Addition of /* fall-through */ comments where appropriate
- Various minor fixes and cleanups
Other changes:
- Update my email address"
* tag 'mtd/for-4.21' of git://git.infradead.org/linux-mtd: (108 commits)
mtd: rawnand: sunxi: Write pageprog related opcodes to WCMD_SET
MAINTAINERS: Update my email address
mtd: rawnand: marvell: prevent timeouts on a loaded machine
mtd: rawnand: omap2: Pass the parent of pdev to dma_request_chan()
mtd: rawnand: Fix JEDEC detection
mtd: spi-nor: Add support for is25lp016d
mtd: spi-nor: parse SFDP 4-byte Address Instruction Table
mtd: spi-nor: Add 4B_OPCODES flag to is25lp256
mtd: spi-nor: Add an SPDX tag to spi-nor.{c,h}
mtd: spi-nor: Make the enable argument passed to set_byte() a bool
mtd: spi-nor: Stop passing flash_info around
mtd: spi-nor: Avoid forward declaration of internal functions
mtd: spi-nor: Drop inline on all internal helpers
mtd: spi-nor: Add a post BFPT fixup for MX25L25635E
mtd: spi-nor: Add a post BFPT parsing fixup hook
mtd: spi-nor: Add the SNOR_F_4B_OPCODES flag
mtd: spi-nor: cast to u64 to avoid uint overflows
mtd: spi-nor: Add support for IS25LP032/064
mtd: spi-nor: add entry for mt35xu512aba flash
mtd: spi-nor: add macros related to MICRON flash
...
Diffstat (limited to 'drivers/mtd/maps/gpio-addr-flash.c')
-rw-r--r-- | drivers/mtd/maps/gpio-addr-flash.c | 281 |
1 files changed, 0 insertions, 281 deletions
diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c deleted file mode 100644 index a20e85aa770e..000000000000 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * drivers/mtd/maps/gpio-addr-flash.c - * - * Handle the case where a flash device is mostly addressed using physical - * line and supplemented by GPIOs. This way you can hook up say a 8MiB flash - * to a 2MiB memory range and use the GPIOs to select a particular range. - * - * Copyright © 2000 Nicolas Pitre <nico@cam.org> - * Copyright © 2005-2009 Analog Devices Inc. - * - * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. - */ - -#include <linux/gpio.h> -#include <linux/gpio/consumer.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/map.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/types.h> - -#define win_mask(x) ((BIT(x)) - 1) - -#define DRIVER_NAME "gpio-addr-flash" - -/** - * struct async_state - keep GPIO flash state - * @mtd: MTD state for this mapping - * @map: MTD map state for this flash - * @gpios: Struct containing the array of GPIO descriptors - * @gpio_values: cached GPIO values - * @win_order: dedicated memory size (if no GPIOs) - */ -struct async_state { - struct mtd_info *mtd; - struct map_info map; - struct gpio_descs *gpios; - unsigned int gpio_values; - unsigned int win_order; -}; -#define gf_map_info_to_state(mi) ((struct async_state *)(mi)->map_priv_1) - -/** - * gf_set_gpios() - set GPIO address lines to access specified flash offset - * @state: GPIO flash state - * @ofs: desired offset to access - * - * Rather than call the GPIO framework every time, cache the last-programmed - * value. This speeds up sequential accesses (which are by far the most common - * type). - */ -static void gf_set_gpios(struct async_state *state, unsigned long ofs) -{ - int i; - - ofs >>= state->win_order; - - if (ofs == state->gpio_values) - return; - - for (i = 0; i < state->gpios->ndescs; i++) { - if ((ofs & BIT(i)) == (state->gpio_values & BIT(i))) - continue; - - gpiod_set_value(state->gpios->desc[i], !!(ofs & BIT(i))); - } - - state->gpio_values = ofs; -} - -/** - * gf_read() - read a word at the specified offset - * @map: MTD map state - * @ofs: desired offset to read - */ -static map_word gf_read(struct map_info *map, unsigned long ofs) -{ - struct async_state *state = gf_map_info_to_state(map); - uint16_t word; - map_word test; - - gf_set_gpios(state, ofs); - - word = readw(map->virt + (ofs & win_mask(state->win_order))); - test.x[0] = word; - return test; -} - -/** - * gf_copy_from() - copy a chunk of data from the flash - * @map: MTD map state - * @to: memory to copy to - * @from: flash offset to copy from - * @len: how much to copy - * - * The "from" region may straddle more than one window, so toggle the GPIOs for - * each window region before reading its data. - */ -static void gf_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - struct async_state *state = gf_map_info_to_state(map); - - int this_len; - - while (len) { - this_len = from & win_mask(state->win_order); - this_len = BIT(state->win_order) - this_len; - this_len = min_t(int, len, this_len); - - gf_set_gpios(state, from); - memcpy_fromio(to, - map->virt + (from & win_mask(state->win_order)), - this_len); - len -= this_len; - from += this_len; - to += this_len; - } -} - -/** - * gf_write() - write a word at the specified offset - * @map: MTD map state - * @ofs: desired offset to write - */ -static void gf_write(struct map_info *map, map_word d1, unsigned long ofs) -{ - struct async_state *state = gf_map_info_to_state(map); - uint16_t d; - - gf_set_gpios(state, ofs); - - d = d1.x[0]; - writew(d, map->virt + (ofs & win_mask(state->win_order))); -} - -/** - * gf_copy_to() - copy a chunk of data to the flash - * @map: MTD map state - * @to: flash offset to copy to - * @from: memory to copy from - * @len: how much to copy - * - * See gf_copy_from() caveat. - */ -static void gf_copy_to(struct map_info *map, unsigned long to, - const void *from, ssize_t len) -{ - struct async_state *state = gf_map_info_to_state(map); - - int this_len; - - while (len) { - this_len = to & win_mask(state->win_order); - this_len = BIT(state->win_order) - this_len; - this_len = min_t(int, len, this_len); - - gf_set_gpios(state, to); - memcpy_toio(map->virt + (to & win_mask(state->win_order)), - from, len); - - len -= this_len; - to += this_len; - from += this_len; - } -} - -static const char * const part_probe_types[] = { - "cmdlinepart", "RedBoot", NULL }; - -/** - * gpio_flash_probe() - setup a mapping for a GPIO assisted flash - * @pdev: platform device - * - * The platform resource layout expected looks something like: - * struct mtd_partition partitions[] = { ... }; - * struct physmap_flash_data flash_data = { ... }; - * static struct gpiod_lookup_table addr_flash_gpios = { - * .dev_id = "gpio-addr-flash.0", - * .table = { - * GPIO_LOOKUP_IDX("gpio.0", 15, "addr", 0, GPIO_ACTIVE_HIGH), - * GPIO_LOOKUP_IDX("gpio.0", 16, "addr", 1, GPIO_ACTIVE_HIGH), - * ); - * }; - * gpiod_add_lookup_table(&addr_flash_gpios); - * - * struct resource flash_resource[] = { - * { - * .name = "cfi_probe", - * .start = 0x20000000, - * .end = 0x201fffff, - * .flags = IORESOURCE_MEM, - * }, - * }; - * struct platform_device flash_device = { - * .name = "gpio-addr-flash", - * .dev = { .platform_data = &flash_data, }, - * .num_resources = ARRAY_SIZE(flash_resource), - * .resource = flash_resource, - * ... - * }; - */ -static int gpio_flash_probe(struct platform_device *pdev) -{ - struct physmap_flash_data *pdata; - struct resource *memory; - struct async_state *state; - - pdata = dev_get_platdata(&pdev->dev); - memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!memory) - return -EINVAL; - - state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - state->gpios = devm_gpiod_get_array(&pdev->dev, "addr", GPIOD_OUT_LOW); - if (IS_ERR(state->gpios)) - return PTR_ERR(state->gpios); - - state->win_order = get_bitmask_order(resource_size(memory)) - 1; - - state->map.name = DRIVER_NAME; - state->map.read = gf_read; - state->map.copy_from = gf_copy_from; - state->map.write = gf_write; - state->map.copy_to = gf_copy_to; - state->map.bankwidth = pdata->width; - state->map.size = BIT(state->win_order + state->gpios->ndescs); - state->map.virt = devm_ioremap_resource(&pdev->dev, memory); - if (IS_ERR(state->map.virt)) - return PTR_ERR(state->map.virt); - - state->map.phys = NO_XIP; - state->map.map_priv_1 = (unsigned long)state; - - platform_set_drvdata(pdev, state); - - dev_notice(&pdev->dev, "probing %d-bit flash bus\n", - state->map.bankwidth * 8); - state->mtd = do_map_probe(memory->name, &state->map); - if (!state->mtd) - return -ENXIO; - state->mtd->dev.parent = &pdev->dev; - - mtd_device_parse_register(state->mtd, part_probe_types, NULL, - pdata->parts, pdata->nr_parts); - - return 0; -} - -static int gpio_flash_remove(struct platform_device *pdev) -{ - struct async_state *state = platform_get_drvdata(pdev); - - mtd_device_unregister(state->mtd); - map_destroy(state->mtd); - return 0; -} - -static struct platform_driver gpio_flash_driver = { - .probe = gpio_flash_probe, - .remove = gpio_flash_remove, - .driver = { - .name = DRIVER_NAME, - }, -}; - -module_platform_driver(gpio_flash_driver); - -MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); -MODULE_DESCRIPTION("MTD map driver for flashes addressed physically and with gpios"); -MODULE_LICENSE("GPL"); |