Commit 751cd4aca2a4225eaf4a552c6ad47aade2f06e33

Authored by Dan Murphy

Merge branch 'platform-ti-linux-4.1.y' of git://git.ti.com/~rrnayak/ti-linux-ker…

…nel/platform-linux-feature-tree into ti-linux-4.1.y

TI-Feature: platform_base
TI-Tree: git://git.ti.com/~rrnayak/ti-linux-kernel/platform-linux-feature-tree.git
TI-Branch: platform-ti-linux-4.1.y

* 'platform-ti-linux-4.1.y' of git://git.ti.com/~rrnayak/ti-linux-kernel/platform-linux-feature-tree:
  ARM: dts: k2g: Add DSP GPIO controller node
  ARM: dts: k2g: Add keystone IRQ controller node
  ARM: dts: k2g: Add device state controller node
  ti_config_fragments/baseport: Enable TI SCI reset driver
  ARM: dts: k2g: Add TI SCI reset-controller node
  reset: Add the TI SCI reset driver
  Documentation: dt: reset: Add TI SCI reset binding
  dt-bindings: reset: Add k2g reset definitions
  ti_config_fragments/baseport: enable reset-syscon driver
  ARM: Keystone: Enable ARCH_HAS_RESET_CONTROLLER
  ARM: dts: keystone: Add PSC reset node
  reset: add a SYSCON based reset driver
  Documentation: dt: reset: Add syscon reset binding

Signed-off-by: Dan Murphy <DMurphy@ti.com>

Conflicts:
	arch/arm/boot/dts/k2g.dtsi

Showing 11 changed files Side-by-side Diff

Documentation/devicetree/bindings/reset/syscon-reset.txt
  1 +SysCon Reset Controller
  2 +=======================
  3 +
  4 +Almost all SoCs have hardware modules that require reset control in addition
  5 +to clock and power control for their functionality. The reset control is
  6 +typically provided by means of memory-mapped I/O registers. These registers are
  7 +sometimes a part of a larger register space region implementing various
  8 +functionalities. This register range is best represented as a syscon node to
  9 +allow multiple entities to access their relevant registers in the common
  10 +register space.
  11 +
  12 +A SysCon Reset Controller node defines a device that uses a syscon node
  13 +and provides reset management functionality for various hardware modules
  14 +present on the SoC.
  15 +
  16 +SysCon Reset Controller Node
  17 +============================
  18 +Each of the reset provider/controller nodes should have the following
  19 +properties.
  20 +
  21 +Required properties:
  22 +--------------------
  23 + - compatible : Should be "syscon-reset"
  24 + - syscon : phandle to the syscon node containing the reset registers
  25 + - #reset-cells : Should be 6. Please see the reset consumer node below for
  26 + usage details
  27 +
  28 +SysCon Reset Consumer Nodes
  29 +===========================
  30 +Each of the reset consumer nodes should have the following properties,
  31 +in addition to their own properties.
  32 +
  33 +Required properties:
  34 +--------------------
  35 + - resets : A phandle and reset specifier pair, one pair for each reset
  36 + signal that affects the device, or that the device manages.
  37 + The phandle should point to the syscon node containing the
  38 + reset registers, and the reset specifier should have 6
  39 + cell-values. The reset specifier contains two similar pairs
  40 + of 3 cell-values each, the first of the pair containing the
  41 + reset control register information, and the second of the pair
  42 + containing the reset status register information. The reset
  43 + control and status registers can be same on some devices/SoCs.
  44 +
  45 + Each of the pairs of 3 cell-values should have the following
  46 + values:
  47 + Cell #1 : register offset of the reset control/status
  48 + register from the syscon register base
  49 + Cell #2 : bit shift value for the reset in the respective
  50 + reset control/status register
  51 + Cell #3 : polarity of the reset bit. Should be 1 for resets
  52 + that are asserted when the bit is set, 0 for
  53 + resets that are asserted when the bit is cleared
  54 +
  55 +Please also refer to Documentation/devicetree/bindings/reset/reset.txt for
  56 +common reset controller usage by consumers.
  57 +
  58 +
  59 +Example:
  60 +--------
  61 +The following example demonstrates a syscon node, the reset controller node
  62 +using the syscon node, and a consumer (a DSP device) on the TI Keystone 2
  63 +Hawking SoC.
  64 +
  65 +/ {
  66 + soc {
  67 + psc: power-sleep-controller@02350000 {
  68 + compatible = "syscon";
  69 + reg = <0x02350000 0x1000>;
  70 + };
  71 +
  72 + pscrst: psc-reset {
  73 + compatible = "syscon-reset";
  74 + syscon = <&psc>;
  75 + #reset-cells = <6>;
  76 + };
  77 +
  78 + dsp0: dsp0 {
  79 + ...
  80 + resets = <&pscrst 0xa3c 8 0 0x83c 8 0>;
  81 + ...
  82 + };
  83 + };
  84 +};
