Skip to content

Commit edd2b98

Browse files
committed
Merge tag 'mtd/for-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull mtd updates from Miquel Raynal: "Core MTD changes: - We must ignore error -ENOENT from parsers on subpartitions which is a legitimate return value - PM support is added to the intel-dg driver Raw NAND changes: - The major change in this is the support for the Allwinner H616 NAND controller, which lead to numerous changes and cleanups in the driver. - Another notable change in this driver is the use of field_get() and field_prep(), but since the global support for this helpers is going to be merged in the same release as we start using these helpers, we undefine them in the first place to avoid warnings. - Marvell drivers layout handling changes have also landed, they fix previous definitions and abuses that have been made previously, which implied to relax the ECC parameters validation in the core a bit. - The Cadence NAND controller driver gets NV-DDR interface support. SPI NAND changes: - Support for FudanMicro FM25S01BI3 and ESMT F50L1G41LC is added. SPI NOR changes: - Fix SMPT parsing for S25FS-S flash family. They report variable dummy cycles for reads. This results in the default of 0 being used. This works for other Infineon chips, but not for the S25FS-S family. They need 8 dummy cycles. Add fixup hooks to specify that. Also add fixup hooks to fix incorrect map ID data in SFDP. - Add support for a bunch of Winbond flashes. Their block protection information is not discoverable, so they need to have an entry in the flash tables to describe that. - Some cleanups for Micron flash support. - Add support for Micron mt35xu01gbba. - Some SPI controllers like the Intel one on the PCI bus do not support the read CR opcode (0x35). Do not use the opcode if the controller does not support it. Aside from these main changes, there is the usual load of API updates, kdoc fixes, potential memory leaks fixes, etc" * tag 'mtd/for-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (51 commits) mtd: sm_ftl: Fix typo in comment in sm_read_lba mtd: sm_ftl: Replace deprecated strncpy with sysfs_emit in sm_attr_show mtd: lpddr_cmds: fix signed shifts in lpddr_cmds mtd: docg3: fix kernel-doc warnings mtd: spinand: add support for FudanMicro FM25S01BI3 mtd: rawnand: renesas: Handle devm_pm_runtime_enable() errors mtd: nand: realtek-ecc: Fix Kconfig dependencies mtd: rawnand: sunxi: #undef field_{get,prep}() before local definition mailmap: update Pratyush Yadav's email address mtd: spi-nor: core: Check read CR support mtd: spi-nor: micron-st: add TODO for fixing mt35xu02gcba mtd: spi-nor: micron-st: add mt35xu01gbba support mtd: spi-nor: micron-st: use SFDP of mt35xu512aba mtd: spi-nor: micron-st: move set_octal_dtr to late_init() mtd: spi-nor: micron-st: rename the die_late_init functions mtd: spinand: esmt: add support for F50L1G41LC mtd: rawnand: lpc32xx_slc: Convert to use devm_gpiod_get_optional() mtd: mtdpart: ignore error -ENOENT from parsers on subpartitions mtd: maps: pcmciamtd: fix potential memory leak in pcmciamtd_detach() mtd: spi-nor: spansion: SMPT fixups for S25FS-S ...
2 parents 77956cf + 801b084 commit edd2b98

27 files changed

Lines changed: 1018 additions & 175 deletions

.mailmap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ Peter Oruba <peter.oruba@amd.com>
638638
Peter Oruba <peter@oruba.de>
639639
Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> <pierre-louis.bossart@linux.intel.com>
640640
Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com>
641+
Pratyush Yadav <pratyush@kernel.org> <ptyadav@amazon.de>
641642
Praveen BP <praveenbp@ti.com>
642643
Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com> <pradeepc@codeaurora.org>
643644
Prasad Sodagudi <quic_psodagud@quicinc.com> <psodagud@codeaurora.org>

Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
66

77
title: Allwinner A10 NAND Controller
88

