linux/drivers/power/reset/axxia-reset.c
Thomas Gleixner 97fb5e8d9b treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284
Based on 1 normalized pattern(s):

  this program is free software you can redistribute it and or modify
  it under the terms of the gnu general public license version 2 and
  only version 2 as published by the free software foundation this
  program is distributed in the hope that it will be useful but
  without any warranty without even the implied warranty of
  merchantability or fitness for a particular purpose see the gnu
  general public license for more details

extracted by the scancode license scanner the SPDX license identifier

  GPL-2.0-only

has been chosen to replace the boilerplate/reference in 294 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Alexios Zavras <alexios.zavras@intel.com>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190529141900.825281744@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-05 17:36:37 +02:00

89 lines
2.2 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Reset driver for Axxia devices
*
* Copyright (C) 2014 LSI
*/
#include <linux/init.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#define SC_CRIT_WRITE_KEY 0x1000
#define SC_LATCH_ON_RESET 0x1004
#define SC_RESET_CONTROL 0x1008
#define RSTCTL_RST_ZERO (1<<3)
#define RSTCTL_RST_FAB (1<<2)
#define RSTCTL_RST_CHIP (1<<1)
#define RSTCTL_RST_SYS (1<<0)
#define SC_EFUSE_INT_STATUS 0x180c
#define EFUSE_READ_DONE (1<<31)
static struct regmap *syscon;
static int axxia_restart_handler(struct notifier_block *this,
unsigned long mode, void *cmd)
{
/* Access Key (0xab) */
regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab);
/* Select internal boot from 0xffff0000 */
regmap_write(syscon, SC_LATCH_ON_RESET, 0x00000040);
/* Assert ResetReadDone (to avoid hanging in boot ROM) */
regmap_write(syscon, SC_EFUSE_INT_STATUS, EFUSE_READ_DONE);
/* Assert chip reset */
regmap_update_bits(syscon, SC_RESET_CONTROL,
RSTCTL_RST_CHIP, RSTCTL_RST_CHIP);
return NOTIFY_DONE;
}
static struct notifier_block axxia_restart_nb = {
.notifier_call = axxia_restart_handler,
.priority = 128,
};
static int axxia_reset_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int err;
syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
if (IS_ERR(syscon)) {
pr_err("%pOFn: syscon lookup failed\n", dev->of_node);
return PTR_ERR(syscon);
}
err = register_restart_handler(&axxia_restart_nb);
if (err)
dev_err(dev, "cannot register restart handler (err=%d)\n", err);
return err;
}
static const struct of_device_id of_axxia_reset_match[] = {
{ .compatible = "lsi,axm55xx-reset", },
{},
};
MODULE_DEVICE_TABLE(of, of_axxia_reset_match);
static struct platform_driver axxia_reset_driver = {
.probe = axxia_reset_probe,
.driver = {
.name = "axxia-reset",
.of_match_table = of_match_ptr(of_axxia_reset_match),
},
};
static int __init axxia_reset_init(void)
{
return platform_driver_register(&axxia_reset_driver);
}
device_initcall(axxia_reset_init);