Documentation/devicetree/bindings/reset/ti,sci-reset.txt
  1 +Texas Instruments System Control Interface (TI-SCI) Reset Controller
  2 +=====================================================================
  3 +
  4 +Some TI SoCs contain a system controller (like the Power Management Micro
  5 +Controller (PMMC) on Keystone 2 Galileo SoC) that are responsible for
  6 +controlling the state of the various hardware modules present on the SoC.
  7 +Communication between the host processor running an OS and the system
  8 +controller happens through a protocol called TI System Control Interface
  9 +(TI-SCI protocol). For TI SCI details, please refer to the document,
  10 +Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
  11 +
  12 +TI-SCI Reset Controller Node
  13 +============================
  14 +This reset controller node uses the TI SCI protocol to perform the reset
  15 +management of various hardware modules present on the SoC.
  16 +
  17 +Required properties:
  18 +--------------------
  19 + - compatible : Should be "ti,sci-reset"
  20 + - ti,sci : phandle to the TI SCI device to use for managing resets
  21 + - #reset-cells : Should be 2. Please see the reset consumer node below for
  22 + usage details.
  23 +
  24 +TI-SCI Reset Consumer Nodes
  25 +===========================
  26 +Each of the reset consumer nodes should have the following properties,
  27 +in addition to their own properties.
  28 +
  29 +Required properties:
  30 +--------------------
  31 + - resets : A phandle and reset specifier pair, one pair for each reset
  32 + signal that affects the device, or that the device manages.
  33 + The phandle should point to the TI-SCI reset controller node,
  34 + and the reset specifier should have 2 cell-values. The first
  35 + cell should contain the device ID, the values of which are
  36 + specified in the <dt-bindings/genpd/<soc>.h> include file.
  37 + The second cell should contain the reset mask value used by
  38 + system controller, the values of which are specified in the
  39 + include file <dt-bindings/reset/<soc>.h>, where <soc> is the
  40 + name of the SoC involved, for example 'k2g'.
  41 +
  42 +Please also refer to Documentation/devicetree/bindings/reset/reset.txt for
  43 +common reset controller usage by consumers.
  44 +
  45 +
  46 +Example:
  47 +--------
  48 +The following example demonstrates both a TI-SCI reset controller node and a
  49 +consumer (a DSP device) on the Keystone 2 Galileo SoC.
  50 +
  51 +#include <dt-bindings/genpd/k2g.h>
  52 +#include <dt-bindings/reset/k2g.h>
  53 +
  54 +/ {
  55 + soc {
  56 + k2g_reset: k2g_reset {
  57 + compatible = "ti,sci-reset";
  58 + ti,sci = <&pmmc>;
  59 + #reset-cells = <2>;
  60 + };
  61 +
  62 + dsp0: dsp0 {
  63 + ...
  64 + resets = <&k2g_reset K2G_DEV_CGEM0 K2G_DEV_CGEM0_DSP0_RESET>;
  65 + ...
  66 + };
  67 + };
  68 +};
arch/arm/boot/dts/k2g.dtsi
... ... @@ -17,6 +17,7 @@
17 17 #include <dt-bindings/pinctrl/keystone.h>
18 18 #include <dt-bindings/genpd/k2g.h>
19 19 #include <dt-bindings/clock/k2g.h>
  20 +#include <dt-bindings/reset/k2g.h>
