Reset controller changes for v4.3
- moved the DT reset binding includes from include/dt-bindings/reset-controller to include/dt-bindings/reset - new driver for LPC18xx Reset Generation Unit (RGU) - of_device_id array in the STi driver changed to const. - extend SoCFPGA reset driver to support Arria10 - new ath79 reset controller driver for AR71XX/AR9XXX - new driver for Xilinx Zynq reset controller -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJV0Km0AAoJEFDCiBxwnmDrOUgQAMkd/AF+Kl2cLpU0am/7yDZE eO4UgnlQ50L3+bXjOdgX0Ge24S6yQRpe66Nj1vpK0lfxzPM+K2/sTfXso0iAhtGd 7OqapeQv+/hlBq2mmPT1smEbDucOFffFmQAq9sV3PbAYgGRn2CD8GYvSoS//0EMm 39KbocTEsuZErf0hmNlhtIwa6vg+Q9H1eWN0A3CZrGOy3zMMGEypyKOyJznIpBZv HccpVN4y3D3BTf2HIWa5p9dHueWv5BdmudM2IypO3EVXOULhu4Jzqt1Fizu9F+yR jvxbB96W8gNDRT5c49vFshkVWfNJAkYnKcXISjWUb0bM9V1l5V62R8f4OJWj24rh GXgT8spdqjze38YYT8VQx7SWXjm6H2aMnrYNMLQsHunJbEbboqCb/JHTTCOrzMSZ FgHWCp0uodNYo/VGWx8GgMKPwrfYpY8iMtm16WSucPZA/ppx21oD8VLzIY1Bd0CW JM5oHG4uYB90EFxQS5XJoAxa9HbIlV6UbHdt44bVPcaQGw9ID+j978Djsjalqqf7 uhA+8wVYGcopOcUWJ8ISsMerQqCiJfMwczhwDh0yEd9NshGv76NbycgsVP/4De6f c8xCEkuADYtWPtaQQakU+l8TfctmrsakNmD5DbkUgoLut+FnkfN1cmHHGnFlI36d DTaKtOAddWkrWebdpXW1 =GBec -----END PGP SIGNATURE----- Merge tag 'reset-for-4.3' of git://git.pengutronix.de/git/pza/linux into next/drivers Reset controller changes for v4.3 - moved the DT reset binding includes from include/dt-bindings/reset-controller to include/dt-bindings/reset - new driver for LPC18xx Reset Generation Unit (RGU) - of_device_id array in the STi driver changed to const. - extend SoCFPGA reset driver to support Arria10 - new ath79 reset controller driver for AR71XX/AR9XXX - new driver for Xilinx Zynq reset controller * tag 'reset-for-4.3' of git://git.pengutronix.de/git/pza/linux: reset: reset-zynq: Adding support for Xilinx Zynq reset controller. docs: dts: Added documentation for Xilinx Zynq Reset Controller bindings. MIPS: ath79: Add the reset controller to the AR9132 dtsi reset: Add a driver for the reset controller on the AR71XX/AR9XXX devicetree: Add bindings for the ATH79 reset controller reset: socfpga: Update reset-socfpga to read the altr,modrst-offset property doc: dt: add documentation for lpc1850-rgu reset driver reset: add driver for lpc18xx rgu reset: sti: constify of_device_id array ARM: STi: DT: Move reset controller constants into common location MAINTAINERS: add include/dt-bindings/reset path to reset controller entry Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
bd90f11589
|
@ -0,0 +1,20 @@
|
||||||
|
Binding for Qualcomm Atheros AR7xxx/AR9XXX reset controller
|
||||||
|
|
||||||
|
Please also refer to reset.txt in this directory for common reset
|
||||||
|
controller binding usage.
|
||||||
|
|
||||||
|
Required Properties:
|
||||||
|
- compatible: has to be "qca,<soctype>-reset", "qca,ar7100-reset"
|
||||||
|
as fallback
|
||||||
|
- reg: Base address and size of the controllers memory area
|
||||||
|
- #reset-cells : Specifies the number of cells needed to encode reset
|
||||||
|
line, should be 1
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
reset-controller@1806001c {
|
||||||
|
compatible = "qca,ar9132-reset", "qca,ar7100-reset";
|
||||||
|
reg = <0x1806001c 0x4>;
|
||||||
|
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
|
@ -0,0 +1,84 @@
|
||||||
|
NXP LPC1850 Reset Generation Unit (RGU)
|
||||||
|
========================================
|
||||||
|
|
||||||
|
Please also refer to reset.txt in this directory for common reset
|
||||||
|
controller binding usage.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: Should be "nxp,lpc1850-rgu"
|
||||||
|
- reg: register base and length
|
||||||
|
- clocks: phandle and clock specifier to RGU clocks
|
||||||
|
- clock-names: should contain "delay" and "reg"
|
||||||
|
- #reset-cells: should be 1
|
||||||
|
|
||||||
|
See table below for valid peripheral reset numbers. Numbers not
|
||||||
|
in the table below are either reserved or not applicable for
|
||||||
|
normal operation.
|
||||||
|
|
||||||
|
Reset Peripheral
|
||||||
|
9 System control unit (SCU)
|
||||||
|
12 ARM Cortex-M0 subsystem core (LPC43xx only)
|
||||||
|
13 CPU core
|
||||||
|
16 LCD controller
|
||||||
|
17 USB0
|
||||||
|
18 USB1
|
||||||
|
19 DMA
|
||||||
|
20 SDIO
|
||||||
|
21 External memory controller (EMC)
|
||||||
|
22 Ethernet
|
||||||
|
25 Flash bank A
|
||||||
|
27 EEPROM
|
||||||
|
28 GPIO
|
||||||
|
29 Flash bank B
|
||||||
|
32 Timer0
|
||||||
|
33 Timer1
|
||||||
|
34 Timer2
|
||||||
|
35 Timer3
|
||||||
|
36 Repetitive Interrupt timer (RIT)
|
||||||
|
37 State Configurable Timer (SCT)
|
||||||
|
38 Motor control PWM (MCPWM)
|
||||||
|
39 QEI
|
||||||
|
40 ADC0
|
||||||
|
41 ADC1
|
||||||
|
42 DAC
|
||||||
|
44 USART0
|
||||||
|
45 UART1
|
||||||
|
46 USART2
|
||||||
|
47 USART3
|
||||||
|
48 I2C0
|
||||||
|
49 I2C1
|
||||||
|
50 SSP0
|
||||||
|
51 SSP1
|
||||||
|
52 I2S0 and I2S1
|
||||||
|
53 Serial Flash Interface (SPIFI)
|
||||||
|
54 C_CAN1
|
||||||
|
55 C_CAN0
|
||||||
|
56 ARM Cortex-M0 application core (LPC4370 only)
|
||||||
|
57 SGPIO (LPC43xx only)
|
||||||
|
58 SPI (LPC43xx only)
|
||||||
|
60 ADCHS (12-bit ADC) (LPC4370 only)
|
||||||
|
|
||||||
|
Refer to NXP LPC18xx or LPC43xx user manual for more details about
|
||||||
|
the reset signals and the connected block/peripheral.
|
||||||
|
|
||||||
|
Reset provider example:
|
||||||
|
rgu: reset-controller@40053000 {
|
||||||
|
compatible = "nxp,lpc1850-rgu";
|
||||||
|
reg = <0x40053000 0x1000>;
|
||||||
|
clocks = <&cgu BASE_SAFE_CLK>, <&ccu1 CLK_CPU_BUS>;
|
||||||
|
clock-names = "delay", "reg";
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
Reset consumer example:
|
||||||
|
mac: ethernet@40010000 {
|
||||||
|
compatible = "nxp,lpc1850-dwmac", "snps,dwmac-3.611", "snps,dwmac";
|
||||||
|
reg = <0x40010000 0x2000>;
|
||||||
|
interrupts = <5>;
|
||||||
|
interrupt-names = "macirq";
|
||||||
|
clocks = <&ccu1 CLK_CPU_ETHERNET>;
|
||||||
|
clock-names = "stmmaceth";
|
||||||
|
resets = <&rgu 22>;
|
||||||
|
reset-names = "stmmaceth";
|
||||||
|
status = "disabled";
|
||||||
|
};
|
|
@ -39,4 +39,4 @@ Example:
|
||||||
};
|
};
|
||||||
|
|
||||||
Macro definitions for the supported reset channels can be found in:
|
Macro definitions for the supported reset channels can be found in:
|
||||||
include/dt-bindings/reset-controller/stih407-resets.h
|
include/dt-bindings/reset/stih407-resets.h
|
||||||
|
|
|
@ -43,5 +43,5 @@ example:
|
||||||
|
|
||||||
Macro definitions for the supported reset channels can be found in:
|
Macro definitions for the supported reset channels can be found in:
|
||||||
|
|
||||||
include/dt-bindings/reset-controller/stih415-resets.h
|
include/dt-bindings/reset/stih415-resets.h
|
||||||
include/dt-bindings/reset-controller/stih416-resets.h
|
include/dt-bindings/reset/stih416-resets.h
|
||||||
|
|
|
@ -42,5 +42,5 @@ example:
|
||||||
|
|
||||||
Macro definitions for the supported reset channels can be found in:
|
Macro definitions for the supported reset channels can be found in:
|
||||||
|
|
||||||
include/dt-bindings/reset-controller/stih415-resets.h
|
include/dt-bindings/reset/stih415-resets.h
|
||||||
include/dt-bindings/reset-controller/stih416-resets.h
|
include/dt-bindings/reset/stih416-resets.h
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
Xilinx Zynq Reset Manager
|
||||||
|
|
||||||
|
The Zynq AP-SoC has several different resets.
|
||||||
|
|
||||||
|
See Chapter 26 of the Zynq TRM (UG585) for more information about Zynq resets.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: "xlnx,zynq-reset"
|
||||||
|
- reg: SLCR offset and size taken via syscon <0x200 0x48>
|
||||||
|
- syscon: <&slcr>
|
||||||
|
This should be a phandle to the Zynq's SLCR registers.
|
||||||
|
- #reset-cells: Must be 1
|
||||||
|
|
||||||
|
The Zynq Reset Manager needs to be a childnode of the SLCR.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
rstc: rstc@200 {
|
||||||
|
compatible = "xlnx,zynq-reset";
|
||||||
|
reg = <0x200 0x48>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
syscon = <&slcr>;
|
||||||
|
};
|
||||||
|
|
||||||
|
Reset outputs:
|
||||||
|
0 : soft reset
|
||||||
|
32 : ddr reset
|
||||||
|
64 : topsw reset
|
||||||
|
96 : dmac reset
|
||||||
|
128: usb0 reset
|
||||||
|
129: usb1 reset
|
||||||
|
160: gem0 reset
|
||||||
|
161: gem1 reset
|
||||||
|
164: gem0 rx reset
|
||||||
|
165: gem1 rx reset
|
||||||
|
166: gem0 ref reset
|
||||||
|
167: gem1 ref reset
|
||||||
|
192: sdio0 reset
|
||||||
|
193: sdio1 reset
|
||||||
|
196: sdio0 ref reset
|
||||||
|
197: sdio1 ref reset
|
||||||
|
224: spi0 reset
|
||||||
|
225: spi1 reset
|
||||||
|
226: spi0 ref reset
|
||||||
|
227: spi1 ref reset
|
||||||
|
256: can0 reset
|
||||||
|
257: can1 reset
|
||||||
|
258: can0 ref reset
|
||||||
|
259: can1 ref reset
|
||||||
|
288: i2c0 reset
|
||||||
|
289: i2c1 reset
|
||||||
|
320: uart0 reset
|
||||||
|
321: uart1 reset
|
||||||
|
322: uart0 ref reset
|
||||||
|
323: uart1 ref reset
|
||||||
|
352: gpio reset
|
||||||
|
384: lqspi reset
|
||||||
|
385: qspi ref reset
|
||||||
|
416: smc reset
|
||||||
|
417: smc ref reset
|
||||||
|
448: ocm reset
|
||||||
|
512: fpga0 out reset
|
||||||
|
513: fpga1 out reset
|
||||||
|
514: fpga2 out reset
|
||||||
|
515: fpga3 out reset
|
||||||
|
544: a9 reset 0
|
||||||
|
545: a9 reset 1
|
||||||
|
552: peri reset
|
||||||
|
|
|
@ -8553,6 +8553,7 @@ M: Philipp Zabel <p.zabel@pengutronix.de>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/reset/
|
F: drivers/reset/
|
||||||
F: Documentation/devicetree/bindings/reset/
|
F: Documentation/devicetree/bindings/reset/
|
||||||
|
F: include/dt-bindings/reset/
|
||||||
F: include/linux/reset.h
|
F: include/linux/reset.h
|
||||||
F: include/linux/reset-controller.h
|
F: include/linux/reset-controller.h
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "stih407-pinctrl.dtsi"
|
#include "stih407-pinctrl.dtsi"
|
||||||
#include <dt-bindings/mfd/st-lpc.h>
|
#include <dt-bindings/mfd/st-lpc.h>
|
||||||
#include <dt-bindings/phy/phy.h>
|
#include <dt-bindings/phy/phy.h>
|
||||||
#include <dt-bindings/reset-controller/stih407-resets.h>
|
#include <dt-bindings/reset/stih407-resets.h>
|
||||||
#include <dt-bindings/interrupt-controller/irq-st.h>
|
#include <dt-bindings/interrupt-controller/irq-st.h>
|
||||||
/ {
|
/ {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "stih415-clock.dtsi"
|
#include "stih415-clock.dtsi"
|
||||||
#include "stih415-pinctrl.dtsi"
|
#include "stih415-pinctrl.dtsi"
|
||||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
#include <dt-bindings/reset-controller/stih415-resets.h>
|
#include <dt-bindings/reset/stih415-resets.h>
|
||||||
/ {
|
/ {
|
||||||
|
|
||||||
L2: cache-controller {
|
L2: cache-controller {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include <dt-bindings/phy/phy.h>
|
#include <dt-bindings/phy/phy.h>
|
||||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
#include <dt-bindings/reset-controller/stih416-resets.h>
|
#include <dt-bindings/reset/stih416-resets.h>
|
||||||
#include <dt-bindings/interrupt-controller/irq-st.h>
|
#include <dt-bindings/interrupt-controller/irq-st.h>
|
||||||
/ {
|
/ {
|
||||||
L2: cache-controller {
|
L2: cache-controller {
|
||||||
|
|
|
@ -118,6 +118,7 @@ config ATH25
|
||||||
|
|
||||||
config ATH79
|
config ATH79
|
||||||
bool "Atheros AR71XX/AR724X/AR913X based boards"
|
bool "Atheros AR71XX/AR724X/AR913X based boards"
|
||||||
|
select ARCH_HAS_RESET_CONTROLLER
|
||||||
select ARCH_REQUIRE_GPIOLIB
|
select ARCH_REQUIRE_GPIOLIB
|
||||||
select BOOT_RAW
|
select BOOT_RAW
|
||||||
select CEVT_R4K
|
select CEVT_R4K
|
||||||
|
|
|
@ -115,6 +115,14 @@
|
||||||
interrupt-controller;
|
interrupt-controller;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rst: reset-controller@1806001c {
|
||||||
|
compatible = "qca,ar9132-reset",
|
||||||
|
"qca,ar7100-reset";
|
||||||
|
reg = <0x1806001c 0x4>;
|
||||||
|
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
spi@1f000000 {
|
spi@1f000000 {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
obj-$(CONFIG_RESET_CONTROLLER) += core.o
|
obj-$(CONFIG_RESET_CONTROLLER) += core.o
|
||||||
|
obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o
|
||||||
obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
|
obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
|
||||||
obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o
|
obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o
|
||||||
obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
|
obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
|
||||||
obj-$(CONFIG_ARCH_STI) += sti/
|
obj-$(CONFIG_ARCH_STI) += sti/
|
||||||
|
obj-$(CONFIG_ARCH_ZYNQ) += reset-zynq.o
|
||||||
|
obj-$(CONFIG_ATH79) += reset-ath79.o
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Alban Bedel <albeu@free.fr>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/reset-controller.h>
|
||||||
|
|
||||||
|
struct ath79_reset {
|
||||||
|
struct reset_controller_dev rcdev;
|
||||||
|
void __iomem *base;
|
||||||
|
spinlock_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ath79_reset_update(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id, bool assert)
|
||||||
|
{
|
||||||
|
struct ath79_reset *ath79_reset =
|
||||||
|
container_of(rcdev, struct ath79_reset, rcdev);
|
||||||
|
unsigned long flags;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ath79_reset->lock, flags);
|
||||||
|
val = readl(ath79_reset->base);
|
||||||
|
if (assert)
|
||||||
|
val |= BIT(id);
|
||||||
|
else
|
||||||
|
val &= ~BIT(id);
|
||||||
|
writel(val, ath79_reset->base);
|
||||||
|
spin_unlock_irqrestore(&ath79_reset->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ath79_reset_assert(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
return ath79_reset_update(rcdev, id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ath79_reset_deassert(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
return ath79_reset_update(rcdev, id, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ath79_reset_status(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
struct ath79_reset *ath79_reset =
|
||||||
|
container_of(rcdev, struct ath79_reset, rcdev);
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = readl(ath79_reset->base);
|
||||||
|
|
||||||
|
return !!(val & BIT(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct reset_control_ops ath79_reset_ops = {
|
||||||
|
.assert = ath79_reset_assert,
|
||||||
|
.deassert = ath79_reset_deassert,
|
||||||
|
.status = ath79_reset_status,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ath79_reset_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct ath79_reset *ath79_reset;
|
||||||
|
struct resource *res;
|
||||||
|
|
||||||
|
ath79_reset = devm_kzalloc(&pdev->dev,
|
||||||
|
sizeof(*ath79_reset), GFP_KERNEL);
|
||||||
|
if (!ath79_reset)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, ath79_reset);
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
ath79_reset->base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
if (IS_ERR(ath79_reset->base))
|
||||||
|
return PTR_ERR(ath79_reset->base);
|
||||||
|
|
||||||
|
ath79_reset->rcdev.ops = &ath79_reset_ops;
|
||||||
|
ath79_reset->rcdev.owner = THIS_MODULE;
|
||||||
|
ath79_reset->rcdev.of_node = pdev->dev.of_node;
|
||||||
|
ath79_reset->rcdev.of_reset_n_cells = 1;
|
||||||
|
ath79_reset->rcdev.nr_resets = 32;
|
||||||
|
|
||||||
|
return reset_controller_register(&ath79_reset->rcdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ath79_reset_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct ath79_reset *ath79_reset = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
reset_controller_unregister(&ath79_reset->rcdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id ath79_reset_dt_ids[] = {
|
||||||
|
{ .compatible = "qca,ar7100-reset", },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, ath79_reset_dt_ids);
|
||||||
|
|
||||||
|
static struct platform_driver ath79_reset_driver = {
|
||||||
|
.probe = ath79_reset_probe,
|
||||||
|
.remove = ath79_reset_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "ath79-reset",
|
||||||
|
.of_match_table = ath79_reset_dt_ids,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module_platform_driver(ath79_reset_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Alban Bedel <albeu@free.fr>");
|
||||||
|
MODULE_DESCRIPTION("AR71xx Reset Controller Driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,258 @@
|
||||||
|
/*
|
||||||
|
* Reset driver for NXP LPC18xx/43xx Reset Generation Unit (RGU).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Joachim Eastwood <manabian@gmail.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/clk.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/reset-controller.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
|
/* LPC18xx RGU registers */
|
||||||
|
#define LPC18XX_RGU_CTRL0 0x100
|
||||||
|
#define LPC18XX_RGU_CTRL1 0x104
|
||||||
|
#define LPC18XX_RGU_ACTIVE_STATUS0 0x150
|
||||||
|
#define LPC18XX_RGU_ACTIVE_STATUS1 0x154
|
||||||
|
|
||||||
|
#define LPC18XX_RGU_RESETS_PER_REG 32
|
||||||
|
|
||||||
|
/* Internal reset outputs */
|
||||||
|
#define LPC18XX_RGU_CORE_RST 0
|
||||||
|
#define LPC43XX_RGU_M0SUB_RST 12
|
||||||
|
#define LPC43XX_RGU_M0APP_RST 56
|
||||||
|
|
||||||
|
struct lpc18xx_rgu_data {
|
||||||
|
struct reset_controller_dev rcdev;
|
||||||
|
struct clk *clk_delay;
|
||||||
|
struct clk *clk_reg;
|
||||||
|
void __iomem *base;
|
||||||
|
spinlock_t lock;
|
||||||
|
u32 delay_us;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_rgu_data(p) container_of(p, struct lpc18xx_rgu_data, rcdev)
|
||||||
|
|
||||||
|
static void __iomem *rgu_base;
|
||||||
|
|
||||||
|
static int lpc18xx_rgu_restart(struct notifier_block *this, unsigned long mode,
|
||||||
|
void *cmd)
|
||||||
|
{
|
||||||
|
writel(BIT(LPC18XX_RGU_CORE_RST), rgu_base + LPC18XX_RGU_CTRL0);
|
||||||
|
mdelay(2000);
|
||||||
|
|
||||||
|
pr_emerg("%s: unable to restart system\n", __func__);
|
||||||
|
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block lpc18xx_rgu_restart_nb = {
|
||||||
|
.notifier_call = lpc18xx_rgu_restart,
|
||||||
|
.priority = 192,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The LPC18xx RGU has mostly self-deasserting resets except for the
|
||||||
|
* two reset lines going to the internal Cortex-M0 cores.
|
||||||
|
*
|
||||||
|
* To prevent the M0 core resets from accidentally getting deasserted
|
||||||
|
* status register must be check and bits in control register set to
|
||||||
|
* preserve the state.
|
||||||
|
*/
|
||||||
|
static int lpc18xx_rgu_setclear_reset(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id, bool set)
|
||||||
|
{
|
||||||
|
struct lpc18xx_rgu_data *rc = to_rgu_data(rcdev);
|
||||||
|
u32 stat_offset = LPC18XX_RGU_ACTIVE_STATUS0;
|
||||||
|
u32 ctrl_offset = LPC18XX_RGU_CTRL0;
|
||||||
|
unsigned long flags;
|
||||||
|
u32 stat, rst_bit;
|
||||||
|
|
||||||
|
stat_offset += (id / LPC18XX_RGU_RESETS_PER_REG) * sizeof(u32);
|
||||||
|
ctrl_offset += (id / LPC18XX_RGU_RESETS_PER_REG) * sizeof(u32);
|
||||||
|
rst_bit = 1 << (id % LPC18XX_RGU_RESETS_PER_REG);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&rc->lock, flags);
|
||||||
|
stat = ~readl(rc->base + stat_offset);
|
||||||
|
if (set)
|
||||||
|
writel(stat | rst_bit, rc->base + ctrl_offset);
|
||||||
|
else
|
||||||
|
writel(stat & ~rst_bit, rc->base + ctrl_offset);
|
||||||
|
spin_unlock_irqrestore(&rc->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lpc18xx_rgu_assert(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
return lpc18xx_rgu_setclear_reset(rcdev, id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lpc18xx_rgu_deassert(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
return lpc18xx_rgu_setclear_reset(rcdev, id, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only M0 cores require explicit reset deassert */
|
||||||
|
static int lpc18xx_rgu_reset(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
struct lpc18xx_rgu_data *rc = to_rgu_data(rcdev);
|
||||||
|
|
||||||
|
lpc18xx_rgu_assert(rcdev, id);
|
||||||
|
udelay(rc->delay_us);
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case LPC43XX_RGU_M0SUB_RST:
|
||||||
|
case LPC43XX_RGU_M0APP_RST:
|
||||||
|
lpc18xx_rgu_setclear_reset(rcdev, id, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lpc18xx_rgu_status(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
struct lpc18xx_rgu_data *rc = to_rgu_data(rcdev);
|
||||||
|
u32 bit, offset = LPC18XX_RGU_ACTIVE_STATUS0;
|
||||||
|
|
||||||
|
offset += (id / LPC18XX_RGU_RESETS_PER_REG) * sizeof(u32);
|
||||||
|
bit = 1 << (id % LPC18XX_RGU_RESETS_PER_REG);
|
||||||
|
|
||||||
|
return !(readl(rc->base + offset) & bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct reset_control_ops lpc18xx_rgu_ops = {
|
||||||
|
.reset = lpc18xx_rgu_reset,
|
||||||
|
.assert = lpc18xx_rgu_assert,
|
||||||
|
.deassert = lpc18xx_rgu_deassert,
|
||||||
|
.status = lpc18xx_rgu_status,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int lpc18xx_rgu_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct lpc18xx_rgu_data *rc;
|
||||||
|
struct resource *res;
|
||||||
|
u32 fcclk, firc;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
rc = devm_kzalloc(&pdev->dev, sizeof(*rc), GFP_KERNEL);
|
||||||
|
if (!rc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
rc->base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
if (IS_ERR(rc->base))
|
||||||
|
return PTR_ERR(rc->base);
|
||||||
|
|
||||||
|
rc->clk_reg = devm_clk_get(&pdev->dev, "reg");
|
||||||
|
if (IS_ERR(rc->clk_reg)) {
|
||||||
|
dev_err(&pdev->dev, "reg clock not found\n");
|
||||||
|
return PTR_ERR(rc->clk_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->clk_delay = devm_clk_get(&pdev->dev, "delay");
|
||||||
|
if (IS_ERR(rc->clk_delay)) {
|
||||||
|
dev_err(&pdev->dev, "delay clock not found\n");
|
||||||
|
return PTR_ERR(rc->clk_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = clk_prepare_enable(rc->clk_reg);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "unable to enable reg clock\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = clk_prepare_enable(rc->clk_delay);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "unable to enable delay clock\n");
|
||||||
|
goto dis_clk_reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
fcclk = clk_get_rate(rc->clk_reg) / USEC_PER_SEC;
|
||||||
|
firc = clk_get_rate(rc->clk_delay) / USEC_PER_SEC;
|
||||||
|
if (fcclk == 0 || firc == 0)
|
||||||
|
rc->delay_us = 2;
|
||||||
|
else
|
||||||
|
rc->delay_us = DIV_ROUND_UP(fcclk, firc * firc);
|
||||||
|
|
||||||
|
spin_lock_init(&rc->lock);
|
||||||
|
|
||||||
|
rc->rcdev.owner = THIS_MODULE;
|
||||||
|
rc->rcdev.nr_resets = 64;
|
||||||
|
rc->rcdev.ops = &lpc18xx_rgu_ops;
|
||||||
|
rc->rcdev.of_node = pdev->dev.of_node;
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, rc);
|
||||||
|
|
||||||
|
ret = reset_controller_register(&rc->rcdev);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "unable to register device\n");
|
||||||
|
goto dis_clks;
|
||||||
|
}
|
||||||
|
|
||||||
|
rgu_base = rc->base;
|
||||||
|
ret = register_restart_handler(&lpc18xx_rgu_restart_nb);
|
||||||
|
if (ret)
|
||||||
|
dev_warn(&pdev->dev, "failed to register restart handler\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dis_clks:
|
||||||
|
clk_disable_unprepare(rc->clk_delay);
|
||||||
|
dis_clk_reg:
|
||||||
|
clk_disable_unprepare(rc->clk_reg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lpc18xx_rgu_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct lpc18xx_rgu_data *rc = platform_get_drvdata(pdev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = unregister_restart_handler(&lpc18xx_rgu_restart_nb);
|
||||||
|
if (ret)
|
||||||
|
dev_warn(&pdev->dev, "failed to unregister restart handler\n");
|
||||||
|
|
||||||
|
reset_controller_unregister(&rc->rcdev);
|
||||||
|
|
||||||
|
clk_disable_unprepare(rc->clk_delay);
|
||||||
|
clk_disable_unprepare(rc->clk_reg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id lpc18xx_rgu_match[] = {
|
||||||
|
{ .compatible = "nxp,lpc1850-rgu" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, lpc18xx_rgu_match);
|
||||||
|
|
||||||
|
static struct platform_driver lpc18xx_rgu_driver = {
|
||||||
|
.probe = lpc18xx_rgu_probe,
|
||||||
|
.remove = lpc18xx_rgu_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "lpc18xx-reset",
|
||||||
|
.of_match_table = lpc18xx_rgu_match,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module_platform_driver(lpc18xx_rgu_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
|
||||||
|
MODULE_DESCRIPTION("Reset driver for LPC18xx/43xx RGU");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
|
@ -24,11 +24,11 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#define NR_BANKS 4
|
#define NR_BANKS 4
|
||||||
#define OFFSET_MODRST 0x10
|
|
||||||
|
|
||||||
struct socfpga_reset_data {
|
struct socfpga_reset_data {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
void __iomem *membase;
|
void __iomem *membase;
|
||||||
|
u32 modrst_offset;
|
||||||
struct reset_controller_dev rcdev;
|
struct reset_controller_dev rcdev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,8 +45,8 @@ static int socfpga_reset_assert(struct reset_controller_dev *rcdev,
|
||||||
|
|
||||||
spin_lock_irqsave(&data->lock, flags);
|
spin_lock_irqsave(&data->lock, flags);
|
||||||
|
|
||||||
reg = readl(data->membase + OFFSET_MODRST + (bank * NR_BANKS));
|
reg = readl(data->membase + data->modrst_offset + (bank * NR_BANKS));
|
||||||
writel(reg | BIT(offset), data->membase + OFFSET_MODRST +
|
writel(reg | BIT(offset), data->membase + data->modrst_offset +
|
||||||
(bank * NR_BANKS));
|
(bank * NR_BANKS));
|
||||||
spin_unlock_irqrestore(&data->lock, flags);
|
spin_unlock_irqrestore(&data->lock, flags);
|
||||||
|
|
||||||
|
@ -67,8 +67,8 @@ static int socfpga_reset_deassert(struct reset_controller_dev *rcdev,
|
||||||
|
|
||||||
spin_lock_irqsave(&data->lock, flags);
|
spin_lock_irqsave(&data->lock, flags);
|
||||||
|
|
||||||
reg = readl(data->membase + OFFSET_MODRST + (bank * NR_BANKS));
|
reg = readl(data->membase + data->modrst_offset + (bank * NR_BANKS));
|
||||||
writel(reg & ~BIT(offset), data->membase + OFFSET_MODRST +
|
writel(reg & ~BIT(offset), data->membase + data->modrst_offset +
|
||||||
(bank * NR_BANKS));
|
(bank * NR_BANKS));
|
||||||
|
|
||||||
spin_unlock_irqrestore(&data->lock, flags);
|
spin_unlock_irqrestore(&data->lock, flags);
|
||||||
|
@ -85,7 +85,7 @@ static int socfpga_reset_status(struct reset_controller_dev *rcdev,
|
||||||
int offset = id % BITS_PER_LONG;
|
int offset = id % BITS_PER_LONG;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
reg = readl(data->membase + OFFSET_MODRST + (bank * NR_BANKS));
|
reg = readl(data->membase + data->modrst_offset + (bank * NR_BANKS));
|
||||||
|
|
||||||
return !(reg & BIT(offset));
|
return !(reg & BIT(offset));
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,8 @@ static int socfpga_reset_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct socfpga_reset_data *data;
|
struct socfpga_reset_data *data;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct device_node *np = dev->of_node;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The binding was mainlined without the required property.
|
* The binding was mainlined without the required property.
|
||||||
|
@ -120,6 +122,11 @@ static int socfpga_reset_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(data->membase))
|
if (IS_ERR(data->membase))
|
||||||
return PTR_ERR(data->membase);
|
return PTR_ERR(data->membase);
|
||||||
|
|
||||||
|
if (of_property_read_u32(np, "altr,modrst-offset", &data->modrst_offset)) {
|
||||||
|
dev_warn(dev, "missing altr,modrst-offset property, assuming 0x10!\n");
|
||||||
|
data->modrst_offset = 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_init(&data->lock);
|
spin_lock_init(&data->lock);
|
||||||
|
|
||||||
data->rcdev.owner = THIS_MODULE;
|
data->rcdev.owner = THIS_MODULE;
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015, National Instruments Corp.
|
||||||
|
*
|
||||||
|
* Xilinx Zynq Reset controller driver
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/mfd/syscon.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/reset-controller.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
struct zynq_reset_data {
|
||||||
|
struct regmap *slcr;
|
||||||
|
struct reset_controller_dev rcdev;
|
||||||
|
u32 offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_zynq_reset_data(p) \
|
||||||
|
container_of((p), struct zynq_reset_data, rcdev)
|
||||||
|
|
||||||
|
static int zynq_reset_assert(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
struct zynq_reset_data *priv = to_zynq_reset_data(rcdev);
|
||||||
|
|
||||||
|
int bank = id / BITS_PER_LONG;
|
||||||
|
int offset = id % BITS_PER_LONG;
|
||||||
|
|
||||||
|
pr_debug("%s: %s reset bank %u offset %u\n", KBUILD_MODNAME, __func__,
|
||||||
|
bank, offset);
|
||||||
|
|
||||||
|
return regmap_update_bits(priv->slcr,
|
||||||
|
priv->offset + (bank * 4),
|
||||||
|
BIT(offset),
|
||||||
|
BIT(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zynq_reset_deassert(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
struct zynq_reset_data *priv = to_zynq_reset_data(rcdev);
|
||||||
|
|
||||||
|
int bank = id / BITS_PER_LONG;
|
||||||
|
int offset = id % BITS_PER_LONG;
|
||||||
|
|
||||||
|
pr_debug("%s: %s reset bank %u offset %u\n", KBUILD_MODNAME, __func__,
|
||||||
|
bank, offset);
|
||||||
|
|
||||||
|
return regmap_update_bits(priv->slcr,
|
||||||
|
priv->offset + (bank * 4),
|
||||||
|
BIT(offset),
|
||||||
|
~BIT(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zynq_reset_status(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
struct zynq_reset_data *priv = to_zynq_reset_data(rcdev);
|
||||||
|
|
||||||
|
int bank = id / BITS_PER_LONG;
|
||||||
|
int offset = id % BITS_PER_LONG;
|
||||||
|
int ret;
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
pr_debug("%s: %s reset bank %u offset %u\n", KBUILD_MODNAME, __func__,
|
||||||
|
bank, offset);
|
||||||
|
|
||||||
|
ret = regmap_read(priv->slcr, priv->offset + (bank * 4), ®);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return !!(reg & BIT(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct reset_control_ops zynq_reset_ops = {
|
||||||
|
.assert = zynq_reset_assert,
|
||||||
|
.deassert = zynq_reset_deassert,
|
||||||
|
.status = zynq_reset_status,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int zynq_reset_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct resource *res;
|
||||||
|
struct zynq_reset_data *priv;
|
||||||
|
|
||||||
|
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||||
|
if (!priv)
|
||||||
|
return -ENOMEM;
|
||||||
|
platform_set_drvdata(pdev, priv);
|
||||||
|
|
||||||
|
priv->slcr = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
|
||||||
|
"syscon");
|
||||||
|
if (IS_ERR(priv->slcr)) {
|
||||||
|
dev_err(&pdev->dev, "unable to get zynq-slcr regmap");
|
||||||
|
return PTR_ERR(priv->slcr);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
if (!res) {
|
||||||
|
dev_err(&pdev->dev, "missing IO resource\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->offset = res->start;
|
||||||
|
|
||||||
|
priv->rcdev.owner = THIS_MODULE;
|
||||||
|
priv->rcdev.nr_resets = resource_size(res) / 4 * BITS_PER_LONG;
|
||||||
|
priv->rcdev.ops = &zynq_reset_ops;
|
||||||
|
priv->rcdev.of_node = pdev->dev.of_node;
|
||||||
|
reset_controller_register(&priv->rcdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zynq_reset_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct zynq_reset_data *priv = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
reset_controller_unregister(&priv->rcdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id zynq_reset_dt_ids[] = {
|
||||||
|
{ .compatible = "xlnx,zynq-reset", },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver zynq_reset_driver = {
|
||||||
|
.probe = zynq_reset_probe,
|
||||||
|
.remove = zynq_reset_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = KBUILD_MODNAME,
|
||||||
|
.of_match_table = zynq_reset_dt_ids,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module_platform_driver(zynq_reset_driver);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
|
MODULE_AUTHOR("Moritz Fischer <moritz.fischer@ettus.com>");
|
||||||
|
MODULE_DESCRIPTION("Zynq Reset Controller Driver");
|
|
@ -11,7 +11,7 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <dt-bindings/reset-controller/stih407-resets.h>
|
#include <dt-bindings/reset/stih407-resets.h>
|
||||||
#include "reset-syscfg.h"
|
#include "reset-syscfg.h"
|
||||||
|
|
||||||
/* STiH407 Peripheral powerdown definitions. */
|
/* STiH407 Peripheral powerdown definitions. */
|
||||||
|
@ -126,7 +126,7 @@ static const struct syscfg_reset_controller_data stih407_picophyreset_controller
|
||||||
.channels = stih407_picophyresets,
|
.channels = stih407_picophyresets,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct of_device_id stih407_reset_match[] = {
|
static const struct of_device_id stih407_reset_match[] = {
|
||||||
{
|
{
|
||||||
.compatible = "st,stih407-powerdown",
|
.compatible = "st,stih407-powerdown",
|
||||||
.data = &stih407_powerdown_controller,
|
.data = &stih407_powerdown_controller,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#include <dt-bindings/reset-controller/stih415-resets.h>
|
#include <dt-bindings/reset/stih415-resets.h>
|
||||||
|
|
||||||
#include "reset-syscfg.h"
|
#include "reset-syscfg.h"
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ static struct syscfg_reset_controller_data stih415_softreset_controller = {
|
||||||
.channels = stih415_softresets,
|
.channels = stih415_softresets,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct of_device_id stih415_reset_match[] = {
|
static const struct of_device_id stih415_reset_match[] = {
|
||||||
{ .compatible = "st,stih415-powerdown",
|
{ .compatible = "st,stih415-powerdown",
|
||||||
.data = &stih415_powerdown_controller, },
|
.data = &stih415_powerdown_controller, },
|
||||||
{ .compatible = "st,stih415-softreset",
|
{ .compatible = "st,stih415-softreset",
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#include <dt-bindings/reset-controller/stih416-resets.h>
|
#include <dt-bindings/reset/stih416-resets.h>
|
||||||
|
|
||||||
#include "reset-syscfg.h"
|
#include "reset-syscfg.h"
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ static struct syscfg_reset_controller_data stih416_softreset_controller = {
|
||||||
.channels = stih416_softresets,
|
.channels = stih416_softresets,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct of_device_id stih416_reset_match[] = {
|
static const struct of_device_id stih416_reset_match[] = {
|
||||||
{ .compatible = "st,stih416-powerdown",
|
{ .compatible = "st,stih416-powerdown",
|
||||||
.data = &stih416_powerdown_controller, },
|
.data = &stih416_powerdown_controller, },
|
||||||
{ .compatible = "st,stih416-softreset",
|
{ .compatible = "st,stih416-softreset",
|
||||||
|
|
Loading…
Reference in New Issue