mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
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
...
This commit is contained in:
@@ -36,9 +36,10 @@ Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
|
||||
Ben Gardner <bgardner@wabtec.com>
|
||||
Ben M Cahill <ben.m.cahill@intel.com>
|
||||
Björn Steinbrink <B.Steinbrink@gmx.de>
|
||||
Boris Brezillon <boris.brezillon@bootlin.com> <boris.brezillon@free-electrons.com>
|
||||
Boris Brezillon <boris.brezillon@bootlin.com> <b.brezillon.dev@gmail.com>
|
||||
Boris Brezillon <boris.brezillon@bootlin.com> <b.brezillon@overkiz.com>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <b.brezillon.dev@gmail.com>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <b.brezillon@overkiz.com>
|
||||
Brian Avery <b.avery@hp.com>
|
||||
Brian King <brking@us.ibm.com>
|
||||
Christoph Hellwig <hch@lst.de>
|
||||
|
||||
@@ -29,6 +29,8 @@ file systems on embedded devices.
|
||||
- use-advanced-sector-protection: boolean to enable support for the
|
||||
advanced sector protection (Spansion: PPB - Persistent Protection
|
||||
Bits) locking.
|
||||
- addr-gpios : (optional) List of GPIO descriptors that will be used to
|
||||
address the MSBs address lines. The order goes from LSB to MSB.
|
||||
|
||||
For JEDEC compatible devices, the following additional properties
|
||||
are defined:
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
RedBoot FLASH Image System (FIS) Partitions
|
||||
===========================================
|
||||
|
||||
The FLASH Image System (FIS) directory is a flash description
|
||||
format closely associated with the RedBoot boot loader.
|
||||
|
||||
It uses one single flash eraseblock in the flash to store an index of
|
||||
all images in the flash.
|
||||
|
||||
This block size will vary depending on flash but is typically
|
||||
32 KB in size.
|
||||
|
||||
Required properties:
|
||||
- compatible : (required) must be "redboot-fis"
|
||||
- fis-index-block : (required) a index to the eraseblock containing
|
||||
the FIS directory on this device. On a flash memory with 32KB
|
||||
eraseblocks, 0 means the first eraseblock at 0x00000000, 1 means the
|
||||
second eraseblock at 0x00008000 and so on.
|
||||
|
||||
Example:
|
||||
|
||||
flash@0 {
|
||||
partitions {
|
||||
compatible = "redboot-fis";
|
||||
fis-index-block = <0>;
|
||||
};
|
||||
};
|
||||
+4
-4
@@ -4915,7 +4915,7 @@ F: Documentation/gpu/meson.rst
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
|
||||
DRM DRIVERS FOR ATMEL HLCDC
|
||||
M: Boris Brezillon <boris.brezillon@bootlin.com>
|
||||
M: Boris Brezillon <bbrezillon@kernel.org>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
F: drivers/gpu/drm/atmel-hlcdc/
|
||||
@@ -8998,7 +8998,7 @@ F: include/uapi/drm/armada_drm.h
|
||||
F: Documentation/devicetree/bindings/display/armada/
|
||||
|
||||
MARVELL CRYPTO DRIVER
|
||||
M: Boris Brezillon <boris.brezillon@bootlin.com>
|
||||
M: Boris Brezillon <bbrezillon@kernel.org>
|
||||
M: Arnaud Ebalard <arno@natisbad.org>
|
||||
F: drivers/crypto/marvell/
|
||||
S: Maintained
|
||||
@@ -9709,7 +9709,7 @@ F: mm/
|
||||
MEMORY TECHNOLOGY DEVICES (MTD)
|
||||
M: David Woodhouse <dwmw2@infradead.org>
|
||||
M: Brian Norris <computersforpeace@gmail.com>
|
||||
M: Boris Brezillon <boris.brezillon@bootlin.com>
|
||||
M: Boris Brezillon <bbrezillon@kernel.org>
|
||||
M: Marek Vasut <marek.vasut@gmail.com>
|
||||
M: Richard Weinberger <richard@nod.at>
|
||||
L: linux-mtd@lists.infradead.org
|
||||
@@ -10296,7 +10296,7 @@ S: Supported
|
||||
F: drivers/net/ethernet/myricom/myri10ge/
|
||||
|
||||
NAND FLASH SUBSYSTEM
|
||||
M: Boris Brezillon <boris.brezillon@bootlin.com>
|
||||
M: Boris Brezillon <bbrezillon@kernel.org>
|
||||
M: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
R: Richard Weinberger <richard@nod.at>
|
||||
L: linux-mtd@lists.infradead.org
|
||||
|
||||
@@ -296,23 +296,13 @@ struct modem_private_data {
|
||||
|
||||
static struct modem_private_data modem_priv;
|
||||
|
||||
static struct resource ams_delta_nand_resources[] = {
|
||||
[0] = {
|
||||
.start = OMAP1_MPUIO_BASE,
|
||||
.end = OMAP1_MPUIO_BASE +
|
||||
OMAP_MPUIO_IO_CNTL + sizeof(u32) - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device ams_delta_nand_device = {
|
||||
.name = "ams-delta-nand",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(ams_delta_nand_resources),
|
||||
.resource = ams_delta_nand_resources,
|
||||
};
|
||||
|
||||
#define OMAP_GPIO_LABEL "gpio-0-15"
|
||||
#define OMAP_GPIO_LABEL "gpio-0-15"
|
||||
#define OMAP_MPUIO_LABEL "mpuio"
|
||||
|
||||
static struct gpiod_lookup_table ams_delta_nand_gpio_table = {
|
||||
.table = {
|
||||
@@ -324,6 +314,14 @@ static struct gpiod_lookup_table ams_delta_nand_gpio_table = {
|
||||
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWE, "nwe", 0),
|
||||
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_ALE, "ale", 0),
|
||||
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_CLE, "cle", 0),
|
||||
GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 0, "data", 0, 0),
|
||||
GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 1, "data", 1, 0),
|
||||
GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 2, "data", 2, 0),
|
||||
GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 3, "data", 3, 0),
|
||||
GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 4, "data", 4, 0),
|
||||
GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 5, "data", 5, 0),
|
||||
GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 6, "data", 6, 0),
|
||||
GPIO_LOOKUP_IDX(OMAP_MPUIO_LABEL, 7, "data", 7, 0),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
+1
-51
@@ -22,56 +22,6 @@ config MTD_TESTS
|
||||
WARNING: some of the tests will ERASE entire MTD device which they
|
||||
test. Do not use these tests unless you really know what you do.
|
||||
|
||||
config MTD_REDBOOT_PARTS
|
||||
tristate "RedBoot partition table parsing"
|
||||
help
|
||||
RedBoot is a ROM monitor and bootloader which deals with multiple
|
||||
'images' in flash devices by putting a table one of the erase
|
||||
blocks on the device, similar to a partition table, which gives
|
||||
the offsets, lengths and names of all the images stored in the
|
||||
flash.
|
||||
|
||||
If you need code which can detect and parse this table, and register
|
||||
MTD 'partitions' corresponding to each image in the table, enable
|
||||
this option.
|
||||
|
||||
You will still need the parsing functions to be called by the driver
|
||||
for your particular device. It won't happen automatically. The
|
||||
SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
|
||||
example.
|
||||
|
||||
if MTD_REDBOOT_PARTS
|
||||
|
||||
config MTD_REDBOOT_DIRECTORY_BLOCK
|
||||
int "Location of RedBoot partition table"
|
||||
default "-1"
|
||||
help
|
||||
This option is the Linux counterpart to the
|
||||
CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK RedBoot compile time
|
||||
option.
|
||||
|
||||
The option specifies which Flash sectors holds the RedBoot
|
||||
partition table. A zero or positive value gives an absolute
|
||||
erase block number. A negative value specifies a number of
|
||||
sectors before the end of the device.
|
||||
|
||||
For example "2" means block number 2, "-1" means the last
|
||||
block and "-2" means the penultimate block.
|
||||
|
||||
config MTD_REDBOOT_PARTS_UNALLOCATED
|
||||
bool "Include unallocated flash regions"
|
||||
help
|
||||
If you need to register each unallocated flash region as a MTD
|
||||
'partition', enable this option.
|
||||
|
||||
config MTD_REDBOOT_PARTS_READONLY
|
||||
bool "Force read-only for RedBoot system images"
|
||||
help
|
||||
If you need to force read-only for 'RedBoot', 'RedBoot Config' and
|
||||
'FIS directory' images, enable this option.
|
||||
|
||||
endif # MTD_REDBOOT_PARTS
|
||||
|
||||
config MTD_CMDLINE_PARTS
|
||||
tristate "Command line partition table parsing"
|
||||
depends on MTD
|
||||
@@ -144,7 +94,7 @@ config MTD_BCM63XX_PARTS
|
||||
depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST
|
||||
select CRC32
|
||||
help
|
||||
This provides partions parsing for BCM63xx devices with CFE
|
||||
This provides partition parsing for BCM63xx devices with CFE
|
||||
bootloaders.
|
||||
|
||||
config MTD_BCM47XX_PARTS
|
||||
|
||||
@@ -8,7 +8,6 @@ obj-$(CONFIG_MTD) += mtd.o
|
||||
mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o
|
||||
|
||||
obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
|
||||
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
|
||||
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
|
||||
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
|
||||
obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
|
||||
|
||||
@@ -324,6 +324,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
|
||||
case FL_JEDEC_QUERY:
|
||||
map_write(map, CMD(0x70), cmd_addr);
|
||||
chip->state = FL_STATUS;
|
||||
/* Fall through */
|
||||
|
||||
case FL_STATUS:
|
||||
status = map_read(map, cmd_addr);
|
||||
@@ -461,6 +462,7 @@ static int do_write_buffer(struct map_info *map, struct flchip *chip,
|
||||
#ifdef DEBUG_CFI_FEATURES
|
||||
printk("%s: 1 status[%x]\n", __func__, map_read(map, cmd_adr));
|
||||
#endif
|
||||
/* Fall through */
|
||||
|
||||
case FL_STATUS:
|
||||
status = map_read(map, cmd_adr);
|
||||
@@ -754,6 +756,7 @@ retry:
|
||||
case FL_READY:
|
||||
map_write(map, CMD(0x70), adr);
|
||||
chip->state = FL_STATUS;
|
||||
/* Fall through */
|
||||
|
||||
case FL_STATUS:
|
||||
status = map_read(map, adr);
|
||||
@@ -995,6 +998,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
|
||||
* as the whole point is that nobody can do anything
|
||||
* with the chip now anyway.
|
||||
*/
|
||||
/* Fall through */
|
||||
case FL_SYNCING:
|
||||
mutex_unlock(&chip->mutex);
|
||||
break;
|
||||
@@ -1050,6 +1054,7 @@ retry:
|
||||
case FL_READY:
|
||||
map_write(map, CMD(0x70), adr);
|
||||
chip->state = FL_STATUS;
|
||||
/* Fall through */
|
||||
|
||||
case FL_STATUS:
|
||||
status = map_read(map, adr);
|
||||
@@ -1196,6 +1201,7 @@ retry:
|
||||
case FL_READY:
|
||||
map_write(map, CMD(0x70), adr);
|
||||
chip->state = FL_STATUS;
|
||||
/* Fall through */
|
||||
|
||||
case FL_STATUS:
|
||||
status = map_read(map, adr);
|
||||
|
||||
@@ -329,8 +329,10 @@ static int ustrtoul(const char *cp, char **endp, unsigned int base)
|
||||
switch (**endp) {
|
||||
case 'G' :
|
||||
result *= 1024;
|
||||
/* fall through */
|
||||
case 'M':
|
||||
result *= 1024;
|
||||
/* fall through */
|
||||
case 'K':
|
||||
case 'k':
|
||||
result *= 1024;
|
||||
|
||||
@@ -1603,7 +1603,7 @@ static void doc_unregister_sysfs(struct platform_device *pdev,
|
||||
/*
|
||||
* Debug sysfs entries
|
||||
*/
|
||||
static int dbg_flashctrl_show(struct seq_file *s, void *p)
|
||||
static int flashcontrol_show(struct seq_file *s, void *p)
|
||||
{
|
||||
struct docg3 *docg3 = (struct docg3 *)s->private;
|
||||
|
||||
@@ -1623,9 +1623,9 @@ static int dbg_flashctrl_show(struct seq_file *s, void *p)
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEBUGFS_RO_ATTR(flashcontrol, dbg_flashctrl_show);
|
||||
DEFINE_SHOW_ATTRIBUTE(flashcontrol);
|
||||
|
||||
static int dbg_asicmode_show(struct seq_file *s, void *p)
|
||||
static int asic_mode_show(struct seq_file *s, void *p)
|
||||
{
|
||||
struct docg3 *docg3 = (struct docg3 *)s->private;
|
||||
|
||||
@@ -1660,9 +1660,9 @@ static int dbg_asicmode_show(struct seq_file *s, void *p)
|
||||
seq_puts(s, ")\n");
|
||||
return 0;
|
||||
}
|
||||
DEBUGFS_RO_ATTR(asic_mode, dbg_asicmode_show);
|
||||
DEFINE_SHOW_ATTRIBUTE(asic_mode);
|
||||
|
||||
static int dbg_device_id_show(struct seq_file *s, void *p)
|
||||
static int device_id_show(struct seq_file *s, void *p)
|
||||
{
|
||||
struct docg3 *docg3 = (struct docg3 *)s->private;
|
||||
int id;
|
||||
@@ -1674,9 +1674,9 @@ static int dbg_device_id_show(struct seq_file *s, void *p)
|
||||
seq_printf(s, "DeviceId = %d\n", id);
|
||||
return 0;
|
||||
}
|
||||
DEBUGFS_RO_ATTR(device_id, dbg_device_id_show);
|
||||
DEFINE_SHOW_ATTRIBUTE(device_id);
|
||||
|
||||
static int dbg_protection_show(struct seq_file *s, void *p)
|
||||
static int protection_show(struct seq_file *s, void *p)
|
||||
{
|
||||
struct docg3 *docg3 = (struct docg3 *)s->private;
|
||||
int protect, dps0, dps0_low, dps0_high, dps1, dps1_low, dps1_high;
|
||||
@@ -1726,7 +1726,7 @@ static int dbg_protection_show(struct seq_file *s, void *p)
|
||||
!!(dps1 & DOC_DPS_KEY_OK));
|
||||
return 0;
|
||||
}
|
||||
DEBUGFS_RO_ATTR(protection, dbg_protection_show);
|
||||
DEFINE_SHOW_ATTRIBUTE(protection);
|
||||
|
||||
static void __init doc_dbg_register(struct mtd_info *floor)
|
||||
{
|
||||
|
||||
@@ -317,17 +317,6 @@ struct docg3 {
|
||||
#define doc_info(fmt, arg...) dev_info(docg3->dev, (fmt), ## arg)
|
||||
#define doc_dbg(fmt, arg...) dev_dbg(docg3->dev, (fmt), ## arg)
|
||||
#define doc_vdbg(fmt, arg...) dev_vdbg(docg3->dev, (fmt), ## arg)
|
||||
|
||||
#define DEBUGFS_RO_ATTR(name, show_fct) \
|
||||
static int name##_open(struct inode *inode, struct file *file) \
|
||||
{ return single_open(file, show_fct, inode->i_private); } \
|
||||
static const struct file_operations name##_fops = { \
|
||||
.owner = THIS_MODULE, \
|
||||
.open = name##_open, \
|
||||
.llseek = seq_lseek, \
|
||||
.read = seq_read, \
|
||||
.release = single_release \
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
+14
-23
@@ -66,15 +66,15 @@ config MTD_PHYSMAP_BANKWIDTH
|
||||
used internally by the CFI drivers.
|
||||
|
||||
config MTD_PHYSMAP_OF
|
||||
tristate "Memory device in physical memory map based on OF description"
|
||||
depends on OF && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM || MTD_RAM)
|
||||
bool "Memory device in physical memory map based on OF description"
|
||||
depends on OF && MTD_PHYSMAP
|
||||
help
|
||||
This provides a 'mapping' driver which allows the NOR Flash, ROM
|
||||
and RAM driver code to communicate with chips which are mapped
|
||||
physically into the CPU's memory. The mapping description here is
|
||||
taken from OF device tree.
|
||||
|
||||
config MTD_PHYSMAP_OF_VERSATILE
|
||||
config MTD_PHYSMAP_VERSATILE
|
||||
bool "ARM Versatile OF-based physical memory map handling"
|
||||
depends on MTD_PHYSMAP_OF
|
||||
depends on MFD_SYSCON
|
||||
@@ -84,16 +84,26 @@ config MTD_PHYSMAP_OF_VERSATILE
|
||||
platforms, basically to add a VPP (write protection) callback so
|
||||
the flash can be taken out of write protection.
|
||||
|
||||
config MTD_PHYSMAP_OF_GEMINI
|
||||
config MTD_PHYSMAP_GEMINI
|
||||
bool "Cortina Gemini OF-based physical memory map handling"
|
||||
depends on MTD_PHYSMAP_OF
|
||||
depends on MFD_SYSCON
|
||||
select MTD_COMPLEX_MAPPINGS
|
||||
default ARCH_GEMINI
|
||||
help
|
||||
This provides some extra DT physmap parsing for the Gemini
|
||||
platforms, some detection and setting up parallel mode on the
|
||||
external interface.
|
||||
|
||||
config MTD_PHYSMAP_GPIO_ADDR
|
||||
bool "GPIO-assisted Flash Chip Support"
|
||||
depends on MTD_PHYSMAP
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
depends on MTD_COMPLEX_MAPPINGS
|
||||
help
|
||||
Extend the physmap driver to allow flashes to be partially
|
||||
physically addressed and assisted by GPIOs.
|
||||
|
||||
config MTD_PMC_MSP_EVM
|
||||
tristate "CFI Flash device mapped on PMC-Sierra MSP"
|
||||
depends on PMC_MSP && MTD_CFI
|
||||
@@ -334,16 +344,6 @@ config MTD_PCMCIA_ANONYMOUS
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config MTD_GPIO_ADDR
|
||||
tristate "GPIO-assisted Flash Chip Support"
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
depends on MTD_COMPLEX_MAPPINGS
|
||||
help
|
||||
Map driver which allows flashes to be partially physically addressed
|
||||
and assisted by GPIOs.
|
||||
|
||||
If compiled as a module, it will be called gpio-addr-flash.
|
||||
|
||||
config MTD_UCLINUX
|
||||
bool "Generic uClinux RAM/ROM filesystem support"
|
||||
depends on (MTD_RAM=y || MTD_ROM=y) && (!MMU || COLDFIRE)
|
||||
@@ -400,13 +400,4 @@ config MTD_PISMO
|
||||
|
||||
When built as a module, it will be called pismo.ko
|
||||
|
||||
config MTD_LATCH_ADDR
|
||||
tristate "Latch-assisted Flash Chip Support"
|
||||
depends on MTD_COMPLEX_MAPPINGS
|
||||
help
|
||||
Map driver which allows flashes to be partially physically addressed
|
||||
and have the upper address lines set by a board specific code.
|
||||
|
||||
If compiled as a module, it will be called latch-addr-flash.
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -17,12 +17,11 @@ obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o
|
||||
obj-$(CONFIG_MTD_CK804XROM) += ck804xrom.o
|
||||
obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
|
||||
obj-$(CONFIG_MTD_PXA2XX) += pxa2xx-flash.o
|
||||
physmap-objs-y += physmap-core.o
|
||||
physmap-objs-$(CONFIG_MTD_PHYSMAP_VERSATILE) += physmap-versatile.o
|
||||
physmap-objs-$(CONFIG_MTD_PHYSMAP_GEMINI) += physmap-gemini.o
|
||||
physmap-objs := $(physmap-objs-y)
|
||||
obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
|
||||
physmap_of-objs-y += physmap_of_core.o
|
||||
physmap_of-objs-$(CONFIG_MTD_PHYSMAP_OF_VERSATILE) += physmap_of_versatile.o
|
||||
physmap_of-objs-$(CONFIG_MTD_PHYSMAP_OF_GEMINI) += physmap_of_gemini.o
|
||||
physmap_of-objs := $(physmap_of-objs-y)
|
||||
obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o
|
||||
obj-$(CONFIG_MTD_PISMO) += pismo.o
|
||||
obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o
|
||||
obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
|
||||
@@ -44,6 +43,4 @@ obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
|
||||
obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
|
||||
obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
|
||||
obj-$(CONFIG_MTD_VMU) += vmu-flash.o
|
||||
obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o
|
||||
obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o
|
||||
obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o
|
||||
|
||||
@@ -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");
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Interface for NOR flash driver whose high address lines are latched
|
||||
*
|
||||
* Copyright © 2000 Nicolas Pitre <nico@cam.org>
|
||||
* Copyright © 2005-2008 Analog Devices Inc.
|
||||
* Copyright © 2008 MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#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/platform_device.h>
|
||||
#include <linux/mtd/latch-addr-flash.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define DRIVER_NAME "latch-addr-flash"
|
||||
|
||||
struct latch_addr_flash_info {
|
||||
struct mtd_info *mtd;
|
||||
struct map_info map;
|
||||
struct resource *res;
|
||||
|
||||
void (*set_window)(unsigned long offset, void *data);
|
||||
void *data;
|
||||
|
||||
/* cache; could be found out of res */
|
||||
unsigned long win_mask;
|
||||
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static map_word lf_read(struct map_info *map, unsigned long ofs)
|
||||
{
|
||||
struct latch_addr_flash_info *info;
|
||||
map_word datum;
|
||||
|
||||
info = (struct latch_addr_flash_info *)map->map_priv_1;
|
||||
|
||||
spin_lock(&info->lock);
|
||||
|
||||
info->set_window(ofs, info->data);
|
||||
datum = inline_map_read(map, info->win_mask & ofs);
|
||||
|
||||
spin_unlock(&info->lock);
|
||||
|
||||
return datum;
|
||||
}
|
||||
|
||||
static void lf_write(struct map_info *map, map_word datum, unsigned long ofs)
|
||||
{
|
||||
struct latch_addr_flash_info *info;
|
||||
|
||||
info = (struct latch_addr_flash_info *)map->map_priv_1;
|
||||
|
||||
spin_lock(&info->lock);
|
||||
|
||||
info->set_window(ofs, info->data);
|
||||
inline_map_write(map, datum, info->win_mask & ofs);
|
||||
|
||||
spin_unlock(&info->lock);
|
||||
}
|
||||
|
||||
static void lf_copy_from(struct map_info *map, void *to,
|
||||
unsigned long from, ssize_t len)
|
||||
{
|
||||
struct latch_addr_flash_info *info =
|
||||
(struct latch_addr_flash_info *) map->map_priv_1;
|
||||
unsigned n;
|
||||
|
||||
while (len > 0) {
|
||||
n = info->win_mask + 1 - (from & info->win_mask);
|
||||
if (n > len)
|
||||
n = len;
|
||||
|
||||
spin_lock(&info->lock);
|
||||
|
||||
info->set_window(from, info->data);
|
||||
memcpy_fromio(to, map->virt + (from & info->win_mask), n);
|
||||
|
||||
spin_unlock(&info->lock);
|
||||
|
||||
to += n;
|
||||
from += n;
|
||||
len -= n;
|
||||
}
|
||||
}
|
||||
|
||||
static char *rom_probe_types[] = { "cfi_probe", NULL };
|
||||
|
||||
static int latch_addr_flash_remove(struct platform_device *dev)
|
||||
{
|
||||
struct latch_addr_flash_info *info;
|
||||
struct latch_addr_flash_data *latch_addr_data;
|
||||
|
||||
info = platform_get_drvdata(dev);
|
||||
if (info == NULL)
|
||||
return 0;
|
||||
|
||||
latch_addr_data = dev_get_platdata(&dev->dev);
|
||||
|
||||
if (info->mtd != NULL) {
|
||||
mtd_device_unregister(info->mtd);
|
||||
map_destroy(info->mtd);
|
||||
}
|
||||
|
||||
if (info->map.virt != NULL)
|
||||
iounmap(info->map.virt);
|
||||
|
||||
if (info->res != NULL)
|
||||
release_mem_region(info->res->start, resource_size(info->res));
|
||||
|
||||
kfree(info);
|
||||
|
||||
if (latch_addr_data->done)
|
||||
latch_addr_data->done(latch_addr_data->data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int latch_addr_flash_probe(struct platform_device *dev)
|
||||
{
|
||||
struct latch_addr_flash_data *latch_addr_data;
|
||||
struct latch_addr_flash_info *info;
|
||||
resource_size_t win_base = dev->resource->start;
|
||||
resource_size_t win_size = resource_size(dev->resource);
|
||||
char **probe_type;
|
||||
int chipsel;
|
||||
int err;
|
||||
|
||||
latch_addr_data = dev_get_platdata(&dev->dev);
|
||||
if (latch_addr_data == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
pr_notice("latch-addr platform flash device: %#llx byte "
|
||||
"window at %#.8llx\n",
|
||||
(unsigned long long)win_size, (unsigned long long)win_base);
|
||||
|
||||
chipsel = dev->id;
|
||||
|
||||
if (latch_addr_data->init) {
|
||||
err = latch_addr_data->init(latch_addr_data->data, chipsel);
|
||||
if (err != 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
info = kzalloc(sizeof(struct latch_addr_flash_info), GFP_KERNEL);
|
||||
if (info == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
platform_set_drvdata(dev, info);
|
||||
|
||||
info->res = request_mem_region(win_base, win_size, DRIVER_NAME);
|
||||
if (info->res == NULL) {
|
||||
dev_err(&dev->dev, "Could not reserve memory region\n");
|
||||
err = -EBUSY;
|
||||
goto free_info;
|
||||
}
|
||||
|
||||
info->map.name = DRIVER_NAME;
|
||||
info->map.size = latch_addr_data->size;
|
||||
info->map.bankwidth = latch_addr_data->width;
|
||||
|
||||
info->map.phys = NO_XIP;
|
||||
info->map.virt = ioremap(win_base, win_size);
|
||||
if (!info->map.virt) {
|
||||
err = -ENOMEM;
|
||||
goto free_res;
|
||||
}
|
||||
|
||||
info->map.map_priv_1 = (unsigned long)info;
|
||||
|
||||
info->map.read = lf_read;
|
||||
info->map.copy_from = lf_copy_from;
|
||||
info->map.write = lf_write;
|
||||
info->set_window = latch_addr_data->set_window;
|
||||
info->data = latch_addr_data->data;
|
||||
info->win_mask = win_size - 1;
|
||||
|
||||
spin_lock_init(&info->lock);
|
||||
|
||||
for (probe_type = rom_probe_types; !info->mtd && *probe_type;
|
||||
probe_type++)
|
||||
info->mtd = do_map_probe(*probe_type, &info->map);
|
||||
|
||||
if (info->mtd == NULL) {
|
||||
dev_err(&dev->dev, "map_probe failed\n");
|
||||
err = -ENODEV;
|
||||
goto iounmap;
|
||||
}
|
||||
info->mtd->dev.parent = &dev->dev;
|
||||
|
||||
mtd_device_register(info->mtd, latch_addr_data->parts,
|
||||
latch_addr_data->nr_parts);
|
||||
return 0;
|
||||
|
||||
iounmap:
|
||||
iounmap(info->map.virt);
|
||||
free_res:
|
||||
release_mem_region(info->res->start, resource_size(info->res));
|
||||
free_info:
|
||||
kfree(info);
|
||||
done:
|
||||
if (latch_addr_data->done)
|
||||
latch_addr_data->done(latch_addr_data->data);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct platform_driver latch_addr_flash_driver = {
|
||||
.probe = latch_addr_flash_probe,
|
||||
.remove = latch_addr_flash_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(latch_addr_flash_driver);
|
||||
|
||||
MODULE_AUTHOR("David Griego <dgriego@mvista.com>");
|
||||
MODULE_DESCRIPTION("MTD map driver for flashes addressed physically with upper "
|
||||
"address lines being set board specifically");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,10 +10,12 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/xip.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/bitops.h>
|
||||
#include "physmap_of_gemini.h"
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include "physmap-gemini.h"
|
||||
|
||||
/*
|
||||
* The Flash-relevant parts of the global status register
|
||||
@@ -44,6 +46,82 @@
|
||||
|
||||
#define FLASH_PARALLEL_HIGH_PIN_CNT (1 << 20) /* else low pin cnt */
|
||||
|
||||
static const struct of_device_id syscon_match[] = {
|
||||
{ .compatible = "cortina,gemini-syscon" },
|
||||
{ },
|
||||
};
|
||||
|
||||
struct gemini_flash {
|
||||
struct device *dev;
|
||||
struct pinctrl *p;
|
||||
struct pinctrl_state *enabled_state;
|
||||
struct pinctrl_state *disabled_state;
|
||||
};
|
||||
|
||||
/* Static local state */
|
||||
static struct gemini_flash *gf;
|
||||
|
||||
static void gemini_flash_enable_pins(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (IS_ERR(gf->enabled_state))
|
||||
return;
|
||||
ret = pinctrl_select_state(gf->p, gf->enabled_state);
|
||||
if (ret)
|
||||
dev_err(gf->dev, "failed to enable pins\n");
|
||||
}
|
||||
|
||||
static void gemini_flash_disable_pins(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (IS_ERR(gf->disabled_state))
|
||||
return;
|
||||
ret = pinctrl_select_state(gf->p, gf->disabled_state);
|
||||
if (ret)
|
||||
dev_err(gf->dev, "failed to disable pins\n");
|
||||
}
|
||||
|
||||
static map_word __xipram gemini_flash_map_read(struct map_info *map,
|
||||
unsigned long ofs)
|
||||
{
|
||||
map_word __xipram ret;
|
||||
|
||||
gemini_flash_enable_pins();
|
||||
ret = inline_map_read(map, ofs);
|
||||
gemini_flash_disable_pins();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __xipram gemini_flash_map_write(struct map_info *map,
|
||||
const map_word datum,
|
||||
unsigned long ofs)
|
||||
{
|
||||
gemini_flash_enable_pins();
|
||||
inline_map_write(map, datum, ofs);
|
||||
gemini_flash_disable_pins();
|
||||
}
|
||||
|
||||
static void __xipram gemini_flash_map_copy_from(struct map_info *map,
|
||||
void *to, unsigned long from,
|
||||
ssize_t len)
|
||||
{
|
||||
gemini_flash_enable_pins();
|
||||
inline_map_copy_from(map, to, from, len);
|
||||
gemini_flash_disable_pins();
|
||||
}
|
||||
|
||||
static void __xipram gemini_flash_map_copy_to(struct map_info *map,
|
||||
unsigned long to,
|
||||
const void *from, ssize_t len)
|
||||
{
|
||||
gemini_flash_enable_pins();
|
||||
inline_map_copy_to(map, to, from, len);
|
||||
gemini_flash_disable_pins();
|
||||
}
|
||||
|
||||
int of_flash_probe_gemini(struct platform_device *pdev,
|
||||
struct device_node *np,
|
||||
struct map_info *map)
|
||||
@@ -57,6 +135,11 @@ int of_flash_probe_gemini(struct platform_device *pdev,
|
||||
if (!of_device_is_compatible(np, "cortina,gemini-flash"))
|
||||
return 0;
|
||||
|
||||
gf = devm_kzalloc(dev, sizeof(*gf), GFP_KERNEL);
|
||||
if (!gf)
|
||||
return -ENOMEM;
|
||||
gf->dev = dev;
|
||||
|
||||
rmap = syscon_regmap_lookup_by_phandle(np, "syscon");
|
||||
if (IS_ERR(rmap)) {
|
||||
dev_err(dev, "no syscon\n");
|
||||
@@ -91,7 +174,32 @@ int of_flash_probe_gemini(struct platform_device *pdev,
|
||||
map->bankwidth * 8);
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "initialized Gemini-specific physmap control\n");
|
||||
gf->p = devm_pinctrl_get(dev);
|
||||
if (IS_ERR(gf->p)) {
|
||||
dev_err(dev, "no pinctrl handle\n");
|
||||
ret = PTR_ERR(gf->p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gf->enabled_state = pinctrl_lookup_state(gf->p, "enabled");
|
||||
if (IS_ERR(gf->enabled_state))
|
||||
dev_err(dev, "no enabled pin control state\n");
|
||||
|
||||
gf->disabled_state = pinctrl_lookup_state(gf->p, "disabled");
|
||||
if (IS_ERR(gf->enabled_state)) {
|
||||
dev_err(dev, "no disabled pin control state\n");
|
||||
} else {
|
||||
ret = pinctrl_select_state(gf->p, gf->disabled_state);
|
||||
if (ret)
|
||||
dev_err(gf->dev, "failed to disable pins\n");
|
||||
}
|
||||
|
||||
map->read = gemini_flash_map_read;
|
||||
map->write = gemini_flash_map_write;
|
||||
map->copy_from = gemini_flash_map_copy_from;
|
||||
map->copy_to = gemini_flash_map_copy_to;
|
||||
|
||||
dev_info(dev, "initialized Gemini-specific physmap control\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/mtd/map.h>
|
||||
|
||||
#ifdef CONFIG_MTD_PHYSMAP_OF_GEMINI
|
||||
#ifdef CONFIG_MTD_PHYSMAP_GEMINI
|
||||
int of_flash_probe_gemini(struct platform_device *pdev,
|
||||
struct device_node *np,
|
||||
struct map_info *map);
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/bitops.h>
|
||||
#include "physmap_of_versatile.h"
|
||||
#include "physmap-versatile.h"
|
||||
|
||||
static struct regmap *syscon_regmap;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/mtd/map.h>
|
||||
|
||||
#ifdef CONFIG_MTD_PHYSMAP_OF_VERSATILE
|
||||
#ifdef CONFIG_MTD_PHYSMAP_VERSATILE
|
||||
int of_flash_probe_versatile(struct platform_device *pdev,
|
||||
struct device_node *np,
|
||||
struct map_info *map);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user