From: Nick Hainke Date: Tue, 27 Dec 2022 10:22:18 +0000 (+0100) Subject: bcm47xx: add tags to upstreamed patches X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=defd016aefb5135e651ecfbffcfa2d5caf1cba7e;p=openwrt%2Fstaging%2Fjow.git bcm47xx: add tags to upstreamed patches All of the mtd patches are upstreamed to 5.18. Add tags indicating this. Signed-off-by: Nick Hainke --- diff --git a/target/linux/bcm47xx/patches-5.10/100-mtd-rawnand-brcmnand-Assign-soc-as-early-as-possible.patch b/target/linux/bcm47xx/patches-5.10/100-mtd-rawnand-brcmnand-Assign-soc-as-early-as-possible.patch deleted file mode 100644 index 8efda10809..0000000000 --- a/target/linux/bcm47xx/patches-5.10/100-mtd-rawnand-brcmnand-Assign-soc-as-early-as-possible.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Florian Fainelli -Subject: [PATCH v3 1/9] mtd: rawnand: brcmnand: Assign soc as early as possible -Date: Fri, 07 Jan 2022 10:46:06 -0800 -Content-Type: text/plain; charset="utf-8" - -In order to key off the brcmnand_probe() code in subsequent changes -depending upon ctrl->soc, assign that variable as early as possible, -instead of much later when we have checked that it is non-NULL. - -Signed-off-by: Florian Fainelli ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -2949,6 +2949,7 @@ int brcmnand_probe(struct platform_devic - - dev_set_drvdata(dev, ctrl); - ctrl->dev = dev; -+ ctrl->soc = soc; - - init_completion(&ctrl->done); - init_completion(&ctrl->dma_done); -@@ -3089,8 +3090,6 @@ int brcmnand_probe(struct platform_devic - * interesting ways - */ - if (soc) { -- ctrl->soc = soc; -- - ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, - DRV_NAME, ctrl); - diff --git a/target/linux/bcm47xx/patches-5.10/100-v5.18-mtd-rawnand-brcmnand-Assign-soc-as-early-as-possible.patch b/target/linux/bcm47xx/patches-5.10/100-v5.18-mtd-rawnand-brcmnand-Assign-soc-as-early-as-possible.patch new file mode 100644 index 0000000000..8efda10809 --- /dev/null +++ b/target/linux/bcm47xx/patches-5.10/100-v5.18-mtd-rawnand-brcmnand-Assign-soc-as-early-as-possible.patch @@ -0,0 +1,33 @@ +From: Florian Fainelli +Subject: [PATCH v3 1/9] mtd: rawnand: brcmnand: Assign soc as early as possible +Date: Fri, 07 Jan 2022 10:46:06 -0800 +Content-Type: text/plain; charset="utf-8" + +In order to key off the brcmnand_probe() code in subsequent changes +depending upon ctrl->soc, assign that variable as early as possible, +instead of much later when we have checked that it is non-NULL. + +Signed-off-by: Florian Fainelli +--- + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -2949,6 +2949,7 @@ int brcmnand_probe(struct platform_devic + + dev_set_drvdata(dev, ctrl); + ctrl->dev = dev; ++ ctrl->soc = soc; + + init_completion(&ctrl->done); + init_completion(&ctrl->dma_done); +@@ -3089,8 +3090,6 @@ int brcmnand_probe(struct platform_devic + * interesting ways + */ + if (soc) { +- ctrl->soc = soc; +- + ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, + DRV_NAME, ctrl); + diff --git a/target/linux/bcm47xx/patches-5.10/101-mtd-rawnand-brcmnand-Allow-SoC-to-provide-I-O-operations.patch b/target/linux/bcm47xx/patches-5.10/101-mtd-rawnand-brcmnand-Allow-SoC-to-provide-I-O-operations.patch deleted file mode 100644 index 23f5df3015..0000000000 --- a/target/linux/bcm47xx/patches-5.10/101-mtd-rawnand-brcmnand-Allow-SoC-to-provide-I-O-operations.patch +++ /dev/null @@ -1,150 +0,0 @@ -From: Florian Fainelli -Subject: [PATCH v3 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations -Date: Fri, 07 Jan 2022 10:46:07 -0800 -Content-Type: text/plain; charset="utf-8" - -Allow a brcmnand_soc instance to provide a custom set of I/O operations -which we will require when using this driver on a BCMA bus which is not -directly memory mapped I/O. Update the nand_{read,write}_reg accordingly -to use the SoC operations if provided. - -To minimize the penalty on other SoCs which do support standard MMIO -accesses, we use a static key which is disabled by default and gets -enabled if a soc implementation does provide I/O operations. - -Signed-off-by: Florian Fainelli ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 28 +++++++++++++++++++++-- - drivers/mtd/nand/raw/brcmnand/brcmnand.h | 29 ++++++++++++++++++++++++ - 2 files changed, 55 insertions(+), 2 deletions(-) - ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -207,6 +208,8 @@ enum { - - struct brcmnand_host; - -+static DEFINE_STATIC_KEY_FALSE(brcmnand_soc_has_ops_key); -+ - struct brcmnand_controller { - struct device *dev; - struct nand_controller controller; -@@ -589,15 +592,25 @@ enum { - INTFC_CTLR_READY = BIT(31), - }; - -+static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) -+{ -+ return static_branch_unlikely(&brcmnand_soc_has_ops_key); -+} -+ - static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs) - { -+ if (brcmnand_non_mmio_ops(ctrl)) -+ return brcmnand_soc_read(ctrl->soc, offs); - return brcmnand_readl(ctrl->nand_base + offs); - } - - static inline void nand_writereg(struct brcmnand_controller *ctrl, u32 offs, - u32 val) - { -- brcmnand_writel(val, ctrl->nand_base + offs); -+ if (brcmnand_non_mmio_ops(ctrl)) -+ brcmnand_soc_write(ctrl->soc, val, offs); -+ else -+ brcmnand_writel(val, ctrl->nand_base + offs); - } - - static int brcmnand_revision_init(struct brcmnand_controller *ctrl) -@@ -763,13 +776,18 @@ static inline void brcmnand_rmw_reg(stru - - static inline u32 brcmnand_read_fc(struct brcmnand_controller *ctrl, int word) - { -+ if (brcmnand_non_mmio_ops(ctrl)) -+ return brcmnand_soc_read(ctrl->soc, BRCMNAND_NON_MMIO_FC_ADDR); - return __raw_readl(ctrl->nand_fc + word * 4); - } - - static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl, - int word, u32 val) - { -- __raw_writel(val, ctrl->nand_fc + word * 4); -+ if (brcmnand_non_mmio_ops(ctrl)) -+ brcmnand_soc_write(ctrl->soc, val, BRCMNAND_NON_MMIO_FC_ADDR); -+ else -+ __raw_writel(val, ctrl->nand_fc + word * 4); - } - - static inline void edu_writel(struct brcmnand_controller *ctrl, -@@ -2951,6 +2969,12 @@ int brcmnand_probe(struct platform_devic - ctrl->dev = dev; - ctrl->soc = soc; - -+ /* Enable the static key if the soc provides I/O operations indicating -+ * that a non-memory mapped IO access path must be used -+ */ -+ if (brcmnand_soc_has_ops(ctrl->soc)) -+ static_branch_enable(&brcmnand_soc_has_ops_key); -+ - init_completion(&ctrl->done); - init_completion(&ctrl->dma_done); - init_completion(&ctrl->edu_done); ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h -@@ -11,12 +11,25 @@ - - struct platform_device; - struct dev_pm_ops; -+struct brcmnand_io_ops; -+ -+/* Special register offset constant to intercept a non-MMIO access -+ * to the flash cache register space. This is intentionally large -+ * not to overlap with an existing offset. -+ */ -+#define BRCMNAND_NON_MMIO_FC_ADDR 0xffffffff - - struct brcmnand_soc { - bool (*ctlrdy_ack)(struct brcmnand_soc *soc); - void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en); - void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare, - bool is_param); -+ const struct brcmnand_io_ops *ops; -+}; -+ -+struct brcmnand_io_ops { -+ u32 (*read_reg)(struct brcmnand_soc *soc, u32 offset); -+ void (*write_reg)(struct brcmnand_soc *soc, u32 val, u32 offset); - }; - - static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc, -@@ -58,6 +71,22 @@ static inline void brcmnand_writel(u32 v - writel_relaxed(val, addr); - } - -+static inline bool brcmnand_soc_has_ops(struct brcmnand_soc *soc) -+{ -+ return soc && soc->ops && soc->ops->read_reg && soc->ops->write_reg; -+} -+ -+static inline u32 brcmnand_soc_read(struct brcmnand_soc *soc, u32 offset) -+{ -+ return soc->ops->read_reg(soc, offset); -+} -+ -+static inline void brcmnand_soc_write(struct brcmnand_soc *soc, u32 val, -+ u32 offset) -+{ -+ soc->ops->write_reg(soc, val, offset); -+} -+ - int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc); - int brcmnand_remove(struct platform_device *pdev); - diff --git a/target/linux/bcm47xx/patches-5.10/101-v5.18-mtd-rawnand-brcmnand-Allow-SoC-to-provide-I-O-operations.patch b/target/linux/bcm47xx/patches-5.10/101-v5.18-mtd-rawnand-brcmnand-Allow-SoC-to-provide-I-O-operations.patch new file mode 100644 index 0000000000..23f5df3015 --- /dev/null +++ b/target/linux/bcm47xx/patches-5.10/101-v5.18-mtd-rawnand-brcmnand-Allow-SoC-to-provide-I-O-operations.patch @@ -0,0 +1,150 @@ +From: Florian Fainelli +Subject: [PATCH v3 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations +Date: Fri, 07 Jan 2022 10:46:07 -0800 +Content-Type: text/plain; charset="utf-8" + +Allow a brcmnand_soc instance to provide a custom set of I/O operations +which we will require when using this driver on a BCMA bus which is not +directly memory mapped I/O. Update the nand_{read,write}_reg accordingly +to use the SoC operations if provided. + +To minimize the penalty on other SoCs which do support standard MMIO +accesses, we use a static key which is disabled by default and gets +enabled if a soc implementation does provide I/O operations. + +Signed-off-by: Florian Fainelli +--- + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 28 +++++++++++++++++++++-- + drivers/mtd/nand/raw/brcmnand/brcmnand.h | 29 ++++++++++++++++++++++++ + 2 files changed, 55 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -207,6 +208,8 @@ enum { + + struct brcmnand_host; + ++static DEFINE_STATIC_KEY_FALSE(brcmnand_soc_has_ops_key); ++ + struct brcmnand_controller { + struct device *dev; + struct nand_controller controller; +@@ -589,15 +592,25 @@ enum { + INTFC_CTLR_READY = BIT(31), + }; + ++static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) ++{ ++ return static_branch_unlikely(&brcmnand_soc_has_ops_key); ++} ++ + static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs) + { ++ if (brcmnand_non_mmio_ops(ctrl)) ++ return brcmnand_soc_read(ctrl->soc, offs); + return brcmnand_readl(ctrl->nand_base + offs); + } + + static inline void nand_writereg(struct brcmnand_controller *ctrl, u32 offs, + u32 val) + { +- brcmnand_writel(val, ctrl->nand_base + offs); ++ if (brcmnand_non_mmio_ops(ctrl)) ++ brcmnand_soc_write(ctrl->soc, val, offs); ++ else ++ brcmnand_writel(val, ctrl->nand_base + offs); + } + + static int brcmnand_revision_init(struct brcmnand_controller *ctrl) +@@ -763,13 +776,18 @@ static inline void brcmnand_rmw_reg(stru + + static inline u32 brcmnand_read_fc(struct brcmnand_controller *ctrl, int word) + { ++ if (brcmnand_non_mmio_ops(ctrl)) ++ return brcmnand_soc_read(ctrl->soc, BRCMNAND_NON_MMIO_FC_ADDR); + return __raw_readl(ctrl->nand_fc + word * 4); + } + + static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl, + int word, u32 val) + { +- __raw_writel(val, ctrl->nand_fc + word * 4); ++ if (brcmnand_non_mmio_ops(ctrl)) ++ brcmnand_soc_write(ctrl->soc, val, BRCMNAND_NON_MMIO_FC_ADDR); ++ else ++ __raw_writel(val, ctrl->nand_fc + word * 4); + } + + static inline void edu_writel(struct brcmnand_controller *ctrl, +@@ -2951,6 +2969,12 @@ int brcmnand_probe(struct platform_devic + ctrl->dev = dev; + ctrl->soc = soc; + ++ /* Enable the static key if the soc provides I/O operations indicating ++ * that a non-memory mapped IO access path must be used ++ */ ++ if (brcmnand_soc_has_ops(ctrl->soc)) ++ static_branch_enable(&brcmnand_soc_has_ops_key); ++ + init_completion(&ctrl->done); + init_completion(&ctrl->dma_done); + init_completion(&ctrl->edu_done); +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h +@@ -11,12 +11,25 @@ + + struct platform_device; + struct dev_pm_ops; ++struct brcmnand_io_ops; ++ ++/* Special register offset constant to intercept a non-MMIO access ++ * to the flash cache register space. This is intentionally large ++ * not to overlap with an existing offset. ++ */ ++#define BRCMNAND_NON_MMIO_FC_ADDR 0xffffffff + + struct brcmnand_soc { + bool (*ctlrdy_ack)(struct brcmnand_soc *soc); + void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en); + void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare, + bool is_param); ++ const struct brcmnand_io_ops *ops; ++}; ++ ++struct brcmnand_io_ops { ++ u32 (*read_reg)(struct brcmnand_soc *soc, u32 offset); ++ void (*write_reg)(struct brcmnand_soc *soc, u32 val, u32 offset); + }; + + static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc, +@@ -58,6 +71,22 @@ static inline void brcmnand_writel(u32 v + writel_relaxed(val, addr); + } + ++static inline bool brcmnand_soc_has_ops(struct brcmnand_soc *soc) ++{ ++ return soc && soc->ops && soc->ops->read_reg && soc->ops->write_reg; ++} ++ ++static inline u32 brcmnand_soc_read(struct brcmnand_soc *soc, u32 offset) ++{ ++ return soc->ops->read_reg(soc, offset); ++} ++ ++static inline void brcmnand_soc_write(struct brcmnand_soc *soc, u32 val, ++ u32 offset) ++{ ++ soc->ops->write_reg(soc, val, offset); ++} ++ + int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc); + int brcmnand_remove(struct platform_device *pdev); + diff --git a/target/linux/bcm47xx/patches-5.10/102-mtd-rawnand-brcmnand-Avoid-pdev-in-brcmnand_init_cs.patch b/target/linux/bcm47xx/patches-5.10/102-mtd-rawnand-brcmnand-Avoid-pdev-in-brcmnand_init_cs.patch deleted file mode 100644 index d9324c2595..0000000000 --- a/target/linux/bcm47xx/patches-5.10/102-mtd-rawnand-brcmnand-Avoid-pdev-in-brcmnand_init_cs.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Florian Fainelli -Subject: [PATCH v3 3/9] mtd: rawnand: brcmnand: Avoid pdev in brcmnand_init_cs() -Date: Fri, 07 Jan 2022 10:46:08 -0800 -Content-Type: text/plain; charset="utf-8" - -In preparation for encapsulating more of what the loop calling -brcmnand_init_cs() does, avoid using platform_device when it is the -device behind platform_device that we are using for printing errors. - -No functional changes introduced. - -Signed-off-by: Florian Fainelli ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -2722,7 +2722,7 @@ static const struct nand_controller_ops - static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) - { - struct brcmnand_controller *ctrl = host->ctrl; -- struct platform_device *pdev = host->pdev; -+ struct device *dev = ctrl->dev; - struct mtd_info *mtd; - struct nand_chip *chip; - int ret; -@@ -2730,7 +2730,7 @@ static int brcmnand_init_cs(struct brcmn - - ret = of_property_read_u32(dn, "reg", &host->cs); - if (ret) { -- dev_err(&pdev->dev, "can't get chip-select\n"); -+ dev_err(dev, "can't get chip-select\n"); - return -ENXIO; - } - -@@ -2739,13 +2739,13 @@ static int brcmnand_init_cs(struct brcmn - - nand_set_flash_node(chip, dn); - nand_set_controller_data(chip, host); -- mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d", -+ mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d", - host->cs); - if (!mtd->name) - return -ENOMEM; - - mtd->owner = THIS_MODULE; -- mtd->dev.parent = &pdev->dev; -+ mtd->dev.parent = dev; - - chip->legacy.cmd_ctrl = brcmnand_cmd_ctrl; - chip->legacy.cmdfunc = brcmnand_cmdfunc; diff --git a/target/linux/bcm47xx/patches-5.10/102-v5.18-mtd-rawnand-brcmnand-Avoid-pdev-in-brcmnand_init_cs.patch b/target/linux/bcm47xx/patches-5.10/102-v5.18-mtd-rawnand-brcmnand-Avoid-pdev-in-brcmnand_init_cs.patch new file mode 100644 index 0000000000..d9324c2595 --- /dev/null +++ b/target/linux/bcm47xx/patches-5.10/102-v5.18-mtd-rawnand-brcmnand-Avoid-pdev-in-brcmnand_init_cs.patch @@ -0,0 +1,52 @@ +From: Florian Fainelli +Subject: [PATCH v3 3/9] mtd: rawnand: brcmnand: Avoid pdev in brcmnand_init_cs() +Date: Fri, 07 Jan 2022 10:46:08 -0800 +Content-Type: text/plain; charset="utf-8" + +In preparation for encapsulating more of what the loop calling +brcmnand_init_cs() does, avoid using platform_device when it is the +device behind platform_device that we are using for printing errors. + +No functional changes introduced. + +Signed-off-by: Florian Fainelli +--- + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -2722,7 +2722,7 @@ static const struct nand_controller_ops + static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) + { + struct brcmnand_controller *ctrl = host->ctrl; +- struct platform_device *pdev = host->pdev; ++ struct device *dev = ctrl->dev; + struct mtd_info *mtd; + struct nand_chip *chip; + int ret; +@@ -2730,7 +2730,7 @@ static int brcmnand_init_cs(struct brcmn + + ret = of_property_read_u32(dn, "reg", &host->cs); + if (ret) { +- dev_err(&pdev->dev, "can't get chip-select\n"); ++ dev_err(dev, "can't get chip-select\n"); + return -ENXIO; + } + +@@ -2739,13 +2739,13 @@ static int brcmnand_init_cs(struct brcmn + + nand_set_flash_node(chip, dn); + nand_set_controller_data(chip, host); +- mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d", ++ mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d", + host->cs); + if (!mtd->name) + return -ENOMEM; + + mtd->owner = THIS_MODULE; +- mtd->dev.parent = &pdev->dev; ++ mtd->dev.parent = dev; + + chip->legacy.cmd_ctrl = brcmnand_cmd_ctrl; + chip->legacy.cmdfunc = brcmnand_cmdfunc; diff --git a/target/linux/bcm47xx/patches-5.10/103-mtd-rawnand-brcmnand-Move-OF-operations-out-of-brcmnand_init_cs.patch b/target/linux/bcm47xx/patches-5.10/103-mtd-rawnand-brcmnand-Move-OF-operations-out-of-brcmnand_init_cs.patch deleted file mode 100644 index 34fd1b47ea..0000000000 --- a/target/linux/bcm47xx/patches-5.10/103-mtd-rawnand-brcmnand-Move-OF-operations-out-of-brcmnand_init_cs.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Florian Fainelli -Subject: [PATCH v3 4/9] mtd: rawnand: brcmnand: Move OF operations out of brcmnand_init_cs() -Date: Fri, 07 Jan 2022 10:46:09 -0800 -Content-Type: text/plain; charset="utf-8" - -In order to initialize a given chip select object for use by the -brcmnand driver, move all of the Device Tree specific routines outside -of brcmnand_init_cs() in order to make it usable in a platform data -configuration which will be necessary for supporting BCMA chips. - -No functional changes introduced. - -Signed-off-by: Florian Fainelli ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -2719,7 +2719,7 @@ static const struct nand_controller_ops - .attach_chip = brcmnand_attach_chip, - }; - --static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) -+static int brcmnand_init_cs(struct brcmnand_host *host) - { - struct brcmnand_controller *ctrl = host->ctrl; - struct device *dev = ctrl->dev; -@@ -2728,16 +2728,9 @@ static int brcmnand_init_cs(struct brcmn - int ret; - u16 cfg_offs; - -- ret = of_property_read_u32(dn, "reg", &host->cs); -- if (ret) { -- dev_err(dev, "can't get chip-select\n"); -- return -ENXIO; -- } -- - mtd = nand_to_mtd(&host->chip); - chip = &host->chip; - -- nand_set_flash_node(chip, dn); - nand_set_controller_data(chip, host); - mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d", - host->cs); -@@ -3144,7 +3137,16 @@ int brcmnand_probe(struct platform_devic - host->pdev = pdev; - host->ctrl = ctrl; - -- ret = brcmnand_init_cs(host, child); -+ ret = of_property_read_u32(child, "reg", &host->cs); -+ if (ret) { -+ dev_err(dev, "can't get chip-select\n"); -+ devm_kfree(dev, host); -+ continue; -+ } -+ -+ nand_set_flash_node(&host->chip, child); -+ -+ ret = brcmnand_init_cs(host); - if (ret) { - devm_kfree(dev, host); - continue; /* Try all chip-selects */ diff --git a/target/linux/bcm47xx/patches-5.10/103-v5.18-mtd-rawnand-brcmnand-Move-OF-operations-out-of-brcmnand_init_cs.patch b/target/linux/bcm47xx/patches-5.10/103-v5.18-mtd-rawnand-brcmnand-Move-OF-operations-out-of-brcmnand_init_cs.patch new file mode 100644 index 0000000000..34fd1b47ea --- /dev/null +++ b/target/linux/bcm47xx/patches-5.10/103-v5.18-mtd-rawnand-brcmnand-Move-OF-operations-out-of-brcmnand_init_cs.patch @@ -0,0 +1,63 @@ +From: Florian Fainelli +Subject: [PATCH v3 4/9] mtd: rawnand: brcmnand: Move OF operations out of brcmnand_init_cs() +Date: Fri, 07 Jan 2022 10:46:09 -0800 +Content-Type: text/plain; charset="utf-8" + +In order to initialize a given chip select object for use by the +brcmnand driver, move all of the Device Tree specific routines outside +of brcmnand_init_cs() in order to make it usable in a platform data +configuration which will be necessary for supporting BCMA chips. + +No functional changes introduced. + +Signed-off-by: Florian Fainelli +--- + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -2719,7 +2719,7 @@ static const struct nand_controller_ops + .attach_chip = brcmnand_attach_chip, + }; + +-static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) ++static int brcmnand_init_cs(struct brcmnand_host *host) + { + struct brcmnand_controller *ctrl = host->ctrl; + struct device *dev = ctrl->dev; +@@ -2728,16 +2728,9 @@ static int brcmnand_init_cs(struct brcmn + int ret; + u16 cfg_offs; + +- ret = of_property_read_u32(dn, "reg", &host->cs); +- if (ret) { +- dev_err(dev, "can't get chip-select\n"); +- return -ENXIO; +- } +- + mtd = nand_to_mtd(&host->chip); + chip = &host->chip; + +- nand_set_flash_node(chip, dn); + nand_set_controller_data(chip, host); + mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d", + host->cs); +@@ -3144,7 +3137,16 @@ int brcmnand_probe(struct platform_devic + host->pdev = pdev; + host->ctrl = ctrl; + +- ret = brcmnand_init_cs(host, child); ++ ret = of_property_read_u32(child, "reg", &host->cs); ++ if (ret) { ++ dev_err(dev, "can't get chip-select\n"); ++ devm_kfree(dev, host); ++ continue; ++ } ++ ++ nand_set_flash_node(&host->chip, child); ++ ++ ret = brcmnand_init_cs(host); + if (ret) { + devm_kfree(dev, host); + continue; /* Try all chip-selects */ diff --git a/target/linux/bcm47xx/patches-5.10/104-mtd-rawnand-brcmnand-Allow-working-without-interrupts.patch b/target/linux/bcm47xx/patches-5.10/104-mtd-rawnand-brcmnand-Allow-working-without-interrupts.patch deleted file mode 100644 index 3a9d18fa21..0000000000 --- a/target/linux/bcm47xx/patches-5.10/104-mtd-rawnand-brcmnand-Allow-working-without-interrupts.patch +++ /dev/null @@ -1,91 +0,0 @@ -From: Florian Fainelli -Subject: [PATCH v3 5/9] mtd: rawnand: brcmnand: Allow working without interrupts -Date: Fri, 07 Jan 2022 10:46:10 -0800 -Content-Type: text/plain; charset="utf-8" - -The BCMA devices include the brcmnand controller but they do not wire up -any interrupt line, allow the main interrupt to be optional and update -the completion path to also check for the lack of an interrupt line. - -Signed-off-by: Florian Fainelli ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 52 +++++++++++------------- - 1 file changed, 24 insertions(+), 28 deletions(-) - ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -216,7 +216,7 @@ struct brcmnand_controller { - void __iomem *nand_base; - void __iomem *nand_fc; /* flash cache */ - void __iomem *flash_dma_base; -- unsigned int irq; -+ int irq; - unsigned int dma_irq; - int nand_version; - -@@ -1590,7 +1590,7 @@ static bool brcmstb_nand_wait_for_comple - bool err = false; - int sts; - -- if (mtd->oops_panic_write) { -+ if (mtd->oops_panic_write || ctrl->irq < 0) { - /* switch to interrupt polling and PIO mode */ - disable_ctrl_irqs(ctrl); - sts = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, -@@ -3095,33 +3095,29 @@ int brcmnand_probe(struct platform_devic - } - - /* IRQ */ -- ctrl->irq = platform_get_irq(pdev, 0); -- if ((int)ctrl->irq < 0) { -- dev_err(dev, "no IRQ defined\n"); -- ret = -ENODEV; -- goto err; -- } -- -- /* -- * Some SoCs integrate this controller (e.g., its interrupt bits) in -- * interesting ways -- */ -- if (soc) { -- ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, -- DRV_NAME, ctrl); -- -- /* Enable interrupt */ -- ctrl->soc->ctlrdy_ack(ctrl->soc); -- ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true); -- } else { -- /* Use standard interrupt infrastructure */ -- ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0, -- DRV_NAME, ctrl); -- } -- if (ret < 0) { -- dev_err(dev, "can't allocate IRQ %d: error %d\n", -- ctrl->irq, ret); -- goto err; -+ ctrl->irq = platform_get_irq_optional(pdev, 0); -+ if (ctrl->irq > 0) { -+ /* -+ * Some SoCs integrate this controller (e.g., its interrupt bits) in -+ * interesting ways -+ */ -+ if (soc) { -+ ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, -+ DRV_NAME, ctrl); -+ -+ /* Enable interrupt */ -+ ctrl->soc->ctlrdy_ack(ctrl->soc); -+ ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true); -+ } else { -+ /* Use standard interrupt infrastructure */ -+ ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0, -+ DRV_NAME, ctrl); -+ } -+ if (ret < 0) { -+ dev_err(dev, "can't allocate IRQ %d: error %d\n", -+ ctrl->irq, ret); -+ goto err; -+ } - } - - for_each_available_child_of_node(dn, child) { diff --git a/target/linux/bcm47xx/patches-5.10/104-v5.18-mtd-rawnand-brcmnand-Allow-working-without-interrupts.patch b/target/linux/bcm47xx/patches-5.10/104-v5.18-mtd-rawnand-brcmnand-Allow-working-without-interrupts.patch new file mode 100644 index 0000000000..3a9d18fa21 --- /dev/null +++ b/target/linux/bcm47xx/patches-5.10/104-v5.18-mtd-rawnand-brcmnand-Allow-working-without-interrupts.patch @@ -0,0 +1,91 @@ +From: Florian Fainelli +Subject: [PATCH v3 5/9] mtd: rawnand: brcmnand: Allow working without interrupts +Date: Fri, 07 Jan 2022 10:46:10 -0800 +Content-Type: text/plain; charset="utf-8" + +The BCMA devices include the brcmnand controller but they do not wire up +any interrupt line, allow the main interrupt to be optional and update +the completion path to also check for the lack of an interrupt line. + +Signed-off-by: Florian Fainelli +--- + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 52 +++++++++++------------- + 1 file changed, 24 insertions(+), 28 deletions(-) + +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -216,7 +216,7 @@ struct brcmnand_controller { + void __iomem *nand_base; + void __iomem *nand_fc; /* flash cache */ + void __iomem *flash_dma_base; +- unsigned int irq; ++ int irq; + unsigned int dma_irq; + int nand_version; + +@@ -1590,7 +1590,7 @@ static bool brcmstb_nand_wait_for_comple + bool err = false; + int sts; + +- if (mtd->oops_panic_write) { ++ if (mtd->oops_panic_write || ctrl->irq < 0) { + /* switch to interrupt polling and PIO mode */ + disable_ctrl_irqs(ctrl); + sts = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, +@@ -3095,33 +3095,29 @@ int brcmnand_probe(struct platform_devic + } + + /* IRQ */ +- ctrl->irq = platform_get_irq(pdev, 0); +- if ((int)ctrl->irq < 0) { +- dev_err(dev, "no IRQ defined\n"); +- ret = -ENODEV; +- goto err; +- } +- +- /* +- * Some SoCs integrate this controller (e.g., its interrupt bits) in +- * interesting ways +- */ +- if (soc) { +- ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, +- DRV_NAME, ctrl); +- +- /* Enable interrupt */ +- ctrl->soc->ctlrdy_ack(ctrl->soc); +- ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true); +- } else { +- /* Use standard interrupt infrastructure */ +- ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0, +- DRV_NAME, ctrl); +- } +- if (ret < 0) { +- dev_err(dev, "can't allocate IRQ %d: error %d\n", +- ctrl->irq, ret); +- goto err; ++ ctrl->irq = platform_get_irq_optional(pdev, 0); ++ if (ctrl->irq > 0) { ++ /* ++ * Some SoCs integrate this controller (e.g., its interrupt bits) in ++ * interesting ways ++ */ ++ if (soc) { ++ ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, ++ DRV_NAME, ctrl); ++ ++ /* Enable interrupt */ ++ ctrl->soc->ctlrdy_ack(ctrl->soc); ++ ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true); ++ } else { ++ /* Use standard interrupt infrastructure */ ++ ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0, ++ DRV_NAME, ctrl); ++ } ++ if (ret < 0) { ++ dev_err(dev, "can't allocate IRQ %d: error %d\n", ++ ctrl->irq, ret); ++ goto err; ++ } + } + + for_each_available_child_of_node(dn, child) { diff --git a/target/linux/bcm47xx/patches-5.10/105-mtd-rawnand-brcmnand-Add-platform-data-structure-for-BCMA.patch b/target/linux/bcm47xx/patches-5.10/105-mtd-rawnand-brcmnand-Add-platform-data-structure-for-BCMA.patch deleted file mode 100644 index 973a3e95ee..0000000000 --- a/target/linux/bcm47xx/patches-5.10/105-mtd-rawnand-brcmnand-Add-platform-data-structure-for-BCMA.patch +++ /dev/null @@ -1,115 +0,0 @@ -From: Florian Fainelli -Subject: [PATCH v3 6/9] mtd: rawnand: brcmnand: Add platform data structure for BCMA -Date: Fri, 07 Jan 2022 10:46:11 -0800 -Content-Type: text/plain; charset="utf-8" - -Update the BCMA's chipcommon nand flash driver to detect which -chip-select is used and pass that information via platform data to the -brcmnand driver. Make sure that the brcmnand platform data structure is -always at the beginning of the platform data of the "nflash" device -created by BCMA to allow brcmnand to safely de-reference it. - -Signed-off-by: Florian Fainelli ---- - MAINTAINERS | 1 + - drivers/bcma/driver_chipcommon_nflash.c | 20 +++++++++++++++++++- - include/linux/bcma/bcma_driver_chipcommon.h | 5 +++++ - include/linux/platform_data/brcmnand.h | 12 ++++++++++++ - 4 files changed, 37 insertions(+), 1 deletion(-) - create mode 100644 include/linux/platform_data/brcmnand.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -3712,6 +3712,7 @@ L: linux-mtd@lists.infradead.org - L: bcm-kernel-feedback-list@broadcom.com - S: Maintained - F: drivers/mtd/nand/raw/brcmnand/ -+F: include/linux/platform_data/brcmnand.h - - BROADCOM SYSTEMPORT ETHERNET DRIVER - M: Florian Fainelli ---- a/drivers/bcma/driver_chipcommon_nflash.c -+++ b/drivers/bcma/driver_chipcommon_nflash.c -@@ -7,18 +7,28 @@ - - #include "bcma_private.h" - -+#include - #include -+#include - #include - -+/* Alternate NAND controller driver name in order to allow both bcm47xxnflash -+ * and bcma_brcmnand to be built into the same kernel image. -+ */ -+static const char *bcma_nflash_alt_name = "bcma_brcmnand"; -+ - struct platform_device bcma_nflash_dev = { - .name = "bcma_nflash", - .num_resources = 0, - }; - -+static const char *probes[] = { "bcm47xxpart", NULL }; -+ - /* Initialize NAND flash access */ - int bcma_nflash_init(struct bcma_drv_cc *cc) - { - struct bcma_bus *bus = cc->core->bus; -+ u32 reg; - - if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && - cc->core->id.rev != 38) { -@@ -33,8 +43,16 @@ int bcma_nflash_init(struct bcma_drv_cc - - cc->nflash.present = true; - if (cc->core->id.rev == 38 && -- (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) -+ (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) { - cc->nflash.boot = true; -+ /* Determine the chip select that is being used */ -+ reg = bcma_cc_read32(cc, BCMA_CC_NAND_CS_NAND_SELECT) & 0xff; -+ cc->nflash.brcmnand_info.chip_select = ffs(reg) - 1; -+ cc->nflash.brcmnand_info.part_probe_types = probes; -+ cc->nflash.brcmnand_info.ecc_stepsize = 512; -+ cc->nflash.brcmnand_info.ecc_strength = 1; -+ bcma_nflash_dev.name = bcma_nflash_alt_name; -+ } - - /* Prepare platform device, but don't register it yet. It's too early, - * malloc (required by device_private_init) is not available yet. */ ---- a/include/linux/bcma/bcma_driver_chipcommon.h -+++ b/include/linux/bcma/bcma_driver_chipcommon.h -@@ -3,6 +3,7 @@ - #define LINUX_BCMA_DRIVER_CC_H_ - - #include -+#include - #include - - /** ChipCommon core registers. **/ -@@ -599,6 +600,10 @@ struct bcma_sflash { - - #ifdef CONFIG_BCMA_NFLASH - struct bcma_nflash { -+ /* Must be the fist member for the brcmnand driver to -+ * de-reference that structure. -+ */ -+ struct brcmnand_platform_data brcmnand_info; - bool present; - bool boot; /* This is the flash the SoC boots from */ - }; ---- /dev/null -+++ b/include/linux/platform_data/brcmnand.h -@@ -0,0 +1,12 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+#ifndef BRCMNAND_PLAT_DATA_H -+#define BRCMNAND_PLAT_DATA_H -+ -+struct brcmnand_platform_data { -+ int chip_select; -+ const char * const *part_probe_types; -+ unsigned int ecc_stepsize; -+ unsigned int ecc_strength; -+}; -+ -+#endif /* BRCMNAND_PLAT_DATA_H */ diff --git a/target/linux/bcm47xx/patches-5.10/105-v5.18-mtd-rawnand-brcmnand-Add-platform-data-structure-for-BCMA.patch b/target/linux/bcm47xx/patches-5.10/105-v5.18-mtd-rawnand-brcmnand-Add-platform-data-structure-for-BCMA.patch new file mode 100644 index 0000000000..973a3e95ee --- /dev/null +++ b/target/linux/bcm47xx/patches-5.10/105-v5.18-mtd-rawnand-brcmnand-Add-platform-data-structure-for-BCMA.patch @@ -0,0 +1,115 @@ +From: Florian Fainelli +Subject: [PATCH v3 6/9] mtd: rawnand: brcmnand: Add platform data structure for BCMA +Date: Fri, 07 Jan 2022 10:46:11 -0800 +Content-Type: text/plain; charset="utf-8" + +Update the BCMA's chipcommon nand flash driver to detect which +chip-select is used and pass that information via platform data to the +brcmnand driver. Make sure that the brcmnand platform data structure is +always at the beginning of the platform data of the "nflash" device +created by BCMA to allow brcmnand to safely de-reference it. + +Signed-off-by: Florian Fainelli +--- + MAINTAINERS | 1 + + drivers/bcma/driver_chipcommon_nflash.c | 20 +++++++++++++++++++- + include/linux/bcma/bcma_driver_chipcommon.h | 5 +++++ + include/linux/platform_data/brcmnand.h | 12 ++++++++++++ + 4 files changed, 37 insertions(+), 1 deletion(-) + create mode 100644 include/linux/platform_data/brcmnand.h + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3712,6 +3712,7 @@ L: linux-mtd@lists.infradead.org + L: bcm-kernel-feedback-list@broadcom.com + S: Maintained + F: drivers/mtd/nand/raw/brcmnand/ ++F: include/linux/platform_data/brcmnand.h + + BROADCOM SYSTEMPORT ETHERNET DRIVER + M: Florian Fainelli +--- a/drivers/bcma/driver_chipcommon_nflash.c ++++ b/drivers/bcma/driver_chipcommon_nflash.c +@@ -7,18 +7,28 @@ + + #include "bcma_private.h" + ++#include + #include ++#include + #include + ++/* Alternate NAND controller driver name in order to allow both bcm47xxnflash ++ * and bcma_brcmnand to be built into the same kernel image. ++ */ ++static const char *bcma_nflash_alt_name = "bcma_brcmnand"; ++ + struct platform_device bcma_nflash_dev = { + .name = "bcma_nflash", + .num_resources = 0, + }; + ++static const char *probes[] = { "bcm47xxpart", NULL }; ++ + /* Initialize NAND flash access */ + int bcma_nflash_init(struct bcma_drv_cc *cc) + { + struct bcma_bus *bus = cc->core->bus; ++ u32 reg; + + if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && + cc->core->id.rev != 38) { +@@ -33,8 +43,16 @@ int bcma_nflash_init(struct bcma_drv_cc + + cc->nflash.present = true; + if (cc->core->id.rev == 38 && +- (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) ++ (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) { + cc->nflash.boot = true; ++ /* Determine the chip select that is being used */ ++ reg = bcma_cc_read32(cc, BCMA_CC_NAND_CS_NAND_SELECT) & 0xff; ++ cc->nflash.brcmnand_info.chip_select = ffs(reg) - 1; ++ cc->nflash.brcmnand_info.part_probe_types = probes; ++ cc->nflash.brcmnand_info.ecc_stepsize = 512; ++ cc->nflash.brcmnand_info.ecc_strength = 1; ++ bcma_nflash_dev.name = bcma_nflash_alt_name; ++ } + + /* Prepare platform device, but don't register it yet. It's too early, + * malloc (required by device_private_init) is not available yet. */ +--- a/include/linux/bcma/bcma_driver_chipcommon.h ++++ b/include/linux/bcma/bcma_driver_chipcommon.h +@@ -3,6 +3,7 @@ + #define LINUX_BCMA_DRIVER_CC_H_ + + #include ++#include + #include + + /** ChipCommon core registers. **/ +@@ -599,6 +600,10 @@ struct bcma_sflash { + + #ifdef CONFIG_BCMA_NFLASH + struct bcma_nflash { ++ /* Must be the fist member for the brcmnand driver to ++ * de-reference that structure. ++ */ ++ struct brcmnand_platform_data brcmnand_info; + bool present; + bool boot; /* This is the flash the SoC boots from */ + }; +--- /dev/null ++++ b/include/linux/platform_data/brcmnand.h +@@ -0,0 +1,12 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++#ifndef BRCMNAND_PLAT_DATA_H ++#define BRCMNAND_PLAT_DATA_H ++ ++struct brcmnand_platform_data { ++ int chip_select; ++ const char * const *part_probe_types; ++ unsigned int ecc_stepsize; ++ unsigned int ecc_strength; ++}; ++ ++#endif /* BRCMNAND_PLAT_DATA_H */ diff --git a/target/linux/bcm47xx/patches-5.10/106-mtd-rawnand-brcmnand-Allow-platform-data-instantation.patch b/target/linux/bcm47xx/patches-5.10/106-mtd-rawnand-brcmnand-Allow-platform-data-instantation.patch deleted file mode 100644 index fb9ee07d04..0000000000 --- a/target/linux/bcm47xx/patches-5.10/106-mtd-rawnand-brcmnand-Allow-platform-data-instantation.patch +++ /dev/null @@ -1,124 +0,0 @@ -From: Florian Fainelli -Subject: [PATCH v3 7/9] mtd: rawnand: brcmnand: Allow platform data instantation -Date: Fri, 07 Jan 2022 10:46:12 -0800 -Content-Type: text/plain; charset="utf-8" - -Make use of the recently refactored code in brcmnand_init_cs() and -derive the chip-select from the platform data that is supplied. Update -the various code paths to avoid relying on possibly non-existent -resources, too. - -Signed-off-by: Florian Fainelli ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 45 ++++++++++++++++++------ - 1 file changed, 35 insertions(+), 10 deletions(-) - ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2719,7 +2720,8 @@ static const struct nand_controller_ops - .attach_chip = brcmnand_attach_chip, - }; - --static int brcmnand_init_cs(struct brcmnand_host *host) -+static int brcmnand_init_cs(struct brcmnand_host *host, -+ const char * const *part_probe_types) - { - struct brcmnand_controller *ctrl = host->ctrl; - struct device *dev = ctrl->dev; -@@ -2772,7 +2774,7 @@ static int brcmnand_init_cs(struct brcmn - if (ret) - return ret; - -- ret = mtd_device_register(mtd, NULL, 0); -+ ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); - if (ret) - nand_cleanup(chip); - -@@ -2941,17 +2943,15 @@ static int brcmnand_edu_setup(struct pla - - int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) - { -+ struct brcmnand_platform_data *pd = dev_get_platdata(&pdev->dev); - struct device *dev = &pdev->dev; - struct device_node *dn = dev->of_node, *child; - struct brcmnand_controller *ctrl; -+ struct brcmnand_host *host; - struct resource *res; - int ret; - -- /* We only support device-tree instantiation */ -- if (!dn) -- return -ENODEV; -- -- if (!of_match_node(brcmnand_of_match, dn)) -+ if (dn && !of_match_node(brcmnand_of_match, dn)) - return -ENODEV; - - ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); -@@ -2978,7 +2978,7 @@ int brcmnand_probe(struct platform_devic - /* NAND register range */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ctrl->nand_base = devm_ioremap_resource(dev, res); -- if (IS_ERR(ctrl->nand_base)) -+ if (IS_ERR(ctrl->nand_base) && !brcmnand_soc_has_ops(soc)) - return PTR_ERR(ctrl->nand_base); - - /* Enable clock before using NAND registers */ -@@ -3122,7 +3122,6 @@ int brcmnand_probe(struct platform_devic - - for_each_available_child_of_node(dn, child) { - if (of_device_is_compatible(child, "brcm,nandcs")) { -- struct brcmnand_host *host; - - host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); - if (!host) { -@@ -3142,7 +3141,7 @@ int brcmnand_probe(struct platform_devic - - nand_set_flash_node(&host->chip, child); - -- ret = brcmnand_init_cs(host); -+ ret = brcmnand_init_cs(host, NULL); - if (ret) { - devm_kfree(dev, host); - continue; /* Try all chip-selects */ -@@ -3152,6 +3151,32 @@ int brcmnand_probe(struct platform_devic - } - } - -+ if (!list_empty(&ctrl->host_list)) -+ return 0; -+ -+ if (!pd) { -+ ret = -ENODEV; -+ goto err; -+ } -+ -+ /* If we got there we must have been probing via platform data */ -+ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); -+ if (!host) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ host->pdev = pdev; -+ host->ctrl = ctrl; -+ host->cs = pd->chip_select; -+ host->chip.ecc.size = pd->ecc_stepsize; -+ host->chip.ecc.strength = pd->ecc_strength; -+ -+ ret = brcmnand_init_cs(host, pd->part_probe_types); -+ if (ret) -+ goto err; -+ -+ list_add_tail(&host->node, &ctrl->host_list); -+ - /* No chip-selects could initialize properly */ - if (list_empty(&ctrl->host_list)) { - ret = -ENODEV; diff --git a/target/linux/bcm47xx/patches-5.10/106-v5.18-mtd-rawnand-brcmnand-Allow-platform-data-instantation.patch b/target/linux/bcm47xx/patches-5.10/106-v5.18-mtd-rawnand-brcmnand-Allow-platform-data-instantation.patch new file mode 100644 index 0000000000..fb9ee07d04 --- /dev/null +++ b/target/linux/bcm47xx/patches-5.10/106-v5.18-mtd-rawnand-brcmnand-Allow-platform-data-instantation.patch @@ -0,0 +1,124 @@ +From: Florian Fainelli +Subject: [PATCH v3 7/9] mtd: rawnand: brcmnand: Allow platform data instantation +Date: Fri, 07 Jan 2022 10:46:12 -0800 +Content-Type: text/plain; charset="utf-8" + +Make use of the recently refactored code in brcmnand_init_cs() and +derive the chip-select from the platform data that is supplied. Update +the various code paths to avoid relying on possibly non-existent +resources, too. + +Signed-off-by: Florian Fainelli +--- + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 45 ++++++++++++++++++------ + 1 file changed, 35 insertions(+), 10 deletions(-) + +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2719,7 +2720,8 @@ static const struct nand_controller_ops + .attach_chip = brcmnand_attach_chip, + }; + +-static int brcmnand_init_cs(struct brcmnand_host *host) ++static int brcmnand_init_cs(struct brcmnand_host *host, ++ const char * const *part_probe_types) + { + struct brcmnand_controller *ctrl = host->ctrl; + struct device *dev = ctrl->dev; +@@ -2772,7 +2774,7 @@ static int brcmnand_init_cs(struct brcmn + if (ret) + return ret; + +- ret = mtd_device_register(mtd, NULL, 0); ++ ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); + if (ret) + nand_cleanup(chip); + +@@ -2941,17 +2943,15 @@ static int brcmnand_edu_setup(struct pla + + int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) + { ++ struct brcmnand_platform_data *pd = dev_get_platdata(&pdev->dev); + struct device *dev = &pdev->dev; + struct device_node *dn = dev->of_node, *child; + struct brcmnand_controller *ctrl; ++ struct brcmnand_host *host; + struct resource *res; + int ret; + +- /* We only support device-tree instantiation */ +- if (!dn) +- return -ENODEV; +- +- if (!of_match_node(brcmnand_of_match, dn)) ++ if (dn && !of_match_node(brcmnand_of_match, dn)) + return -ENODEV; + + ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); +@@ -2978,7 +2978,7 @@ int brcmnand_probe(struct platform_devic + /* NAND register range */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ctrl->nand_base = devm_ioremap_resource(dev, res); +- if (IS_ERR(ctrl->nand_base)) ++ if (IS_ERR(ctrl->nand_base) && !brcmnand_soc_has_ops(soc)) + return PTR_ERR(ctrl->nand_base); + + /* Enable clock before using NAND registers */ +@@ -3122,7 +3122,6 @@ int brcmnand_probe(struct platform_devic + + for_each_available_child_of_node(dn, child) { + if (of_device_is_compatible(child, "brcm,nandcs")) { +- struct brcmnand_host *host; + + host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); + if (!host) { +@@ -3142,7 +3141,7 @@ int brcmnand_probe(struct platform_devic + + nand_set_flash_node(&host->chip, child); + +- ret = brcmnand_init_cs(host); ++ ret = brcmnand_init_cs(host, NULL); + if (ret) { + devm_kfree(dev, host); + continue; /* Try all chip-selects */ +@@ -3152,6 +3151,32 @@ int brcmnand_probe(struct platform_devic + } + } + ++ if (!list_empty(&ctrl->host_list)) ++ return 0; ++ ++ if (!pd) { ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ /* If we got there we must have been probing via platform data */ ++ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); ++ if (!host) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ host->pdev = pdev; ++ host->ctrl = ctrl; ++ host->cs = pd->chip_select; ++ host->chip.ecc.size = pd->ecc_stepsize; ++ host->chip.ecc.strength = pd->ecc_strength; ++ ++ ret = brcmnand_init_cs(host, pd->part_probe_types); ++ if (ret) ++ goto err; ++ ++ list_add_tail(&host->node, &ctrl->host_list); ++ + /* No chip-selects could initialize properly */ + if (list_empty(&ctrl->host_list)) { + ret = -ENODEV; diff --git a/target/linux/bcm47xx/patches-5.10/107-mtd-rawnand-brcmnand-BCMA-controller-uses-command-shift-of-0.patch b/target/linux/bcm47xx/patches-5.10/107-mtd-rawnand-brcmnand-BCMA-controller-uses-command-shift-of-0.patch deleted file mode 100644 index 39f34aab29..0000000000 --- a/target/linux/bcm47xx/patches-5.10/107-mtd-rawnand-brcmnand-BCMA-controller-uses-command-shift-of-0.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Florian Fainelli -Subject: [PATCH v3 8/9] mtd: rawnand: brcmnand: BCMA controller uses command shift of 0 -Date: Fri, 07 Jan 2022 10:46:13 -0800 -Content-Type: text/plain; charset="utf-8" - -For some odd and unexplained reason the BCMA NAND controller, albeit -revision 3.4 uses a command shift of 0 instead of 24 as it should be, -quirk that. - -Signed-off-by: Florian Fainelli ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -913,6 +913,12 @@ static void brcmnand_wr_corr_thresh(stru - - static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl) - { -+ /* Kludge for the BCMA-based NAND controller which does not actually -+ * shift the command -+ */ -+ if (ctrl->nand_version == 0x0304 && brcmnand_non_mmio_ops(ctrl)) -+ return 0; -+ - if (ctrl->nand_version < 0x0602) - return 24; - return 0; diff --git a/target/linux/bcm47xx/patches-5.10/107-v5.18-mtd-rawnand-brcmnand-BCMA-controller-uses-command-shift-of-0.patch b/target/linux/bcm47xx/patches-5.10/107-v5.18-mtd-rawnand-brcmnand-BCMA-controller-uses-command-shift-of-0.patch new file mode 100644 index 0000000000..39f34aab29 --- /dev/null +++ b/target/linux/bcm47xx/patches-5.10/107-v5.18-mtd-rawnand-brcmnand-BCMA-controller-uses-command-shift-of-0.patch @@ -0,0 +1,29 @@ +From: Florian Fainelli +Subject: [PATCH v3 8/9] mtd: rawnand: brcmnand: BCMA controller uses command shift of 0 +Date: Fri, 07 Jan 2022 10:46:13 -0800 +Content-Type: text/plain; charset="utf-8" + +For some odd and unexplained reason the BCMA NAND controller, albeit +revision 3.4 uses a command shift of 0 instead of 24 as it should be, +quirk that. + +Signed-off-by: Florian Fainelli +--- + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -913,6 +913,12 @@ static void brcmnand_wr_corr_thresh(stru + + static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl) + { ++ /* Kludge for the BCMA-based NAND controller which does not actually ++ * shift the command ++ */ ++ if (ctrl->nand_version == 0x0304 && brcmnand_non_mmio_ops(ctrl)) ++ return 0; ++ + if (ctrl->nand_version < 0x0602) + return 24; + return 0; diff --git a/target/linux/bcm47xx/patches-5.10/108-mtd-rawnand-brcmnand-Add-BCMA-shim.patch b/target/linux/bcm47xx/patches-5.10/108-mtd-rawnand-brcmnand-Add-BCMA-shim.patch deleted file mode 100644 index eabb4c2475..0000000000 --- a/target/linux/bcm47xx/patches-5.10/108-mtd-rawnand-brcmnand-Add-BCMA-shim.patch +++ /dev/null @@ -1,201 +0,0 @@ -From: Florian Fainelli -Subject: [PATCH v3 9/9] mtd: rawnand: brcmnand: Add BCMA shim -Date: Fri, 07 Jan 2022 10:46:14 -0800 -Content-Type: text/plain; charset="utf-8" - -Add a BCMA shim to allow us to register the brcmnand driver using the -BCMA bus which provides indirect memory mapped access to SoC registers. - -There are a number of registers that need to be byte swapped because -they are natively big endian, coming directly from the NAND chip, and -there is no bus interface unlike the iProc or STB platforms that -performs the byte swapping for us. - -Signed-off-by: Florian Fainelli ---- - drivers/mtd/nand/raw/Kconfig | 13 +++ - drivers/mtd/nand/raw/brcmnand/Makefile | 2 + - drivers/mtd/nand/raw/brcmnand/bcma_nand.c | 132 ++++++++++++++++++++++ - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 + - 4 files changed, 151 insertions(+) - create mode 100644 drivers/mtd/nand/raw/brcmnand/bcma_nand.c - ---- a/drivers/mtd/nand/raw/Kconfig -+++ b/drivers/mtd/nand/raw/Kconfig -@@ -236,6 +236,19 @@ config MTD_NAND_BRCMNAND - originally designed for Set-Top Box but is used on various BCM7xxx, - BCM3xxx, BCM63xxx, iProc/Cygnus and more. - -+if MTD_NAND_BRCMNAND -+ -+config MTD_NAND_BRCMNAND_BCMA -+ tristate "Broadcom BCMA NAND controller" -+ depends on BCMA_NFLASH -+ depends on BCMA -+ help -+ Enables the BRCMNAND controller over BCMA on BCM47186/BCM5358 SoCs. -+ The glue driver will take care of performing the low-level I/O -+ operations to interface the BRCMNAND controller over the BCMA bus. -+ -+endif # MTD_NAND_BRCMNAND -+ - config MTD_NAND_BCM47XXNFLASH - tristate "BCM4706 BCMA NAND controller" - depends on BCMA_NFLASH ---- a/drivers/mtd/nand/raw/brcmnand/Makefile -+++ b/drivers/mtd/nand/raw/brcmnand/Makefile -@@ -6,3 +6,5 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm6 - obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm6368_nand.o - obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmstb_nand.o - obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand.o -+ -+obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMA) += bcma_nand.o ---- /dev/null -+++ b/drivers/mtd/nand/raw/brcmnand/bcma_nand.c -@@ -0,0 +1,132 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright © 2021 Broadcom -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include "brcmnand.h" -+ -+struct brcmnand_bcma_soc { -+ struct brcmnand_soc soc; -+ struct bcma_drv_cc *cc; -+}; -+ -+static inline bool brcmnand_bcma_needs_swapping(u32 offset) -+{ -+ switch (offset) { -+ case BCMA_CC_NAND_SPARE_RD0: -+ case BCMA_CC_NAND_SPARE_RD4: -+ case BCMA_CC_NAND_SPARE_RD8: -+ case BCMA_CC_NAND_SPARE_RD12: -+ case BCMA_CC_NAND_SPARE_WR0: -+ case BCMA_CC_NAND_SPARE_WR4: -+ case BCMA_CC_NAND_SPARE_WR8: -+ case BCMA_CC_NAND_SPARE_WR12: -+ case BCMA_CC_NAND_DEVID: -+ case BCMA_CC_NAND_DEVID_X: -+ case BCMA_CC_NAND_SPARE_RD16: -+ case BCMA_CC_NAND_SPARE_RD20: -+ case BCMA_CC_NAND_SPARE_RD24: -+ case BCMA_CC_NAND_SPARE_RD28: -+ return true; -+ } -+ -+ return false; -+} -+ -+static inline struct brcmnand_bcma_soc *to_bcma_soc(struct brcmnand_soc *soc) -+{ -+ return container_of(soc, struct brcmnand_bcma_soc, soc); -+} -+ -+static u32 brcmnand_bcma_read_reg(struct brcmnand_soc *soc, u32 offset) -+{ -+ struct brcmnand_bcma_soc *sc = to_bcma_soc(soc); -+ u32 val; -+ -+ /* Offset into the NAND block and deal with the flash cache separately */ -+ if (offset == BRCMNAND_NON_MMIO_FC_ADDR) -+ offset = BCMA_CC_NAND_CACHE_DATA; -+ else -+ offset += BCMA_CC_NAND_REVISION; -+ -+ val = bcma_cc_read32(sc->cc, offset); -+ -+ /* Swap if necessary */ -+ if (brcmnand_bcma_needs_swapping(offset)) -+ val = be32_to_cpu(val); -+ return val; -+} -+ -+static void brcmnand_bcma_write_reg(struct brcmnand_soc *soc, u32 val, -+ u32 offset) -+{ -+ struct brcmnand_bcma_soc *sc = to_bcma_soc(soc); -+ -+ /* Offset into the NAND block */ -+ if (offset == BRCMNAND_NON_MMIO_FC_ADDR) -+ offset = BCMA_CC_NAND_CACHE_DATA; -+ else -+ offset += BCMA_CC_NAND_REVISION; -+ -+ /* Swap if necessary */ -+ if (brcmnand_bcma_needs_swapping(offset)) -+ val = cpu_to_be32(val); -+ -+ bcma_cc_write32(sc->cc, offset, val); -+} -+ -+static struct brcmnand_io_ops brcmnand_bcma_io_ops = { -+ .read_reg = brcmnand_bcma_read_reg, -+ .write_reg = brcmnand_bcma_write_reg, -+}; -+ -+static void brcmnand_bcma_prepare_data_bus(struct brcmnand_soc *soc, bool prepare, -+ bool is_param) -+{ -+ struct brcmnand_bcma_soc *sc = to_bcma_soc(soc); -+ -+ /* Reset the cache address to ensure we are already accessing the -+ * beginning of a sub-page. -+ */ -+ bcma_cc_write32(sc->cc, BCMA_CC_NAND_CACHE_ADDR, 0); -+} -+ -+static int brcmnand_bcma_nand_probe(struct platform_device *pdev) -+{ -+ struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); -+ struct brcmnand_bcma_soc *soc; -+ -+ soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL); -+ if (!soc) -+ return -ENOMEM; -+ -+ soc->cc = container_of(nflash, struct bcma_drv_cc, nflash); -+ soc->soc.prepare_data_bus = brcmnand_bcma_prepare_data_bus; -+ soc->soc.ops = &brcmnand_bcma_io_ops; -+ -+ if (soc->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { -+ dev_err(&pdev->dev, "Use bcm47xxnflash for 4706!\n"); -+ return -ENODEV; -+ } -+ -+ return brcmnand_probe(pdev, &soc->soc); -+} -+ -+static struct platform_driver brcmnand_bcma_nand_driver = { -+ .probe = brcmnand_bcma_nand_probe, -+ .remove = brcmnand_remove, -+ .driver = { -+ .name = "bcma_brcmnand", -+ .pm = &brcmnand_pm_ops, -+ } -+}; -+module_platform_driver(brcmnand_bcma_nand_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Broadcom"); -+MODULE_DESCRIPTION("NAND controller driver glue for BCMA chips"); ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -595,7 +595,11 @@ enum { - - static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) - { -+#if IS_ENABLED(CONFIG_MTD_NAND_BRCMNAND_BCMA) - return static_branch_unlikely(&brcmnand_soc_has_ops_key); -+#else -+ return false; -+#endif - } - - static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs) diff --git a/target/linux/bcm47xx/patches-5.10/108-v5.18-mtd-rawnand-brcmnand-Add-BCMA-shim.patch b/target/linux/bcm47xx/patches-5.10/108-v5.18-mtd-rawnand-brcmnand-Add-BCMA-shim.patch new file mode 100644 index 0000000000..eabb4c2475 --- /dev/null +++ b/target/linux/bcm47xx/patches-5.10/108-v5.18-mtd-rawnand-brcmnand-Add-BCMA-shim.patch @@ -0,0 +1,201 @@ +From: Florian Fainelli +Subject: [PATCH v3 9/9] mtd: rawnand: brcmnand: Add BCMA shim +Date: Fri, 07 Jan 2022 10:46:14 -0800 +Content-Type: text/plain; charset="utf-8" + +Add a BCMA shim to allow us to register the brcmnand driver using the +BCMA bus which provides indirect memory mapped access to SoC registers. + +There are a number of registers that need to be byte swapped because +they are natively big endian, coming directly from the NAND chip, and +there is no bus interface unlike the iProc or STB platforms that +performs the byte swapping for us. + +Signed-off-by: Florian Fainelli +--- + drivers/mtd/nand/raw/Kconfig | 13 +++ + drivers/mtd/nand/raw/brcmnand/Makefile | 2 + + drivers/mtd/nand/raw/brcmnand/bcma_nand.c | 132 ++++++++++++++++++++++ + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 + + 4 files changed, 151 insertions(+) + create mode 100644 drivers/mtd/nand/raw/brcmnand/bcma_nand.c + +--- a/drivers/mtd/nand/raw/Kconfig ++++ b/drivers/mtd/nand/raw/Kconfig +@@ -236,6 +236,19 @@ config MTD_NAND_BRCMNAND + originally designed for Set-Top Box but is used on various BCM7xxx, + BCM3xxx, BCM63xxx, iProc/Cygnus and more. + ++if MTD_NAND_BRCMNAND ++ ++config MTD_NAND_BRCMNAND_BCMA ++ tristate "Broadcom BCMA NAND controller" ++ depends on BCMA_NFLASH ++ depends on BCMA ++ help ++ Enables the BRCMNAND controller over BCMA on BCM47186/BCM5358 SoCs. ++ The glue driver will take care of performing the low-level I/O ++ operations to interface the BRCMNAND controller over the BCMA bus. ++ ++endif # MTD_NAND_BRCMNAND ++ + config MTD_NAND_BCM47XXNFLASH + tristate "BCM4706 BCMA NAND controller" + depends on BCMA_NFLASH +--- a/drivers/mtd/nand/raw/brcmnand/Makefile ++++ b/drivers/mtd/nand/raw/brcmnand/Makefile +@@ -6,3 +6,5 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm6 + obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm6368_nand.o + obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmstb_nand.o + obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand.o ++ ++obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMA) += bcma_nand.o +--- /dev/null ++++ b/drivers/mtd/nand/raw/brcmnand/bcma_nand.c +@@ -0,0 +1,132 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright © 2021 Broadcom ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include "brcmnand.h" ++ ++struct brcmnand_bcma_soc { ++ struct brcmnand_soc soc; ++ struct bcma_drv_cc *cc; ++}; ++ ++static inline bool brcmnand_bcma_needs_swapping(u32 offset) ++{ ++ switch (offset) { ++ case BCMA_CC_NAND_SPARE_RD0: ++ case BCMA_CC_NAND_SPARE_RD4: ++ case BCMA_CC_NAND_SPARE_RD8: ++ case BCMA_CC_NAND_SPARE_RD12: ++ case BCMA_CC_NAND_SPARE_WR0: ++ case BCMA_CC_NAND_SPARE_WR4: ++ case BCMA_CC_NAND_SPARE_WR8: ++ case BCMA_CC_NAND_SPARE_WR12: ++ case BCMA_CC_NAND_DEVID: ++ case BCMA_CC_NAND_DEVID_X: ++ case BCMA_CC_NAND_SPARE_RD16: ++ case BCMA_CC_NAND_SPARE_RD20: ++ case BCMA_CC_NAND_SPARE_RD24: ++ case BCMA_CC_NAND_SPARE_RD28: ++ return true; ++ } ++ ++ return false; ++} ++ ++static inline struct brcmnand_bcma_soc *to_bcma_soc(struct brcmnand_soc *soc) ++{ ++ return container_of(soc, struct brcmnand_bcma_soc, soc); ++} ++ ++static u32 brcmnand_bcma_read_reg(struct brcmnand_soc *soc, u32 offset) ++{ ++ struct brcmnand_bcma_soc *sc = to_bcma_soc(soc); ++ u32 val; ++ ++ /* Offset into the NAND block and deal with the flash cache separately */ ++ if (offset == BRCMNAND_NON_MMIO_FC_ADDR) ++ offset = BCMA_CC_NAND_CACHE_DATA; ++ else ++ offset += BCMA_CC_NAND_REVISION; ++ ++ val = bcma_cc_read32(sc->cc, offset); ++ ++ /* Swap if necessary */ ++ if (brcmnand_bcma_needs_swapping(offset)) ++ val = be32_to_cpu(val); ++ return val; ++} ++ ++static void brcmnand_bcma_write_reg(struct brcmnand_soc *soc, u32 val, ++ u32 offset) ++{ ++ struct brcmnand_bcma_soc *sc = to_bcma_soc(soc); ++ ++ /* Offset into the NAND block */ ++ if (offset == BRCMNAND_NON_MMIO_FC_ADDR) ++ offset = BCMA_CC_NAND_CACHE_DATA; ++ else ++ offset += BCMA_CC_NAND_REVISION; ++ ++ /* Swap if necessary */ ++ if (brcmnand_bcma_needs_swapping(offset)) ++ val = cpu_to_be32(val); ++ ++ bcma_cc_write32(sc->cc, offset, val); ++} ++ ++static struct brcmnand_io_ops brcmnand_bcma_io_ops = { ++ .read_reg = brcmnand_bcma_read_reg, ++ .write_reg = brcmnand_bcma_write_reg, ++}; ++ ++static void brcmnand_bcma_prepare_data_bus(struct brcmnand_soc *soc, bool prepare, ++ bool is_param) ++{ ++ struct brcmnand_bcma_soc *sc = to_bcma_soc(soc); ++ ++ /* Reset the cache address to ensure we are already accessing the ++ * beginning of a sub-page. ++ */ ++ bcma_cc_write32(sc->cc, BCMA_CC_NAND_CACHE_ADDR, 0); ++} ++ ++static int brcmnand_bcma_nand_probe(struct platform_device *pdev) ++{ ++ struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); ++ struct brcmnand_bcma_soc *soc; ++ ++ soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL); ++ if (!soc) ++ return -ENOMEM; ++ ++ soc->cc = container_of(nflash, struct bcma_drv_cc, nflash); ++ soc->soc.prepare_data_bus = brcmnand_bcma_prepare_data_bus; ++ soc->soc.ops = &brcmnand_bcma_io_ops; ++ ++ if (soc->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { ++ dev_err(&pdev->dev, "Use bcm47xxnflash for 4706!\n"); ++ return -ENODEV; ++ } ++ ++ return brcmnand_probe(pdev, &soc->soc); ++} ++ ++static struct platform_driver brcmnand_bcma_nand_driver = { ++ .probe = brcmnand_bcma_nand_probe, ++ .remove = brcmnand_remove, ++ .driver = { ++ .name = "bcma_brcmnand", ++ .pm = &brcmnand_pm_ops, ++ } ++}; ++module_platform_driver(brcmnand_bcma_nand_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("NAND controller driver glue for BCMA chips"); +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -595,7 +595,11 @@ enum { + + static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) + { ++#if IS_ENABLED(CONFIG_MTD_NAND_BRCMNAND_BCMA) + return static_branch_unlikely(&brcmnand_soc_has_ops_key); ++#else ++ return false; ++#endif + } + + static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs)