Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-spi into next
- SPI NOT OF partitions (Marek Behún) - Macronic SPI NAND (Jaime Liao) - Macronix MX66UW2G345G SPI NOR (zhengxun)
This commit is contained in:
commit
67edf2553f
@ -126,6 +126,13 @@ static void mtd_show_device(struct mtd_info *mtd)
|
||||
printf(" - driver: %s\n", mtd->dev->driver->name);
|
||||
}
|
||||
#endif
|
||||
if (IS_ENABLED(CONFIG_OF_CONTROL) && mtd->dev) {
|
||||
char buf[256];
|
||||
int res;
|
||||
|
||||
res = ofnode_get_path(mtd_get_ofnode(mtd), buf, 256);
|
||||
printf(" - path: %s\n", res == 0 ? buf : "unavailable");
|
||||
}
|
||||
|
||||
/* MTD device information */
|
||||
printf(" - type: ");
|
||||
@ -535,7 +542,7 @@ static char mtd_help_text[] =
|
||||
"mtd bad <name>\n"
|
||||
"\n"
|
||||
"With:\n"
|
||||
"\t<name>: NAND partition/chip name\n"
|
||||
"\t<name>: NAND partition/chip name (or corresponding DM device name or OF path)\n"
|
||||
"\t<addr>: user address from/to which data will be retrieved/stored\n"
|
||||
"\t<off>: offset in <name> in bytes (default: start of the part)\n"
|
||||
"\t\t* must be block-aligned for erase\n"
|
||||
|
@ -286,6 +286,31 @@ const char *ofnode_get_name(ofnode node)
|
||||
return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL);
|
||||
}
|
||||
|
||||
int ofnode_get_path(ofnode node, char *buf, int buflen)
|
||||
{
|
||||
assert(ofnode_valid(node));
|
||||
|
||||
if (ofnode_is_np(node)) {
|
||||
if (strlen(node.np->full_name) >= buflen)
|
||||
return -ENOSPC;
|
||||
|
||||
strcpy(buf, node.np->full_name);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
int res;
|
||||
|
||||
res = fdt_get_path(gd->fdt_blob, ofnode_to_offset(node), buf,
|
||||
buflen);
|
||||
if (!res)
|
||||
return res;
|
||||
else if (res == -FDT_ERR_NOSPACE)
|
||||
return -ENOSPC;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ofnode ofnode_get_by_phandle(uint phandle)
|
||||
{
|
||||
ofnode node;
|
||||
@ -299,7 +324,8 @@ ofnode ofnode_get_by_phandle(uint phandle)
|
||||
return node;
|
||||
}
|
||||
|
||||
fdt_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size)
|
||||
static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index,
|
||||
fdt_size_t *size, bool translate)
|
||||
{
|
||||
int na, ns;
|
||||
|
||||
@ -319,7 +345,7 @@ fdt_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size)
|
||||
|
||||
ns = of_n_size_cells(ofnode_to_np(node));
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF_TRANSLATE) && ns > 0) {
|
||||
if (translate && IS_ENABLED(CONFIG_OF_TRANSLATE) && ns > 0) {
|
||||
return of_translate_address(ofnode_to_np(node), prop_val);
|
||||
} else {
|
||||
na = of_n_addr_cells(ofnode_to_np(node));
|
||||
@ -330,12 +356,24 @@ fdt_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size)
|
||||
ns = ofnode_read_simple_size_cells(ofnode_get_parent(node));
|
||||
return fdtdec_get_addr_size_fixed(gd->fdt_blob,
|
||||
ofnode_to_offset(node), "reg",
|
||||
index, na, ns, size, true);
|
||||
index, na, ns, size,
|
||||
translate);
|
||||
}
|
||||
|
||||
return FDT_ADDR_T_NONE;
|
||||
}
|
||||
|
||||
fdt_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size)
|
||||
{
|
||||
return __ofnode_get_addr_size_index(node, index, size, true);
|
||||
}
|
||||
|
||||
fdt_addr_t ofnode_get_addr_size_index_notrans(ofnode node, int index,
|
||||
fdt_size_t *size)
|
||||
{
|
||||
return __ofnode_get_addr_size_index(node, index, size, false);
|
||||
}
|
||||
|
||||
fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
|
||||
{
|
||||
fdt_size_t size;
|
||||
|
@ -9,21 +9,6 @@
|
||||
#include <errno.h>
|
||||
#include <mtd.h>
|
||||
|
||||
/**
|
||||
* mtd_probe - Probe the device @dev if not already done
|
||||
*
|
||||
* @dev: U-Boot device to probe
|
||||
*
|
||||
* @return 0 on success, an error otherwise.
|
||||
*/
|
||||
int mtd_probe(struct udevice *dev)
|
||||
{
|
||||
if (device_active(dev))
|
||||
return 0;
|
||||
|
||||
return device_probe(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement a MTD uclass which should include most flash drivers.
|
||||
* The uclass private is pointed to mtd_info.
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <malloc.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
@ -106,18 +107,26 @@ int mtd_search_alternate_name(const char *mtdname, char *altname,
|
||||
static void mtd_probe_uclass_mtd_devs(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int idx = 0;
|
||||
|
||||
/* Probe devices with DM compliant drivers */
|
||||
while (!uclass_find_device(UCLASS_MTD, idx, &dev) && dev) {
|
||||
mtd_probe(dev);
|
||||
idx++;
|
||||
}
|
||||
uclass_foreach_dev_probe(UCLASS_MTD, dev)
|
||||
;
|
||||
}
|
||||
#else
|
||||
static void mtd_probe_uclass_mtd_devs(void) { }
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_DM_SPI_FLASH) && IS_ENABLED(CONFIG_SPI_FLASH_MTD)
|
||||
static void mtd_probe_uclass_spi_nor_devs(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
|
||||
uclass_foreach_dev_probe(UCLASS_SPI_FLASH, dev)
|
||||
;
|
||||
}
|
||||
#else
|
||||
static void mtd_probe_uclass_spi_nor_devs(void) { }
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MTD_PARTITIONS)
|
||||
|
||||
#define MTDPARTS_MAXLEN 512
|
||||
@ -198,53 +207,11 @@ static void mtd_del_all_parts(void)
|
||||
} while (ret > 0);
|
||||
}
|
||||
|
||||
int mtd_probe_devices(void)
|
||||
static int parse_mtdparts(const char *mtdparts, const char *mtdids)
|
||||
{
|
||||
static char *old_mtdparts;
|
||||
static char *old_mtdids;
|
||||
const char *mtdparts = get_mtdparts();
|
||||
const char *mtdids = get_mtdids();
|
||||
const char *mtdparts_next = mtdparts;
|
||||
const char *mtdparts_next;
|
||||
struct mtd_info *mtd;
|
||||
|
||||
mtd_probe_uclass_mtd_devs();
|
||||
|
||||
/*
|
||||
* Check if mtdparts/mtdids changed, if the MTD dev list was updated
|
||||
* or if our previous attempt to delete existing partititions failed.
|
||||
* In any of these cases we want to update the partitions, otherwise,
|
||||
* everything is up-to-date and we can return 0 directly.
|
||||
*/
|
||||
if ((!mtdparts && !old_mtdparts && !mtdids && !old_mtdids) ||
|
||||
(mtdparts && old_mtdparts && mtdids && old_mtdids &&
|
||||
!mtd_dev_list_updated() && !mtd_del_all_parts_failed &&
|
||||
!strcmp(mtdparts, old_mtdparts) &&
|
||||
!strcmp(mtdids, old_mtdids)))
|
||||
return 0;
|
||||
|
||||
/* Update the local copy of mtdparts */
|
||||
free(old_mtdparts);
|
||||
free(old_mtdids);
|
||||
old_mtdparts = strdup(mtdparts);
|
||||
old_mtdids = strdup(mtdids);
|
||||
|
||||
/*
|
||||
* Remove all old parts. Note that partition removal can fail in case
|
||||
* one of the partition is still being used by an MTD user, so this
|
||||
* does not guarantee that all old partitions are gone.
|
||||
*/
|
||||
mtd_del_all_parts();
|
||||
|
||||
/*
|
||||
* Call mtd_dev_list_updated() to clear updates generated by our own
|
||||
* parts removal loop.
|
||||
*/
|
||||
mtd_dev_list_updated();
|
||||
|
||||
/* If either mtdparts or mtdids is empty, then exit */
|
||||
if (!mtdparts || !mtdids)
|
||||
return 0;
|
||||
|
||||
/* Start the parsing by ignoring the extra 'mtdparts=' prefix, if any */
|
||||
if (!strncmp(mtdparts, "mtdparts=", sizeof("mtdparts=") - 1))
|
||||
mtdparts += 9;
|
||||
@ -343,6 +310,67 @@ int mtd_probe_devices(void)
|
||||
put_mtd_device(mtd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtd_probe_devices(void)
|
||||
{
|
||||
static char *old_mtdparts;
|
||||
static char *old_mtdids;
|
||||
const char *mtdparts = get_mtdparts();
|
||||
const char *mtdids = get_mtdids();
|
||||
struct mtd_info *mtd;
|
||||
|
||||
mtd_probe_uclass_mtd_devs();
|
||||
mtd_probe_uclass_spi_nor_devs();
|
||||
|
||||
/*
|
||||
* Check if mtdparts/mtdids changed, if the MTD dev list was updated
|
||||
* or if our previous attempt to delete existing partititions failed.
|
||||
* In any of these cases we want to update the partitions, otherwise,
|
||||
* everything is up-to-date and we can return 0 directly.
|
||||
*/
|
||||
if ((!mtdparts && !old_mtdparts && !mtdids && !old_mtdids) ||
|
||||
(mtdparts && old_mtdparts && mtdids && old_mtdids &&
|
||||
!mtd_dev_list_updated() && !mtd_del_all_parts_failed &&
|
||||
!strcmp(mtdparts, old_mtdparts) &&
|
||||
!strcmp(mtdids, old_mtdids)))
|
||||
return 0;
|
||||
|
||||
/* Update the local copy of mtdparts */
|
||||
free(old_mtdparts);
|
||||
free(old_mtdids);
|
||||
old_mtdparts = strdup(mtdparts);
|
||||
old_mtdids = strdup(mtdids);
|
||||
|
||||
/*
|
||||
* Remove all old parts. Note that partition removal can fail in case
|
||||
* one of the partition is still being used by an MTD user, so this
|
||||
* does not guarantee that all old partitions are gone.
|
||||
*/
|
||||
mtd_del_all_parts();
|
||||
|
||||
/*
|
||||
* Call mtd_dev_list_updated() to clear updates generated by our own
|
||||
* parts removal loop.
|
||||
*/
|
||||
mtd_dev_list_updated();
|
||||
|
||||
/* If both mtdparts and mtdids are non-empty, parse */
|
||||
if (mtdparts && mtdids) {
|
||||
if (parse_mtdparts(mtdparts, mtdids) < 0)
|
||||
printf("Failed parsing MTD partitions from mtdparts!\n");
|
||||
}
|
||||
|
||||
/* Fallback to OF partitions */
|
||||
mtd_for_each_device(mtd) {
|
||||
if (list_empty(&mtd->partitions)) {
|
||||
if (add_mtd_partitions_of(mtd) < 0)
|
||||
printf("Failed parsing MTD %s OF partitions!\n",
|
||||
mtd->name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Call mtd_dev_list_updated() to clear updates generated by our own
|
||||
* parts registration loop.
|
||||
@ -355,6 +383,7 @@ int mtd_probe_devices(void)
|
||||
int mtd_probe_devices(void)
|
||||
{
|
||||
mtd_probe_uclass_mtd_devs();
|
||||
mtd_probe_uclass_spi_nor_devs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -768,6 +768,32 @@ int __get_mtd_device(struct mtd_info *mtd)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__get_mtd_device);
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
static bool mtd_device_matches_name(struct mtd_info *mtd, const char *name)
|
||||
{
|
||||
struct udevice *dev = NULL;
|
||||
bool is_part;
|
||||
|
||||
/*
|
||||
* If the first character of mtd name is '/', try interpreting as OF
|
||||
* path. Otherwise try comparing by mtd->name and mtd->dev->name.
|
||||
*/
|
||||
if (*name == '/')
|
||||
device_get_global_by_ofnode(ofnode_path(name), &dev);
|
||||
|
||||
is_part = mtd_is_partition(mtd);
|
||||
|
||||
return (!is_part && dev && mtd->dev == dev) ||
|
||||
!strcmp(name, mtd->name) ||
|
||||
(is_part && mtd->dev && !strcmp(name, mtd->dev->name));
|
||||
}
|
||||
#else
|
||||
static bool mtd_device_matches_name(struct mtd_info *mtd, const char *name)
|
||||
{
|
||||
return !strcmp(name, mtd->name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* get_mtd_device_nm - obtain a validated handle for an MTD device by
|
||||
* device name
|
||||
@ -784,10 +810,19 @@ struct mtd_info *get_mtd_device_nm(const char *name)
|
||||
mutex_lock(&mtd_table_mutex);
|
||||
|
||||
mtd_for_each_device(other) {
|
||||
#ifdef __UBOOT__
|
||||
if (mtd_device_matches_name(other, name)) {
|
||||
if (mtd)
|
||||
printf("\nWarning: MTD name \"%s\" is not unique!\n\n",
|
||||
name);
|
||||
mtd = other;
|
||||
}
|
||||
#else /* !__UBOOT__ */
|
||||
if (!strcmp(name, other->name)) {
|
||||
mtd = other;
|
||||
break;
|
||||
}
|
||||
#endif /* !__UBOOT__ */
|
||||
}
|
||||
|
||||
if (!mtd)
|
||||
|
@ -892,6 +892,69 @@ int add_mtd_partitions(struct mtd_info *master,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
int add_mtd_partitions_of(struct mtd_info *master)
|
||||
{
|
||||
ofnode parts, child;
|
||||
int i = 0;
|
||||
|
||||
if (!master->dev)
|
||||
return 0;
|
||||
|
||||
parts = ofnode_find_subnode(mtd_get_ofnode(master), "partitions");
|
||||
if (!ofnode_valid(parts) || !ofnode_is_available(parts) ||
|
||||
!ofnode_device_is_compatible(parts, "fixed-partitions"))
|
||||
return 0;
|
||||
|
||||
ofnode_for_each_subnode(child, parts) {
|
||||
struct mtd_partition part = { 0 };
|
||||
struct mtd_info *slave;
|
||||
fdt_addr_t offset, size;
|
||||
|
||||
if (!ofnode_is_available(child))
|
||||
continue;
|
||||
|
||||
offset = ofnode_get_addr_size_index_notrans(child, 0, &size);
|
||||
if (offset == FDT_ADDR_T_NONE || !size) {
|
||||
debug("Missing partition offset/size on \"%s\" partition\n",
|
||||
master->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
part.name = ofnode_read_string(child, "label");
|
||||
if (!part.name)
|
||||
part.name = ofnode_read_string(child, "name");
|
||||
|
||||
/*
|
||||
* .mask_flags is used to remove flags in allocate_partition(),
|
||||
* so when "read-only" is present, we add MTD_WRITABLE to the
|
||||
* mask, and so MTD_WRITABLE will be removed on partition
|
||||
* allocation
|
||||
*/
|
||||
if (ofnode_read_bool(child, "read-only"))
|
||||
part.mask_flags |= MTD_WRITEABLE;
|
||||
if (ofnode_read_bool(child, "lock"))
|
||||
part.mask_flags |= MTD_POWERUP_LOCK;
|
||||
|
||||
part.offset = offset;
|
||||
part.size = size;
|
||||
part.ecclayout = master->ecclayout;
|
||||
|
||||
slave = allocate_partition(master, &part, i++, 0);
|
||||
if (IS_ERR(slave))
|
||||
return PTR_ERR(slave);
|
||||
|
||||
mutex_lock(&mtd_partitions_mutex);
|
||||
list_add_tail(&slave->node, &master->partitions);
|
||||
mutex_unlock(&mtd_partitions_mutex);
|
||||
|
||||
add_mtd_device(slave);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(OF_CONTROL) */
|
||||
|
||||
#ifndef __UBOOT__
|
||||
static DEFINE_SPINLOCK(part_parser_lock);
|
||||
static LIST_HEAD(part_parsers);
|
||||
|
@ -114,6 +114,52 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
SPINAND_INFO("MX35UF4GE4AD", 0xb7,
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35UF2GE4AD", 0xa6,
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35UF2GE4AC", 0xa2,
|
||||
NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
|
||||
NAND_ECCREQ(4, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35UF1GE4AD", 0x96,
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35UF1GE4AC", 0x92,
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
|
||||
NAND_ECCREQ(4, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
|
||||
};
|
||||
|
||||
static int macronix_spinand_detect(struct spinand_device *spinand)
|
||||
|
@ -81,14 +81,14 @@ int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash);
|
||||
|
||||
#if CONFIG_IS_ENABLED(SPI_FLASH_MTD)
|
||||
int spi_flash_mtd_register(struct spi_flash *flash);
|
||||
void spi_flash_mtd_unregister(void);
|
||||
void spi_flash_mtd_unregister(struct spi_flash *flash);
|
||||
#else
|
||||
static inline int spi_flash_mtd_register(struct spi_flash *flash)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void spi_flash_mtd_unregister(void)
|
||||
static inline void spi_flash_mtd_unregister(struct spi_flash *flash)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
@ -10,6 +10,20 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <spi_flash.h>
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_SPI_FLASH)
|
||||
|
||||
int spi_flash_mtd_register(struct spi_flash *flash)
|
||||
{
|
||||
return add_mtd_device(&flash->mtd);
|
||||
}
|
||||
|
||||
void spi_flash_mtd_unregister(struct spi_flash *flash)
|
||||
{
|
||||
del_mtd_device(&flash->mtd);
|
||||
}
|
||||
|
||||
#else /* !CONFIG_IS_ENABLED(DM_SPI_FLASH) */
|
||||
|
||||
static struct mtd_info sf_mtd_info;
|
||||
static bool sf_mtd_registered;
|
||||
static char sf_mtd_name[8];
|
||||
@ -111,6 +125,7 @@ int spi_flash_mtd_register(struct spi_flash *flash)
|
||||
|
||||
sf_mtd_info.size = flash->size;
|
||||
sf_mtd_info.priv = flash;
|
||||
sf_mtd_info.dev = flash->dev;
|
||||
|
||||
/* Only uniform flash devices for now */
|
||||
sf_mtd_info.numeraseregions = 0;
|
||||
@ -123,7 +138,7 @@ int spi_flash_mtd_register(struct spi_flash *flash)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void spi_flash_mtd_unregister(void)
|
||||
void spi_flash_mtd_unregister(struct spi_flash *flash)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -146,3 +161,5 @@ void spi_flash_mtd_unregister(void)
|
||||
printf("Failed to unregister MTD %s and the spi_flash object is going away: you're in deep trouble!",
|
||||
sf_mtd_info.name);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_IS_ENABLED(DM_SPI_FLASH) */
|
||||
|
@ -84,7 +84,7 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
|
||||
void spi_flash_free(struct spi_flash *flash)
|
||||
{
|
||||
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
|
||||
spi_flash_mtd_unregister();
|
||||
spi_flash_mtd_unregister(flash);
|
||||
|
||||
spi_free_slave(flash->spi);
|
||||
free(flash);
|
||||
@ -150,8 +150,10 @@ int spi_flash_std_probe(struct udevice *dev)
|
||||
|
||||
static int spi_flash_std_remove(struct udevice *dev)
|
||||
{
|
||||
struct spi_flash *flash = dev_get_uclass_priv(dev);
|
||||
|
||||
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
|
||||
spi_flash_mtd_unregister();
|
||||
spi_flash_mtd_unregister(flash);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2535,6 +2535,7 @@ int spi_nor_scan(struct spi_nor *nor)
|
||||
|
||||
if (!mtd->name)
|
||||
mtd->name = info->name;
|
||||
mtd->dev = nor->dev;
|
||||
mtd->priv = nor;
|
||||
mtd->type = MTD_NORFLASH;
|
||||
mtd->writesize = 1;
|
||||
|
@ -167,6 +167,7 @@ const struct flash_info spi_nor_ids[] = {
|
||||
{ INFO("mx66l1g45g", 0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ INFO("mx25l1633e", 0xc22415, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) },
|
||||
{ INFO("mx25r6435f", 0xc22817, 0, 64 * 1024, 128, SECT_4K) },
|
||||
{ INFO("mx66uw2g345g", 0xc2943c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPI_FLASH_STMICRO /* STMICRO */
|
||||
|
@ -751,6 +751,7 @@ int spi_nor_scan(struct spi_nor *nor)
|
||||
return ret;
|
||||
|
||||
mtd->name = "spi-flash";
|
||||
mtd->dev = nor->dev;
|
||||
mtd->priv = nor;
|
||||
mtd->type = MTD_NORFLASH;
|
||||
mtd->writesize = 1;
|
||||
|
@ -458,6 +458,16 @@ ofnode ofnode_get_parent(ofnode node);
|
||||
*/
|
||||
const char *ofnode_get_name(ofnode node);
|
||||
|
||||
/**
|
||||
* ofnode_get_path() - get the full path of a node
|
||||
*
|
||||
* @node: valid node to look up
|
||||
* @buf: buffer to write the node path into
|
||||
* @buflen: buffer size
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int ofnode_get_path(ofnode node, char *buf, int buflen);
|
||||
|
||||
/**
|
||||
* ofnode_get_by_phandle() - get ofnode from phandle
|
||||
*
|
||||
@ -489,6 +499,23 @@ int ofnode_read_size(ofnode node, const char *propname);
|
||||
phys_addr_t ofnode_get_addr_size_index(ofnode node, int index,
|
||||
fdt_size_t *size);
|
||||
|
||||
/**
|
||||
* ofnode_get_addr_size_index_notrans() - get an address/size from a node
|
||||
* based on index, without address
|
||||
* translation
|
||||
*
|
||||
* This reads the register address/size from a node based on index.
|
||||
* The resulting address is not translated. Useful for example for on-disk
|
||||
* addresses.
|
||||
*
|
||||
* @node: node to read from
|
||||
* @index: Index of address to read (0 for first)
|
||||
* @size: Pointer to size of the address
|
||||
* @return address, or FDT_ADDR_T_NONE if not present or invalid
|
||||
*/
|
||||
phys_addr_t ofnode_get_addr_size_index_notrans(ofnode node, int index,
|
||||
fdt_size_t *size);
|
||||
|
||||
/**
|
||||
* ofnode_get_addr_index() - get an address from a node
|
||||
*
|
||||
|
@ -581,6 +581,16 @@ static inline int del_mtd_partitions(struct mtd_info *mtd)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MTD_PARTITIONS) && CONFIG_IS_ENABLED(DM) && \
|
||||
CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
int add_mtd_partitions_of(struct mtd_info *master);
|
||||
#else
|
||||
static inline int add_mtd_partitions_of(struct mtd_info *master)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct mtd_info *__mtd_next_device(int i);
|
||||
#define mtd_for_each_device(mtd) \
|
||||
for ((mtd) = __mtd_next_device(0); \
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
|
||||
int mtd_probe(struct udevice *dev);
|
||||
int mtd_probe_devices(void);
|
||||
|
||||
void board_mtdparts_default(const char **mtdids, const char **mtdparts);
|
||||
|
@ -289,6 +289,32 @@ static int dm_test_ofnode_get_reg(struct unit_test_state *uts)
|
||||
ut_asserteq(FDT_ADDR_T_NONE, addr);
|
||||
ut_asserteq(FDT_SIZE_T_NONE, size);
|
||||
|
||||
node = ofnode_path("/translation-test@8000/noxlatebus@3,300/dev@42");
|
||||
ut_assert(ofnode_valid(node));
|
||||
addr = ofnode_get_addr_size_index_notrans(node, 0, &size);
|
||||
ut_asserteq_64(0x42, addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ofnode_get_reg, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_ofnode_get_path(struct unit_test_state *uts)
|
||||
{
|
||||
const char *path = "/translation-test@8000/noxlatebus@3,300/dev@42";
|
||||
char buf[64];
|
||||
ofnode node;
|
||||
int res;
|
||||
|
||||
node = ofnode_path(path);
|
||||
ut_assert(ofnode_valid(node));
|
||||
|
||||
res = ofnode_get_path(node, buf, 64);
|
||||
ut_asserteq(0, res);
|
||||
ut_asserteq_str(path, buf);
|
||||
|
||||
res = ofnode_get_path(node, buf, 32);
|
||||
ut_asserteq(-ENOSPC, res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
|
Loading…
Reference in New Issue
Block a user