9-
allOf:
10-
- $ref: nand-controller.yaml
11-
129
maintainers:
1310
- Chen-Yu Tsai <wens@csie.org>
1411
- Maxime Ripard <mripard@kernel.org>
@@ -18,21 +15,29 @@ properties:
1815
enum:
1916
- allwinner,sun4i-a10-nand
2017
- allwinner,sun8i-a23-nand-controller
18+
- allwinner,sun50i-h616-nand-controller
19+
2120
reg:
2221
maxItems: 1
2322

2423
interrupts:
2524
maxItems: 1
2625

2726
clocks:
27+
minItems: 2
2828
items:
2929
- description: Bus Clock
3030
- description: Module Clock
31+
- description: ECC Clock
32+
- description: MBus Clock
3133

3234
clock-names:
35+
minItems: 2
3336
items:
3437
- const: ahb
3538
- const: mod
39+
- const: ecc
40+
- const: mbus
3641

3742
resets:
3843
maxItems: 1
@@ -85,6 +90,36 @@ required:
8590

8691
unevaluatedProperties: false
8792

93+
allOf:
94+
- $ref: nand-controller.yaml
95+
96+
- if:
97+
properties:
98+
compatible:
99+
contains:
100+
enum:
101+
- allwinner,sun4i-a10-nand
102+
- allwinner,sun8i-a23-nand-controller
103+
then:
104+
properties:
105+
clocks:
106+
maxItems: 2
107+
clock-names:
108+
maxItems: 2
109+
110+
- if:
111+
properties:
112+
compatible:
113+
contains:
114+
enum:
115+
- allwinner,sun50i-h616-nand-controller
116+
then:
117+
properties:
118+
clocks:
119+
minItems: 4
120+
clock-names:
121+
minItems: 4
122+
88123
examples:
89124
- |
90125
#include <dt-bindings/interrupt-controller/arm-gic.h>

Documentation/devicetree/bindings/mtd/mtd-physmap.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ properties:
6969
minItems: 1
7070
maxItems: 8
7171

72+
clocks:
73+
description: |
74+
Chips may need clocks to be enabled for themselves or for transparent
75+
bridges.
76+
77+
power-domains:
78+
description: |
79+
Chips may need power domains to be enabled for themselves or for
80+
transparent bridges.
81+
7282
bank-width:
7383
description: Width (in bytes) of the bank. Equal to the device width times
7484
the number of interleaved chips.

