lkml.org 
[lkml]   [2022]   [Apr]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 3/4] mtd: phram: Allow probing via reserved-memory
    Date
    Allow phram to be probed from the devicetree.  It expects to be in a
    reserved-memory node as documented by the bindings. This allows things
    like partitioning to be specified via the devicetree.

    Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
    ---

    Notes:
    v3:
    - Add missing semicolon after MODULE_DEVICE_TABLE causing build errors on some
    configs.

    drivers/mtd/devices/phram.c | 67 ++++++++++++++++++++++++++++++++++---
    drivers/of/platform.c | 1 +
    2 files changed, 64 insertions(+), 4 deletions(-)

    diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
    index d503821a3e60..506e9edf5c85 100644
    --- a/drivers/mtd/devices/phram.c
    +++ b/drivers/mtd/devices/phram.c
    @@ -27,6 +27,9 @@
    #include <linux/slab.h>
    #include <linux/mtd/mtd.h>
    #include <asm/div64.h>
    +#include <linux/platform_device.h>
    +#include <linux/of_address.h>
    +#include <linux/of.h>

    struct phram_mtd_list {
    struct mtd_info mtd;
    @@ -89,8 +92,10 @@ static void unregister_devices(void)
    }
    }

    -static int register_device(char *name, phys_addr_t start, size_t len, uint32_t erasesize)
    +static int register_device(struct platform_device *pdev, const char *name,
    + phys_addr_t start, size_t len, uint32_t erasesize)
    {
    + struct device_node *np = pdev ? pdev->dev.of_node : NULL;
    struct phram_mtd_list *new;
    int ret = -ENOMEM;

    @@ -119,13 +124,19 @@ static int register_device(char *name, phys_addr_t start, size_t len, uint32_t e
    new->mtd.erasesize = erasesize;
    new->mtd.writesize = 1;

    + mtd_set_of_node(&new->mtd, np);
    +
    ret = -EAGAIN;
    if (mtd_device_register(&new->mtd, NULL, 0)) {
    pr_err("Failed to register new device\n");
    goto out2;
    }

    - list_add_tail(&new->list, &phram_list);
    + if (pdev)
    + platform_set_drvdata(pdev, new);
    + else
    + list_add_tail(&new->list, &phram_list);
    +
    return 0;

    out2:
    @@ -278,7 +289,7 @@ static int phram_setup(const char *val)
    goto error;
    }

    - ret = register_device(name, start, len, (uint32_t)erasesize);
    + ret = register_device(NULL, name, start, len, (uint32_t)erasesize);
    if (ret)
    goto error;

    @@ -325,10 +336,54 @@ static int phram_param_call(const char *val, const struct kernel_param *kp)
    module_param_call(phram, phram_param_call, NULL, NULL, 0200);
    MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>[,<erasesize>]\"");

    +#ifdef CONFIG_OF
    +static const struct of_device_id phram_of_match[] = {
    + { .compatible = "phram" },
    + {}
    +};
    +MODULE_DEVICE_TABLE(of, phram_of_match);
    +#endif
    +
    +static int phram_probe(struct platform_device *pdev)
    +{
    + struct resource *res;
    +
    + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    + if (!res)
    + return -ENOMEM;
    +
    + /* mtd_set_of_node() reads name from "label" */
    + return register_device(pdev, NULL, res->start, resource_size(res),
    + PAGE_SIZE);
    +}
    +
    +static int phram_remove(struct platform_device *pdev)
    +{
    + struct phram_mtd_list *phram = platform_get_drvdata(pdev);
    +
    + mtd_device_unregister(&phram->mtd);
    + iounmap(phram->mtd.priv);
    + kfree(phram);
    +
    + return 0;
    +}
    +
    +static struct platform_driver phram_driver = {
    + .probe = phram_probe,
    + .remove = phram_remove,
    + .driver = {
    + .name = "phram",
    + .of_match_table = of_match_ptr(phram_of_match),
    + },
    +};

    static int __init init_phram(void)
    {
    - int ret = 0;
    + int ret;
    +
    + ret = platform_driver_register(&phram_driver);
    + if (ret)
    + return ret;

    #ifndef MODULE
    if (phram_paramline[0])
    @@ -336,12 +391,16 @@ static int __init init_phram(void)
    phram_init_called = 1;
    #endif

    + if (ret)
    + platform_driver_unregister(&phram_driver);
    +
    return ret;
    }

    static void __exit cleanup_phram(void)
    {
    unregister_devices();
    + platform_driver_unregister(&phram_driver);
    }

    module_init(init_phram);
    diff --git a/drivers/of/platform.c b/drivers/of/platform.c
    index a16b74f32aa9..55d62b82c650 100644
    --- a/drivers/of/platform.c
    +++ b/drivers/of/platform.c
    @@ -509,6 +509,7 @@ EXPORT_SYMBOL_GPL(of_platform_default_populate);

    #ifndef CONFIG_PPC
    static const struct of_device_id reserved_mem_matches[] = {
    + { .compatible = "phram" },
    { .compatible = "qcom,rmtfs-mem" },
    { .compatible = "qcom,cmd-db" },
    { .compatible = "qcom,smem" },
    --
    2.34.1
    \
     
     \ /
      Last update: 2022-09-17 16:21    [W:5.114 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site