root/drivers/reset/reset-berlin.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. berlin_reset_reset
  2. berlin_reset_xlate
  3. berlin2_reset_probe

   1 /*
   2  * Copyright (C) 2014 Marvell Technology Group Ltd.
   3  *
   4  * Marvell Berlin reset driver
   5  *
   6  * Antoine Tenart <antoine.tenart@free-electrons.com>
   7  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
   8  *
   9  * This file is licensed under the terms of the GNU General Public
  10  * License version 2. This program is licensed "as is" without any
  11  * warranty of any kind, whether express or implied.
  12  */
  13 
  14 #include <linux/delay.h>
  15 #include <linux/io.h>
  16 #include <linux/mfd/syscon.h>
  17 #include <linux/init.h>
  18 #include <linux/of.h>
  19 #include <linux/of_address.h>
  20 #include <linux/platform_device.h>
  21 #include <linux/regmap.h>
  22 #include <linux/reset-controller.h>
  23 #include <linux/slab.h>
  24 #include <linux/types.h>
  25 
  26 #define BERLIN_MAX_RESETS       32
  27 
  28 #define to_berlin_reset_priv(p)         \
  29         container_of((p), struct berlin_reset_priv, rcdev)
  30 
  31 struct berlin_reset_priv {
  32         struct regmap                   *regmap;
  33         struct reset_controller_dev     rcdev;
  34 };
  35 
  36 static int berlin_reset_reset(struct reset_controller_dev *rcdev,
  37                               unsigned long id)
  38 {
  39         struct berlin_reset_priv *priv = to_berlin_reset_priv(rcdev);
  40         int offset = id >> 8;
  41         int mask = BIT(id & 0x1f);
  42 
  43         regmap_write(priv->regmap, offset, mask);
  44 
  45         /* let the reset be effective */
  46         udelay(10);
  47 
  48         return 0;
  49 }
  50 
  51 static const struct reset_control_ops berlin_reset_ops = {
  52         .reset  = berlin_reset_reset,
  53 };
  54 
  55 static int berlin_reset_xlate(struct reset_controller_dev *rcdev,
  56                               const struct of_phandle_args *reset_spec)
  57 {
  58         unsigned offset, bit;
  59 
  60         offset = reset_spec->args[0];
  61         bit = reset_spec->args[1];
  62 
  63         if (bit >= BERLIN_MAX_RESETS)
  64                 return -EINVAL;
  65 
  66         return (offset << 8) | bit;
  67 }
  68 
  69 static int berlin2_reset_probe(struct platform_device *pdev)
  70 {
  71         struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
  72         struct berlin_reset_priv *priv;
  73 
  74         priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  75         if (!priv)
  76                 return -ENOMEM;
  77 
  78         priv->regmap = syscon_node_to_regmap(parent_np);
  79         of_node_put(parent_np);
  80         if (IS_ERR(priv->regmap))
  81                 return PTR_ERR(priv->regmap);
  82 
  83         priv->rcdev.owner = THIS_MODULE;
  84         priv->rcdev.ops = &berlin_reset_ops;
  85         priv->rcdev.of_node = pdev->dev.of_node;
  86         priv->rcdev.of_reset_n_cells = 2;
  87         priv->rcdev.of_xlate = berlin_reset_xlate;
  88 
  89         return reset_controller_register(&priv->rcdev);
  90 }
  91 
  92 static const struct of_device_id berlin_reset_dt_match[] = {
  93         { .compatible = "marvell,berlin2-reset" },
  94         { },
  95 };
  96 
  97 static struct platform_driver berlin_reset_driver = {
  98         .probe  = berlin2_reset_probe,
  99         .driver = {
 100                 .name = "berlin2-reset",
 101                 .of_match_table = berlin_reset_dt_match,
 102         },
 103 };
 104 builtin_platform_driver(berlin_reset_driver);

/* [<][>][^][v][top][bottom][index][help] */