drivers/mtd/devices/docg3.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,11 @@ struct docg3_cascade {
274274
* @cascade: the cascade this device belongs to
275275
* @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
276276
* @if_cfg: if true, reads are on 16bits, else reads are on 8bits
277-
278277
* @reliable: if 0, docg3 in normal mode, if 1 docg3 in fast mode, if 2 in
279278
* reliable mode
280279
* Fast mode implies more errors than normal mode.
281280
* Reliable mode implies that page 2*n and 2*n+1 are clones.
281+
* @max_block: maximum block number for this device
282282
* @bbt: bad block table cache
283283
* @oob_write_ofs: offset of the MTD where this OOB should belong (ie. in next
284284
* page_write)

drivers/mtd/devices/mtd_intel_dg.c

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@
1515
#include <linux/module.h>
1616
#include <linux/mtd/mtd.h>
1717
#include <linux/mtd/partitions.h>
18+
#include <linux/pm_runtime.h>
1819
#include <linux/string.h>
1920
#include <linux/slab.h>
2021
#include <linux/sizes.h>
2122
#include <linux/types.h>
2223

24+
#define INTEL_DG_NVM_RPM_TIMEOUT_MS 500
25+
2326
struct intel_dg_nvm {
2427
struct kref refcnt;
2528
struct mtd_info mtd;
29+
struct device *dev;
2630
struct mutex lock; /* region access lock */
2731
void __iomem *base;
2832
void __iomem *base2;
@@ -421,6 +425,8 @@ static int intel_dg_nvm_init(struct intel_dg_nvm *nvm, struct device *device,
421425
unsigned int i, n;
422426
int ret;
423427

428+
nvm->dev = device;
429+
424430
/* clean error register, previous errors are ignored */
425431
idg_nvm_error(nvm);
426432

@@ -498,6 +504,7 @@ static int intel_dg_mtd_erase(struct mtd_info *mtd, struct erase_info *info)
498504
size_t len;
499505
u8 region;
500506
u64 addr;
507+
int ret;
501508

502509
if (WARN_ON(!nvm))
503510
return -EINVAL;
@@ -512,20 +519,29 @@ static int intel_dg_mtd_erase(struct mtd_info *mtd, struct erase_info *info)
512519
total_len = info->len;
513520
addr = info->addr;
514521

522+
ret = pm_runtime_resume_and_get(nvm->dev);
523+
if (ret < 0) {
524+
dev_err(&mtd->dev, "rpm: get failed %d\n", ret);
525+
return ret;
526+
}
527+
528+
ret = 0;
515529
guard(mutex)(&nvm->lock);
516530

517531
while (total_len > 0) {
518532
if (!IS_ALIGNED(addr, SZ_4K) || !IS_ALIGNED(total_len, SZ_4K)) {
519533
dev_err(&mtd->dev, "unaligned erase %llx %zx\n", addr, total_len);
520534
info->fail_addr = addr;
521-
return -ERANGE;
535+
ret = -ERANGE;
536+
break;
522537
}
523538

524539
idx = idg_nvm_get_region(nvm, addr);
525540
if (idx >= nvm->nregions) {
526541
dev_err(&mtd->dev, "out of range");
527542
info->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
528-
return -ERANGE;
543+
ret = -ERANGE;
544+
break;
529545
}
530546

531547
from = addr - nvm->regions[idx].offset;
@@ -541,14 +557,16 @@ static int intel_dg_mtd_erase(struct mtd_info *mtd, struct erase_info *info)
541557
if (bytes < 0) {
542558
dev_dbg(&mtd->dev, "erase failed with %zd\n", bytes);
543559
info->fail_addr += nvm->regions[idx].offset;
544-
return bytes;
560+
ret = bytes;
561+
break;
545562
}
546563

547564
addr += len;
548565
total_len -= len;
549566
}
550567

551-
return 0;
568+
pm_runtime_put_autosuspend(nvm->dev);
569+
return ret;
552570
}
553571

554572
static int intel_dg_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
@@ -577,17 +595,24 @@ static int intel_dg_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
577595
if (len > nvm->regions[idx].size - from)
578596
len = nvm->regions[idx].size - from;
579597

598+
ret = pm_runtime_resume_and_get(nvm->dev);
599+
if (ret < 0) {
600+
dev_err(&mtd->dev, "rpm: get failed %zd\n", ret);
601+
return ret;
602+
}
603+
580604
guard(mutex)(&nvm->lock);
581605

582606
ret = idg_read(nvm, region, from, len, buf);
583607
if (ret < 0) {
584608
dev_dbg(&mtd->dev, "read failed with %zd\n", ret);
585-
return ret;
609+
} else {
610+
*retlen = ret;
611+
ret = 0;
586612
}
587613

588-
*retlen = ret;
589-
590-
return 0;
614+
pm_runtime_put_autosuspend(nvm->dev);
615+
return ret;
591616
}
592617

593618
static int intel_dg_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
@@ -616,17 +641,24 @@ static int intel_dg_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
616641
if (len > nvm->regions[idx].size - to)
617642
len = nvm->regions[idx].size - to;
618643

644+
ret = pm_runtime_resume_and_get(nvm->dev);
645+
if (ret < 0) {
646+
dev_err(&mtd->dev, "rpm: get failed %zd\n", ret);
647+
return ret;
648+
}
649+
619650
guard(mutex)(&nvm->lock);
620651

621652
ret = idg_write(nvm, region, to, len, buf);
622653
if (ret < 0) {
623654
dev_dbg(&mtd->dev, "write failed with %zd\n", ret);
624-
return ret;
655+
} else {
656+
*retlen = ret;
657+
ret = 0;
625658
}
626659

627-
*retlen = ret;
628-
629-
return 0;
660+
pm_runtime_put_autosuspend(nvm->dev);
661+
return ret;
630662
}
631663

