linux/arch/arm/mach-prima2/rstc.c
<<
>>
Prefs
   1/*
   2 * reset controller for CSR SiRFprimaII
   3 *
   4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
   5 *
   6 * Licensed under GPLv2 or later.
   7 */
   8
   9#include <linux/kernel.h>
  10#include <linux/mutex.h>
  11#include <linux/io.h>
  12#include <linux/delay.h>
  13#include <linux/device.h>
  14#include <linux/of.h>
  15#include <linux/of_address.h>
  16
  17void __iomem *sirfsoc_rstc_base;
  18static DEFINE_MUTEX(rstc_lock);
  19
  20static struct of_device_id rstc_ids[]  = {
  21        { .compatible = "sirf,prima2-rstc" },
  22        {},
  23};
  24
  25static int __init sirfsoc_of_rstc_init(void)
  26{
  27        struct device_node *np;
  28
  29        np = of_find_matching_node(NULL, rstc_ids);
  30        if (!np)
  31                panic("unable to find compatible rstc node in dtb\n");
  32
  33        sirfsoc_rstc_base = of_iomap(np, 0);
  34        if (!sirfsoc_rstc_base)
  35                panic("unable to map rstc cpu registers\n");
  36
  37        of_node_put(np);
  38
  39        return 0;
  40}
  41early_initcall(sirfsoc_of_rstc_init);
  42
  43int sirfsoc_reset_device(struct device *dev)
  44{
  45        const unsigned int *prop = of_get_property(dev->of_node, "reset-bit", NULL);
  46        unsigned int reset_bit;
  47
  48        if (!prop)
  49                return -ENODEV;
  50
  51        reset_bit = be32_to_cpup(prop);
  52
  53        mutex_lock(&rstc_lock);
  54
  55        /*
  56         * Writing 1 to this bit resets corresponding block. Writing 0 to this
  57         * bit de-asserts reset signal of the corresponding block.
  58         * datasheet doesn't require explicit delay between the set and clear
  59         * of reset bit. it could be shorter if tests pass.
  60         */
  61        writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit,
  62                sirfsoc_rstc_base + (reset_bit / 32) * 4);
  63        msleep(10);
  64        writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit,
  65                sirfsoc_rstc_base + (reset_bit / 32) * 4);
  66
  67        mutex_unlock(&rstc_lock);
  68
  69        return 0;
  70}
  71