20 21 #include "skeleton.dtsi"
21 22  
22 23 / {
... ... @@ -89,6 +90,11 @@
89 90 ranges = <0x0 0x0 0x0 0xc0000000>;
90 91 dma-ranges = <0x80000000 0x8 0x00000000 0x80000000>;
91 92  
  93 + devctrl: device-state-control@02620000 {
  94 + compatible = "ti,keystone-devctrl", "syscon";
  95 + reg = <0x02620000 0x1000>;
  96 + };
  97 +
92 98 k2g_pinctrl: pinmux@02621000 {
93 99 compatible = "pinctrl-single";
94 100 reg = <0x02621000 0x410>;
... ... @@ -473,6 +479,27 @@
473 479 compatible = "ti,sci-pm-domains";
474 480 #power-domain-cells = <1>;
475 481 ti,sci = <&pmmc>;
  482 + };
  483 +
  484 + k2g_reset: k2g_reset {
  485 + compatible = "ti,sci-reset";
  486 + ti,sci = <&pmmc>;
  487 + #reset-cells = <2>;
  488 + };
  489 +
  490 + kirq0: keystone_irq@026202a0 {
  491 + compatible = "ti,keystone-irq";
  492 + interrupts = <GIC_SPI 1 IRQ_TYPE_EDGE_RISING>;
  493 + interrupt-controller;
  494 + #interrupt-cells = <1>;
  495 + ti,syscon-dev = <&devctrl 0x2a0>;
  496 + };
  497 +
  498 + dspgpio0: keystone_dsp_gpio@02620240 {
  499 + compatible = "ti,keystone-dsp-gpio";
  500 + gpio-controller;
  501 + #gpio-cells = <2>;
  502 + gpio,syscon-dev = <&devctrl 0x240>;
476 503 };
477 504  
478 505 mdio: mdio@4200f00 {
arch/arm/boot/dts/keystone.dtsi
... ... @@ -89,6 +89,12 @@
89 89 ti,wdt-list = <0>;
90 90 };
91 91  
  92 + pscrst: psc-reset {
  93 + compatible = "syscon-reset";
  94 + syscon = <&psc>;
  95 + #reset-cells = <6>;
  96 + };
  97 +
92 98 /include/ "keystone-clocks.dtsi"
93 99  
94 100 uart0: serial@02530c00 {
arch/arm/mach-keystone/Kconfig
... ... @@ -5,6 +5,7 @@
5 5 select ARM_GIC
6 6 select HAVE_ARM_ARCH_TIMER
7 7 select CLKSRC_MMIO
  8 + select ARCH_HAS_RESET_CONTROLLER
8 9 select ARM_ERRATA_798181 if SMP
9 10 select COMMON_CLK_KEYSTONE
10 11 select ARCH_SUPPORTS_BIG_ENDIAN
drivers/reset/Kconfig
... ... @@ -12,5 +12,24 @@
12 12  
13 13 If unsure, say no.
14 14  
  15 +config SYSCON_RESET
  16 + tristate "SYSCON Reset Driver"
  17 + depends on RESET_CONTROLLER
  18 + select MFD_SYSCON
  19 + help
  20 + This enables the reset driver support for devices with memory-mapped
  21 + reset registers as part of a syscon device node. If you wish to use
  22 + the reset framework for such memory-mapped devices, say Y here.
  23 + Otherwise, say N.
  24 +
  25 +config TI_SCI_RESET
  26 + tristate "TI System Control Interface (TI-SCI) reset driver"
  27 + depends on RESET_CONTROLLER
  28 + depends on TI_SCI_PROTOCOL
  29 + help
  30 + This enables the reset driver support over TI System Control Interface
  31 + for TI's Keystone family of SoCs. If you wish to use reset resources
  32 + managed by the TI System Controller, say Y here. Otherwise, say N.
  33 +
15 34 source "drivers/reset/sti/Kconfig"
drivers/reset/Makefile
... ... @@ -3,4 +3,7 @@
3 3 obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o
4 4 obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
5 5 obj-$(CONFIG_ARCH_STI) += sti/
  6 +
  7 +obj-$(CONFIG_SYSCON_RESET) += reset-syscon.o
  8 +obj-$(CONFIG_TI_SCI_RESET) += reset-ti-sci.o
drivers/reset/reset-syscon.c
  1 +/*
  2 + * SYSCON regmap reset driver
  3 + *
  4 + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
  5 + * Andrew F. Davis <afd@ti.com>
  6 + * Suman Anna <afd@ti.com>
  7 + *
  8 + * This program is free software; you can redistribute it and/or modify
  9 + * it under the terms of the GNU General Public License version 2 as
  10 + * published by the Free Software Foundation.
  11 + *
  12 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  13 + * kind, whether express or implied; without even the implied warranty
  14 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + * GNU General Public License for more details.
  16 + */
  17 +
  18 +#include <linux/idr.h>
  19 +#include <linux/mfd/syscon.h>
  20 +#include <linux/module.h>
  21 +#include <linux/of.h>
  22 +#include <linux/platform_device.h>
  23 +#include <linux/regmap.h>
  24 +#include <linux/reset-controller.h>
  25 +
  26 +/**
  27 + * struct syscon_reset_control - reset control structure
  28 + * @offset: reset control register offset from syscon base
  29 + * @reset_bit: reset bit in the reset control register
  30 + * @assert_high: flag to indicate if setting the bit high asserts the reset
  31 + * @status_offset: reset status register offset from syscon base
  32 + * @status_reset_bit: reset status bit in the reset status register
  33 + * @status_assert_high: flag to indicate if a set bit represents asserted state
  34 + */
  35 +struct syscon_reset_control {
  36 + unsigned int offset;
  37 + unsigned int reset_bit;
  38 + bool assert_high;
  39 + unsigned int status_offset;
  40 + unsigned int status_reset_bit;
  41 + bool status_assert_high;
  42 +};
  43 +
  44 +/**
  45 + * struct syscon_reset_data - reset controller information structure
  46 + * @rcdev: reset controller entity
  47 + * @dev: reset controller device pointer
  48 + * @memory: regmap handle containing the memory-mapped reset registers
  49 + * @idr: idr structure for mapping ids to reset control structures
  50 + */
  51 +struct syscon_reset_data {
  52 + struct reset_controller_dev rcdev;
  53 + struct device *dev;
  54 + struct regmap *memory;
  55 + struct idr idr;
  56 +};
  57 +
  58 +#define to_syscon_reset_data(rcdev) \
  59 + container_of(rcdev, struct syscon_reset_data, rcdev)
  60 +
  61 +/**
  62 + * syscon_reset_set() - program a device's reset
  63 + * @rcdev: reset controller entity
  64 + * @id: ID of the reset to toggle
  65 + * @assert: boolean flag to indicate assert or deassert
  66 + *
  67 + * This is a common internal function used to assert or deassert a device's
  68 + * reset using the regmap API. The device's reset is asserted if the @assert
  69 + * argument is true, or deasserted if the @assert argument is false.
  70 + *
  71 + * Return: 0 for successful request, else a corresponding error value
  72 + */
  73 +static int syscon_reset_set(struct reset_controller_dev *rcdev,
  74 + unsigned long id, bool assert)
  75 +{
  76 + struct syscon_reset_data *data = to_syscon_reset_data(rcdev);
  77 + struct syscon_reset_control *control;
  78 + unsigned int mask, value;
  79 +
  80 + control = idr_find(&data->idr, id);
  81 + if (!control)
  82 + return -EINVAL;
  83 +
  84 + mask = BIT(control->reset_bit);
  85 + value = (assert == control->assert_high) ? mask : 0x0;
  86 +
  87 + return regmap_update_bits(data->memory, control->offset, mask, value);
  88 +}
  89 +
  90 +/**
  91 + * syscon_reset_assert() - assert device reset
  92 + * @rcdev: reset controller entity
  93 + * @id: ID of the reset to be asserted
  94 + *
  95 + * This function implements the reset driver op to assert a device's reset.
  96 + * This invokes the function syscon_reset_set() with the corresponding
  97 + * parameters as passed in, but with the @assert argument set to true for
  98 + * asserting the reset.
  99 + *
  100 + * Return: 0 for successful request, else a corresponding error value
  101 + */
  102 +static int syscon_reset_assert(struct reset_controller_dev *rcdev,
  103 + unsigned long id)
  104 +{
  105 + return syscon_reset_set(rcdev, id, true);
  106 +}
  107 +
  108 +/**
  109 + * syscon_reset_deassert() - deassert device reset
  110 + * @rcdev: reset controller entity
  111 + * @id: ID of reset to be deasserted
  112 + *
  113 + * This function implements the reset driver op to deassert a device's reset.
  114 + * This invokes the function syscon_reset_set() with the corresponding
  115 + * parameters as passed in, but with the @assert argument set to false for
  116 + * deasserting the reset.
  117 + *
  118 + * Return: 0 for successful request, else a corresponding error value
  119 + */
  120 +static int syscon_reset_deassert(struct reset_controller_dev *rcdev,
  121 + unsigned long id)
  122 +{
  123 + return syscon_reset_set(rcdev, id, false);
  124 +}
  125 +
  126 +/**
  127 + * syscon_reset_status() - check device reset status
  128 + * @rcdev: reset controller entity
  129 + * @id: ID of the reset for which the status is being requested
  130 + *
  131 + * This function implements the reset driver op to return the status of a
  132 + * device's reset.
  133 + *
  134 + * Return: 0 if reset is deasserted, or a non-zero value if reset is asserted
  135 + */
  136 +static int syscon_reset_status(struct reset_controller_dev *rcdev,
  137 + unsigned long id)
  138 +{
  139 + struct syscon_reset_data *data = to_syscon_reset_data(rcdev);
  140 + struct syscon_reset_control *control;
  141 + unsigned int reset_state;
  142 + int ret;
  143 +
  144 + control = idr_find(&data->idr, id);
  145 + if (!control)
  146 + return -EINVAL;
  147 +
  148 + ret = regmap_read(data->memory, control->status_offset, &reset_state);
  149 + if (ret)
  150 + return ret;
  151 +
  152 + return (reset_state & BIT(control->status_reset_bit)) ==
  153 + control->status_assert_high;
  154 +}
  155 +
  156 +static struct reset_control_ops syscon_reset_ops = {
  157 + .assert = syscon_reset_assert,
  158 + .deassert = syscon_reset_deassert,
  159 + .status = syscon_reset_status,
  160 +};
  161 +
  162 +/**
  163 + * syscon_reset_of_xlate() - translate a set of OF arguments to a reset ID
  164 + * @rcdev: reset controller entity
  165 + * @reset_spec: OF reset argument specifier
  166 + *
  167 + * This function performs the translation of the reset argument specifier
  168 + * values defined in a reset consumer device node. The function allocates a
  169 + * reset control structure for that device reset, that will be used by the
  170 + * driver for performing any reset functions on that reset. An idr structure
  171 + * is allocated and used to map to the reset control structure. This idr is
  172 + * used by the driver to do reset lookups.
  173 + *
  174 + * Return: 0 for successful request, else a corresponding error value
  175 + */
  176 +static int syscon_reset_of_xlate(struct reset_controller_dev *rcdev,
  177 + const struct of_phandle_args *reset_spec)
  178 +{
  179 + struct syscon_reset_data *data = to_syscon_reset_data(rcdev);
  180 + struct syscon_reset_control *control;
  181 +
  182 + if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
  183 + return -EINVAL;
  184 +
  185 + control = devm_kzalloc(data->dev, sizeof(*control), GFP_KERNEL);
  186 + if (!control)
  187 + return -ENOMEM;
  188 +
  189 + control->offset = reset_spec->args[0];
  190 + control->reset_bit = reset_spec->args[1];
  191 + control->assert_high = reset_spec->args[2] == 1;
  192 + control->status_offset = reset_spec->args[3];
  193 + control->status_reset_bit = reset_spec->args[4];
  194 + control->status_assert_high = reset_spec->args[5] == 1;
  195 +
  196 + return idr_alloc(&data->idr, control, 0, 0, GFP_KERNEL);
  197 +}
  198 +
  199 +static const struct of_device_id syscon_reset_of_match[] = {
  200 + { .compatible = "syscon-reset", },
  201 + { /* sentinel */ },
  202 +};
  203 +MODULE_DEVICE_TABLE(of, syscon_reset_of_match);
  204 +
  205 +static int syscon_reset_probe(struct platform_device *pdev)
  206 +{
  207 + struct syscon_reset_data *data;
  208 + struct device_node *np = pdev->dev.of_node;
  209 + struct regmap *memory;
  210 +
  211 + if (!np)
  212 + return -ENODEV;
  213 +
  214 + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  215 + if (!data)
  216 + return -ENOMEM;
  217 +
  218 + memory = syscon_regmap_lookup_by_phandle(np, "syscon");
  219 + if (IS_ERR(memory))
  220 + return PTR_ERR(memory);
  221 +
  222 + data->rcdev.ops = &syscon_reset_ops;
  223 + data->rcdev.owner = THIS_MODULE;
  224 + data->rcdev.of_node = np;
  225 + data->rcdev.of_reset_n_cells = 6;
  226 + data->rcdev.of_xlate = syscon_reset_of_xlate;
  227 + data->dev = &pdev->dev;
  228 + data->memory = memory;
  229 + idr_init(&data->idr);
  230 +
  231 + platform_set_drvdata(pdev, data);
  232 +
  233 + return reset_controller_register(&data->rcdev);
  234 +}
  235 +
  236 +static int syscon_reset_remove(struct platform_device *pdev)
  237 +{
  238 + struct syscon_reset_data *data = platform_get_drvdata(pdev);
  239 +
  240 + reset_controller_unregister(&data->rcdev);
  241 +
  242 + idr_destroy(&data->idr);
  243 +
  244 + return 0;
  245 +}
  246 +
  247 +static struct platform_driver syscon_reset_driver = {
  248 + .probe = syscon_reset_probe,
  249 + .remove = syscon_reset_remove,
  250 + .driver = {
  251 + .name = "syscon-reset",
  252 + .of_match_table = syscon_reset_of_match,
  253 + },
  254 +};
  255 +module_platform_driver(syscon_reset_driver);
  256 +
  257 +MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
  258 +MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
  259 +MODULE_DESCRIPTION("SYSCON Regmap Reset Driver");
  260 +MODULE_LICENSE("GPL v2");
drivers/reset/reset-ti-sci.c
  1 +/*
  2 + * Texas Instrument's System Control Interface (TI-SCI) reset driver for TI's
  3 + * Keystone generation devices
  4 + *
  5 + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
  6 + * Andrew F. Davis <afd@ti.com>
  7 + *
  8 + * This program is free software; you can redistribute it and/or modify
  9 + * it under the terms of the GNU General Public License version 2 as
  10 + * published by the Free Software Foundation.
  11 + *
  12 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  13 + * kind, whether express or implied; without even the implied warranty
  14 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + * GNU General Public License for more details.
  16 + */
  17 +
  18 +#include <linux/idr.h>
  19 +#include <linux/module.h>
  20 +#include <linux/of.h>
  21 +#include <linux/platform_device.h>
  22 +#include <linux/reset-controller.h>
  23 +#include <linux/ti_sci_protocol.h>
  24 +
  25 +/**
  26 + * struct ti_sci_reset_control - reset control structure
  27 + * @dev_id: SoC-specific device identifier
  28 + * @reset_mask: reset mask to use for toggling reset
  29 + */
  30 +struct ti_sci_reset_control {
  31 + u32 dev_id;
  32 + u32 reset_mask;
  33 +};
  34 +
  35 +/**
  36 + * struct ti_sci_reset_data - reset controller information structure
  37 + * @rcdev: reset controller entity
  38 + * @dev: reset controller device pointer
  39 + * @sci: TI SCI handle used for communication with system controller
  40 + * @idr: idr structure for mapping ids to reset control structures
  41 + */
  42 +struct ti_sci_reset_data {
  43 + struct reset_controller_dev rcdev;
  44 + struct device *dev;
  45 + const struct ti_sci_handle *sci;
  46 + struct idr idr;
  47 +};
  48 +
  49 +#define to_ti_sci_reset_data(rcdev) \
  50 + container_of(rcdev, struct ti_sci_reset_data, rcdev)
  51 +
  52 +/**
  53 + * ti_sci_reset_set() - program a device's reset
  54 + * @rcdev: reset controller entity
  55 + * @id: ID of the reset to toggle
  56 + * @assert: boolean flag to indicate assert or deassert
  57 + *
  58 + * This is a common internal function used to assert or deassert a device's
  59 + * reset using the TI SCI protocol. The device's reset is asserted if the
  60 + * @assert argument is true, or deasserted if @assert argument is false.
  61 + * The mechanism itself is a read-modify-write procedure, the current device
  62 + * reset register is read using a TI SCI device operation, the new value is
  63 + * set or un-set using the reset's mask, and the new reset value written by
  64 + * using another TI SCI device operation.
  65 + *
  66 + * Return: 0 for successful request, else a corresponding error value
  67 + */
  68 +static int ti_sci_reset_set(struct reset_controller_dev *rcdev,
  69 + unsigned long id, bool assert)
  70 +{
  71 + struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
  72 + const struct ti_sci_handle *sci = data->sci;
  73 + const struct ti_sci_dev_ops *dev_ops = &sci->ops.dev_ops;
  74 + struct ti_sci_reset_control *control;
  75 + u32 reset_state;
  76 + int ret;
  77 +
  78 + control = idr_find(&data->idr, id);
  79 + if (!control)
  80 + return -EINVAL;
  81 +
  82 + ret = dev_ops->get_device_resets(sci, control->dev_id,
  83 + &reset_state);
  84 + if (ret)
  85 + return ret;
  86 +
  87 + if (assert)
  88 + reset_state |= control->reset_mask;
  89 + else
  90 + reset_state &= ~control->reset_mask;
  91 +
  92 + return dev_ops->set_device_resets(sci, control->dev_id,
  93 + reset_state);
  94 +}
  95 +
  96 +/**
  97 + * ti_sci_reset_assert() - assert device reset
  98 + * @rcdev: reset controller entity
  99 + * @id: ID of the reset to be asserted
  100 + *
  101 + * This function implements the reset driver op to assert a device's reset
  102 + * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
  103 + * with the corresponding parameters as passed in, but with the @assert
  104 + * argument set to true for asserting the reset.
  105 + *
  106 + * Return: 0 for successful request, else a corresponding error value
  107 + */
  108 +static int ti_sci_reset_assert(struct reset_controller_dev *rcdev,
  109 + unsigned long id)
  110 +{
  111 + return ti_sci_reset_set(rcdev, id, true);
  112 +}
  113 +
  114 +/**
  115 + * ti_sci_reset_deassert() - deassert device reset
  116 + * @rcdev: reset controller entity
  117 + * @id: ID of the reset to be deasserted
  118 + *
  119 + * This function implements the reset driver op to deassert a device's reset
  120 + * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
  121 + * with the corresponding parameters as passed in, but with the @assert
  122 + * argument set to false for deasserting the reset.
  123 + *
  124 + * Return: 0 for successful request, else a corresponding error value
  125 + */
  126 +static int ti_sci_reset_deassert(struct reset_controller_dev *rcdev,
  127 + unsigned long id)
  128 +{
  129 + return ti_sci_reset_set(rcdev, id, false);
  130 +}
  131 +
  132 +/**
  133 + * ti_sci_reset_status() - check device reset status
  134 + * @rcdev: reset controller entity
  135 + * @id: ID of reset to be checked
  136 + *
  137 + * This function implements the reset driver op to return the status of a
  138 + * device's reset using the TI SCI protocol. The reset register value is read
  139 + * by invoking the TI SCI device opertation .get_device_resets(), and the
  140 + * status of the specific reset is extracted and returned using this reset's
  141 + * reset mask.
  142 + *
  143 + * Return: 0 if reset is deasserted, or a non-zero value if reset is asserted
  144 + */
  145 +static int ti_sci_reset_status(struct reset_controller_dev *rcdev,
  146 + unsigned long id)
  147 +{
  148 + struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
  149 + const struct ti_sci_handle *sci = data->sci;
  150 + const struct ti_sci_dev_ops *dev_ops = &sci->ops.dev_ops;
  151 + struct ti_sci_reset_control *control;
  152 + u32 reset_state;
  153 + int ret;
  154 +
  155 + control = idr_find(&data->idr, id);
  156 + if (!control)
  157 + return -EINVAL;
  158 +
  159 + ret = dev_ops->get_device_resets(sci, control->dev_id,
  160 + &reset_state);
  161 + if (ret)
  162 + return ret;
  163 +
  164 + return reset_state & control->reset_mask;
  165 +}
  166 +
  167 +static struct reset_control_ops ti_sci_reset_ops = {
  168 + .assert = ti_sci_reset_assert,
  169 + .deassert = ti_sci_reset_deassert,
  170 + .status = ti_sci_reset_status,
  171 +};
  172 +
  173 +/**
  174 + * ti_sci_reset_of_xlate() - translate a set of OF arguments to a reset ID
  175 + * @rcdev: reset controller entity
  176 + * @reset_spec: OF reset argument specifier
  177 + *
  178 + * This function performs the translation of the reset argument specifier
  179 + * values defined in a reset consumer device node. The function allocates a
  180 + * reset control structure for that device reset, and will be used by the
  181 + * driver for performing any reset functions on that reset. An idr structure
  182 + * is allocated and used to map to the reset control structure. This idr
  183 + * is used by the driver to do reset lookups.
  184 + *
  185 + * Return: 0 for successful request, else a corresponding error value
  186 + */
  187 +static int ti_sci_reset_of_xlate(struct reset_controller_dev *rcdev,
  188 + const struct of_phandle_args *reset_spec)
  189 +{
  190 + struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
  191 + struct ti_sci_reset_control *control;
  192 +
  193 + if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
  194 + return -EINVAL;
  195 +
  196 + control = devm_kzalloc(data->dev, sizeof(*control), GFP_KERNEL);
  197 + if (!control)
  198 + return -ENOMEM;
  199 +
  200 + control->dev_id = reset_spec->args[0];
  201 + control->reset_mask = reset_spec->args[1];
  202 +
  203 + return idr_alloc(&data->idr, control, 0, 0, GFP_KERNEL);
  204 +}
  205 +
  206 +static const struct of_device_id ti_sci_reset_of_match[] = {
  207 + { .compatible = "ti,sci-reset", },
  208 + { /* sentinel */ },
  209 +};
  210 +MODULE_DEVICE_TABLE(of, ti_sci_reset_of_match);
  211 +
  212 +static int ti_sci_reset_probe(struct platform_device *pdev)
  213 +{
  214 + struct ti_sci_reset_data *data;
  215 +
  216 + if (!pdev->dev.of_node)
  217 + return -ENODEV;
  218 +
  219 + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  220 + if (!data)
  221 + return -ENOMEM;
  222 +
  223 + data->sci = devm_ti_sci_get_handle(&pdev->dev);
  224 + if (IS_ERR(data->sci))
  225 + return PTR_ERR(data->sci);
  226 +
  227 + data->rcdev.ops = &ti_sci_reset_ops;
  228 + data->rcdev.owner = THIS_MODULE;
  229 + data->rcdev.of_node = pdev->dev.of_node;
  230 + data->rcdev.of_reset_n_cells = 2;
  231 + data->rcdev.of_xlate = ti_sci_reset_of_xlate;
  232 + data->dev = &pdev->dev;
  233 + idr_init(&data->idr);
  234 +
  235 + platform_set_drvdata(pdev, data);
  236 +
  237 + return reset_controller_register(&data->rcdev);
  238 +}
  239 +
  240 +static int ti_sci_reset_remove(struct platform_device *pdev)
  241 +{
  242 + struct ti_sci_reset_data *data = platform_get_drvdata(pdev);
  243 +
  244 + reset_controller_unregister(&data->rcdev);
  245 +
  246 + idr_destroy(&data->idr);
  247 +
  248 + return 0;
  249 +}
  250 +
  251 +static struct platform_driver ti_sci_reset_driver = {
  252 + .probe = ti_sci_reset_probe,
  253 + .remove = ti_sci_reset_remove,
  254 + .driver = {
  255 + .name = "ti-sci-reset",
  256 + .of_match_table = ti_sci_reset_of_match,
  257 + },
  258 +};
  259 +module_platform_driver(ti_sci_reset_driver);
  260 +
  261 +MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
  262 +MODULE_DESCRIPTION("TI System Control Interface (TI SCI) Reset driver");
  263 +MODULE_LICENSE("GPL v2");
include/dt-bindings/reset/k2g.h
  1 +/*
  2 + * TI K2G SoC reset definitions
  3 + *
  4 + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + *
  11 + * This program is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + * GNU General Public License for more details.
  15 + */
  16 +
  17 +#ifndef __DT_BINDINGS_RESET_K2G_H__
  18 +#define __DT_BINDINGS_RESET_K2G_H__
  19 +
  20 +#define K2G_DEV_CGEM0_DSP0_RESET 0x1
  21 +
  22 +#endif
ti_config_fragments/baseport.cfg
... ... @@ -72,6 +72,10 @@
72 72 # Enable SCI Generic PM domains
73 73 CONFIG_TI_SCI_PM_DOMAINS=y
74 74  
  75 +# Enable Reset Controllers
  76 +CONFIG_SYSCON_RESET=y
  77 +CONFIG_TI_SCI_RESET=y
  78 +
75 79 CONFIG_REGULATOR=y
76 80 CONFIG_REGULATOR_FIXED_VOLTAGE=y
77 81