lkml.org 
[lkml]   [2022]   [Jan]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations
    Date
    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 <f.fainelli@gmail.com>
    ---
    drivers/mtd/nand/raw/brcmnand/brcmnand.c | 30 ++++++++++++++++++++++--
    drivers/mtd/nand/raw/brcmnand/brcmnand.h | 29 +++++++++++++++++++++++
    2 files changed, 57 insertions(+), 2 deletions(-)

    diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
    index 63080ae3aef1..9c3909c34dc2 100644
    --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
    +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
    @@ -25,6 +25,7 @@
    #include <linux/of.h>
    #include <linux/of_platform.h>
    #include <linux/slab.h>
    +#include <linux/static_key.h>
    #include <linux/list.h>
    #include <linux/log2.h>

    @@ -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;
    @@ -592,15 +595,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)
    @@ -766,13 +779,18 @@ static inline void brcmnand_rmw_reg(struct brcmnand_controller *ctrl,

    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,
    @@ -3000,6 +3018,12 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
    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);
    @@ -3145,6 +3169,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
    /* Enable interrupt */
    ctrl->soc->ctlrdy_ack(ctrl->soc);
    ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
    + if (brcmnand_soc_has_ops(soc))
    + static_branch_enable(&brcmnand_soc_has_ops_key);
    } else {
    /* Use standard interrupt infrastructure */
    ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0,
    diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.h b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
    index eb498fbe505e..f1f93d85f50d 100644
    --- 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 val, void __iomem *addr)
    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);

    --
    2.25.1
    \
     
     \ /
      Last update: 2022-01-07 01:15    [W:3.459 / U:0.252 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site