632664
static void intel_dg_nvm_release(struct kref *kref)
@@ -753,6 +785,21 @@ static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev,
753785
}
754786
nvm->nregions = n; /* in case where kasprintf fail */
755787

788+
ret = devm_pm_runtime_enable(device);
789+
if (ret < 0) {
790+
dev_err(device, "rpm: enable failed %d\n", ret);
791+
goto err_norpm;
792+
}
793+
794+
pm_runtime_set_autosuspend_delay(device, INTEL_DG_NVM_RPM_TIMEOUT_MS);
795+
pm_runtime_use_autosuspend(device);
796+
797+
ret = pm_runtime_resume_and_get(device);
798+
if (ret < 0) {
799+
dev_err(device, "rpm: get failed %d\n", ret);
800+
goto err_norpm;
801+
}
802+
756803
nvm->base = devm_ioremap_resource(device, &invm->bar);
757804
if (IS_ERR(nvm->base)) {
758805
ret = PTR_ERR(nvm->base);
@@ -781,9 +828,12 @@ static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev,
781828

782829
dev_set_drvdata(&aux_dev->dev, nvm);
783830

831+
pm_runtime_put(device);
784832
return 0;
785833

786834
err:
835+
pm_runtime_put(device);
836+
err_norpm:
787837
kref_put(&nvm->refcnt, intel_dg_nvm_release);
788838
return ret;
789839
}

drivers/mtd/lpddr/lpddr_cmds.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
7979
mutex_init(&shared[i].lock);
8080
for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) {
8181
*chip = lpddr->chips[i];
82-
chip->start += j << lpddr->chipshift;
82+
chip->start += (unsigned long)j << lpddr->chipshift;
8383
chip->oldstate = chip->state = FL_READY;
8484
chip->priv = &shared[i];
8585
/* those should be reset too since
@@ -559,7 +559,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
559559
break;
560560

561561
if ((len + ofs - 1) >> lpddr->chipshift)
562-
thislen = (1<<lpddr->chipshift) - ofs;
562+
thislen = (1UL << lpddr->chipshift) - ofs;
563563
else
564564
thislen = len;
565565
/* get the chip */
@@ -575,7 +575,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
575575
len -= thislen;
576576

577577
ofs = 0;
578-
last_end += 1 << lpddr->chipshift;
578+
last_end += 1UL << lpddr->chipshift;
579579
chipnum++;
580580
chip = &lpddr->chips[chipnum];
581581
}
@@ -601,7 +601,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
601601
break;
602602

603603
if ((len + ofs - 1) >> lpddr->chipshift)
604-
thislen = (1<<lpddr->chipshift) - ofs;
604+
thislen = (1UL << lpddr->chipshift) - ofs;
605605
else
606606
thislen = len;
607607

drivers/mtd/maps/pcmciamtd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
665665
}
666666

667667
pcmciamtd_release(link);
668+
kfree(dev);
668669
}
669670

670671

drivers/mtd/mtdpart.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,12 @@ int add_mtd_partitions(struct mtd_info *parent,
425425

426426
mtd_add_partition_attrs(child);
427427

428-
/* Look for subpartitions */
428+
/* Look for subpartitions (skip if no maching parser found) */
429429
ret = parse_mtd_partitions(child, parts[i].types, NULL);
430-
if (ret < 0) {
430+
if (ret < 0 && ret == -ENOENT) {
431+
pr_debug("Skip parsing subpartitions: %d\n", ret);
432+
continue;
433+
} else if (ret < 0) {
431434
pr_err("Failed to parse subpartitions: %d\n", ret);
432435
goto err_del_partitions;
433436
}

0 commit comments

Comments
 (0)