cregit-Linux how code gets into the kernel

Release 4.11 drivers/power/reset/keystone-reset.c

/*
 * TI keystone reboot driver
 *
 * Copyright (C) 2014 Texas Instruments Incorporated. http://www.ti.com/
 *
 * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/io.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/of_platform.h>


#define RSTYPE_RG			0x0

#define RSCTRL_RG			0x4

#define RSCFG_RG			0x8

#define RSISO_RG			0xc


#define RSCTRL_KEY_MASK			0x0000ffff

#define RSCTRL_RESET_MASK		BIT(16)

#define RSCTRL_KEY			0x5a69


#define RSMUX_OMODE_MASK		0xe

#define RSMUX_OMODE_RESET_ON		0xa

#define RSMUX_OMODE_RESET_OFF		0x0

#define RSMUX_LOCK_MASK			0x1

#define RSMUX_LOCK_SET			0x1


#define RSCFG_RSTYPE_SOFT		0x300f

#define RSCFG_RSTYPE_HARD		0x0


#define WDT_MUX_NUMBER			0x4


static int rspll_offset;

static struct regmap *pllctrl_regs;

/**
 * rsctrl_enable_rspll_write - enable access to RSCTRL, RSCFG
 * To be able to access to RSCTRL, RSCFG registers
 * we have to write a key before
 */

static inline int rsctrl_enable_rspll_write(void) { return regmap_update_bits(pllctrl_regs, rspll_offset + RSCTRL_RG, RSCTRL_KEY_MASK, RSCTRL_KEY); }

Contributors

PersonTokensPropCommitsCommitProp
Ivan Khoronzhuk23100.00%1100.00%
Total23100.00%1100.00%


static int rsctrl_restart_handler(struct notifier_block *this, unsigned long mode, void *cmd) { /* enable write access to RSTCTRL */ rsctrl_enable_rspll_write(); /* reset the SOC */ regmap_update_bits(pllctrl_regs, rspll_offset + RSCTRL_RG, RSCTRL_RESET_MASK, 0); return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
Ivan Khoronzhuk2767.50%150.00%
Guenter Roeck1332.50%150.00%
Total40100.00%2100.00%

static struct notifier_block rsctrl_restart_nb = { .notifier_call = rsctrl_restart_handler, .priority = 128, }; static const struct of_device_id rsctrl_of_match[] = { {.compatible = "ti,keystone-reset", }, {}, };
static int rsctrl_probe(struct platform_device *pdev) { int i; int ret; u32 val; unsigned int rg; u32 rsmux_offset; struct regmap *devctrl_regs; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; if (!np) return -ENODEV; /* get regmaps */ pllctrl_regs = syscon_regmap_lookup_by_phandle(np, "ti,syscon-pll"); if (IS_ERR(pllctrl_regs)) return PTR_ERR(pllctrl_regs); devctrl_regs = syscon_regmap_lookup_by_phandle(np, "ti,syscon-dev"); if (IS_ERR(devctrl_regs)) return PTR_ERR(devctrl_regs); ret = of_property_read_u32_index(np, "ti,syscon-pll", 1, &rspll_offset); if (ret) { dev_err(dev, "couldn't read the reset pll offset!\n"); return -EINVAL; } ret = of_property_read_u32_index(np, "ti,syscon-dev", 1, &rsmux_offset); if (ret) { dev_err(dev, "couldn't read the rsmux offset!\n"); return -EINVAL; } /* set soft/hard reset */ val = of_property_read_bool(np, "ti,soft-reset"); val = val ? RSCFG_RSTYPE_SOFT : RSCFG_RSTYPE_HARD; ret = rsctrl_enable_rspll_write(); if (ret) return ret; ret = regmap_write(pllctrl_regs, rspll_offset + RSCFG_RG, val); if (ret) return ret; /* disable a reset isolation for all module clocks */ ret = regmap_write(pllctrl_regs, rspll_offset + RSISO_RG, 0); if (ret) return ret; /* enable a reset for watchdogs from wdt-list */ for (i = 0; i < WDT_MUX_NUMBER; i++) { ret = of_property_read_u32_index(np, "ti,wdt-list", i, &val); if (ret == -EOVERFLOW && !i) { dev_err(dev, "ti,wdt-list property has to contain at" "least one entry\n"); return -EINVAL; } else if (ret) { break; } if (val >= WDT_MUX_NUMBER) { dev_err(dev, "ti,wdt-list property can contain " "only numbers < 4\n"); return -EINVAL; } rg = rsmux_offset + val * 4; ret = regmap_update_bits(devctrl_regs, rg, RSMUX_OMODE_MASK, RSMUX_OMODE_RESET_ON | RSMUX_LOCK_SET); if (ret) return ret; } ret = register_restart_handler(&rsctrl_restart_nb); if (ret) dev_err(dev, "cannot register restart handler (err=%d)\n", ret); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Ivan Khoronzhuk35193.85%133.33%
Guenter Roeck225.88%133.33%
Colin Ian King10.27%133.33%
Total374100.00%3100.00%

static struct platform_driver rsctrl_driver = { .probe = rsctrl_probe, .driver = { .name = KBUILD_MODNAME, .of_match_table = rsctrl_of_match, }, }; module_platform_driver(rsctrl_driver); MODULE_AUTHOR("Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>"); MODULE_DESCRIPTION("Texas Instruments keystone reset driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" KBUILD_MODNAME);

Overall Contributors

PersonTokensPropCommitsCommitProp
Ivan Khoronzhuk56190.78%125.00%
Guenter Roeck558.90%125.00%
Colin Ian King10.16%125.00%
Fabian Frederick10.16%125.00%
Total618100.00%4100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.