root/drivers/reset/reset-ath79.c

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

DEFINITIONS

This source file includes following definitions.
  1. ath79_reset_update
  2. ath79_reset_assert
  3. ath79_reset_deassert
  4. ath79_reset_status
  5. ath79_reset_restart_handler
  6. ath79_reset_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * AR71xx Reset Controller Driver
   4  * Author: Alban Bedel
   5  *
   6  * Copyright (C) 2015 Alban Bedel <albeu@free.fr>
   7  */
   8 
   9 #include <linux/io.h>
  10 #include <linux/init.h>
  11 #include <linux/mod_devicetable.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/reset-controller.h>
  14 #include <linux/reboot.h>
  15 
  16 struct ath79_reset {
  17         struct reset_controller_dev rcdev;
  18         struct notifier_block restart_nb;
  19         void __iomem *base;
  20         spinlock_t lock;
  21 };
  22 
  23 #define FULL_CHIP_RESET 24
  24 
  25 static int ath79_reset_update(struct reset_controller_dev *rcdev,
  26                         unsigned long id, bool assert)
  27 {
  28         struct ath79_reset *ath79_reset =
  29                 container_of(rcdev, struct ath79_reset, rcdev);
  30         unsigned long flags;
  31         u32 val;
  32 
  33         spin_lock_irqsave(&ath79_reset->lock, flags);
  34         val = readl(ath79_reset->base);
  35         if (assert)
  36                 val |= BIT(id);
  37         else
  38                 val &= ~BIT(id);
  39         writel(val, ath79_reset->base);
  40         spin_unlock_irqrestore(&ath79_reset->lock, flags);
  41 
  42         return 0;
  43 }
  44 
  45 static int ath79_reset_assert(struct reset_controller_dev *rcdev,
  46                         unsigned long id)
  47 {
  48         return ath79_reset_update(rcdev, id, true);
  49 }
  50 
  51 static int ath79_reset_deassert(struct reset_controller_dev *rcdev,
  52                                 unsigned long id)
  53 {
  54         return ath79_reset_update(rcdev, id, false);
  55 }
  56 
  57 static int ath79_reset_status(struct reset_controller_dev *rcdev,
  58                         unsigned long id)
  59 {
  60         struct ath79_reset *ath79_reset =
  61                 container_of(rcdev, struct ath79_reset, rcdev);
  62         u32 val;
  63 
  64         val = readl(ath79_reset->base);
  65 
  66         return !!(val & BIT(id));
  67 }
  68 
  69 static const struct reset_control_ops ath79_reset_ops = {
  70         .assert = ath79_reset_assert,
  71         .deassert = ath79_reset_deassert,
  72         .status = ath79_reset_status,
  73 };
  74 
  75 static int ath79_reset_restart_handler(struct notifier_block *nb,
  76                                 unsigned long action, void *data)
  77 {
  78         struct ath79_reset *ath79_reset =
  79                 container_of(nb, struct ath79_reset, restart_nb);
  80 
  81         ath79_reset_assert(&ath79_reset->rcdev, FULL_CHIP_RESET);
  82 
  83         return NOTIFY_DONE;
  84 }
  85 
  86 static int ath79_reset_probe(struct platform_device *pdev)
  87 {
  88         struct ath79_reset *ath79_reset;
  89         struct resource *res;
  90         int err;
  91 
  92         ath79_reset = devm_kzalloc(&pdev->dev,
  93                                 sizeof(*ath79_reset), GFP_KERNEL);
  94         if (!ath79_reset)
  95                 return -ENOMEM;
  96 
  97         platform_set_drvdata(pdev, ath79_reset);
  98 
  99         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 100         ath79_reset->base = devm_ioremap_resource(&pdev->dev, res);
 101         if (IS_ERR(ath79_reset->base))
 102                 return PTR_ERR(ath79_reset->base);
 103 
 104         spin_lock_init(&ath79_reset->lock);
 105         ath79_reset->rcdev.ops = &ath79_reset_ops;
 106         ath79_reset->rcdev.owner = THIS_MODULE;
 107         ath79_reset->rcdev.of_node = pdev->dev.of_node;
 108         ath79_reset->rcdev.of_reset_n_cells = 1;
 109         ath79_reset->rcdev.nr_resets = 32;
 110 
 111         err = devm_reset_controller_register(&pdev->dev, &ath79_reset->rcdev);
 112         if (err)
 113                 return err;
 114 
 115         ath79_reset->restart_nb.notifier_call = ath79_reset_restart_handler;
 116         ath79_reset->restart_nb.priority = 128;
 117 
 118         err = register_restart_handler(&ath79_reset->restart_nb);
 119         if (err)
 120                 dev_warn(&pdev->dev, "Failed to register restart handler\n");
 121 
 122         return 0;
 123 }
 124 
 125 static const struct of_device_id ath79_reset_dt_ids[] = {
 126         { .compatible = "qca,ar7100-reset", },
 127         { },
 128 };
 129 
 130 static struct platform_driver ath79_reset_driver = {
 131         .probe  = ath79_reset_probe,
 132         .driver = {
 133                 .name                   = "ath79-reset",
 134                 .of_match_table         = ath79_reset_dt_ids,
 135                 .suppress_bind_attrs    = true,
 136         },
 137 };
 138 builtin_platform_driver(ath79_reset_driver);

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