mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-29 05:55:02 +08:00
97fb5e8d9b
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>
89 lines
2.2 KiB
C
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);
|