ARM: SoC driver updates for v4.10

Driver updates for ARM SoCs, including a couple of newly added drivers:
 
 - A new driver for the power management controller on TI Keystone
 - Support for the prerelease "SCPI" firmware protocol that ended up
   being shipped by Amlogic in their GXBB SoC.
 - A soc_device can now be matched using a glob from inside the
   kernel, when another driver wants to know the specific chip
   it is running on and cannot find out from DT, firmware or hardware.
 - Renesas SoCs now support identification through the soc_device
   interface, both in user space and kernel.
 - Renesas r8a7743 and r8a7745 gain support for their system controller
 - A new checking module for the ARM "PSCI" (not to be confused
   with "SCPI" mentioned above) firmware interface.
 - A new driver for the Tegra GMI memory interface
 - Support for the Tegra firmware interfaces with their
   power management controllers
 
 As usual, the updates for the reset controller framework are merged
 here, as they tend to touch multiple SoCs as well, including a new
 driver for the Oxford (now Broadcom) OX820 chip and the Tegra
 bpmp interface.
 
 The existing drivers for Atmel, Qualcomm, NVIDIA, TI Davinci, and
 Rockchips SoCs see some further updates.
 
 Conflicts:
 - ARCH_RENESAS now selects SOC_BUS, but no longer needs GPIOLIB
 - drivers/soc/renesas/Makefile: multiple files got added, keep
   all in logical sorting
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIVAwUAWFMaGWCrR//JCVInAQLs5RAA3I1I8/R+pd5jfMaAB8Od3S4g8YSqIDjC
 EIOoDPx9GDV70+cGs4ea+L9bfGs3ePGivCtcbftNsLDAueQ2jKMa3ShqxA/MMbJE
 rWQi/ARaDFY0nHL8VPWq7XyYwwrah+/gKBr8UhkaKI0vy6DBqxyCknrS2kgF88rv
 DVs2wnRvDM7GVUax0JDzuySR7BXJIuUfS78jPMESASbTQktsZTFUyH+osiqHtptD
 M5bPC8rxOeZXljt3DOvXSdK9rVnji/A3nznY4r3tlt805eaOA7CzjVSsY27WQel0
 63uj+FgE+eM0sECIxpkNbH/HHq2V4QkUoy3fk0xPkzRbllBBpS+UieGamTnPJup8
 wf5uiH1IqLLLV9F/504S92fp0pgFPpOGYWZnBDlIbh3aGq4tMjIRqRYMTyCT02hN
 +b54v0SuImFiN6p8HMS1ugYQ+1m9TU40b5pZkzkTJbSQOMm6oi3j0A0orXU/TPKd
 FVMrlUyfh+yu+vs1hGWLs1+mBjFnxXzSc8yJeaCdX4MvCY5/aVJZ+cwq4Bk+1YU5
 9Qhkeo5JV/l9FlrjxomnEq3l/WV/pFmj7JRZsb1BM88m+5LYUf2lv11b5B4FvrTd
 yx8SSpe3+ofIijdNbJ8IywF6y0OXF6UnrlouOVdSIp+wPs+pibdU/5gQep16pvqd
 WW6sVWn6quA=
 =6dP8
 -----END PGP SIGNATURE-----

Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC driver updates from Arnd Bergmann:
 "Driver updates for ARM SoCs, including a couple of newly added
  drivers:

   - A new driver for the power management controller on TI Keystone

   - Support for the prerelease "SCPI" firmware protocol that ended up
     being shipped by Amlogic in their GXBB SoC.

   - A soc_device can now be matched using a glob from inside the
     kernel, when another driver wants to know the specific chip it is
     running on and cannot find out from DT, firmware or hardware.

   - Renesas SoCs now support identification through the soc_device
     interface, both in user space and kernel.

   - Renesas r8a7743 and r8a7745 gain support for their system
     controller

   - A new checking module for the ARM "PSCI" (not to be confused with
     "SCPI" mentioned above) firmware interface.

   - A new driver for the Tegra GMI memory interface

   - Support for the Tegra firmware interfaces with their power
     management controllers

  As usual, the updates for the reset controller framework are merged
  here, as they tend to touch multiple SoCs as well, including a new
  driver for the Oxford (now Broadcom) OX820 chip and the Tegra bpmp
  interface.

  The existing drivers for Atmel, Qualcomm, NVIDIA, TI Davinci, and
  Rockchips SoCs see some further updates"

* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (76 commits)
  misc: sram: remove useless #ifdef
  drivers: psci: Allow PSCI node to be disabled
  drivers: psci: PSCI checker module
  soc: renesas: Identify SoC and register with the SoC bus
  firmware: qcom: scm: Return PTR_ERR when devm_clk_get fails
  firmware: qcom: scm: Remove core, iface and bus clocks dependency
  dt-bindings: firmware: scm: Add MSM8996 DT bindings
  memory: da8xx-ddrctl: drop the call to of_flat_dt_get_machine_name()
  bus: da8xx-mstpri: drop the call to of_flat_dt_get_machine_name()
  ARM: shmobile: Document DT bindings for Product Register
  soc: renesas: rcar-sysc: add R8A7745 support
  reset: Add Tegra BPMP reset driver
  dt-bindings: firmware: Allow child nodes inside the Tegra BPMP
  dt-bindings: Add power domains to Tegra BPMP firmware
  firmware: tegra: Add BPMP support
  firmware: tegra: Add IVC library
  dt-bindings: firmware: Add bindings for Tegra BPMP
  mailbox: tegra-hsp: Use after free in tegra_hsp_remove_doorbells()
  mailbox: Add Tegra HSP driver
  firmware: arm_scpi: add support for pre-v1.0 SCPI compatible
  ...
This commit is contained in:
Linus Torvalds 2016-12-15 16:03:25 -08:00
commit 991688bfc6
86 changed files with 11428 additions and 722 deletions

View file

@ -94,5 +94,6 @@ config RESET_ZYNQ
source "drivers/reset/sti/Kconfig"
source "drivers/reset/hisilicon/Kconfig"
source "drivers/reset/tegra/Kconfig"
endif

View file

@ -1,6 +1,7 @@
obj-y += core.o
obj-y += hisilicon/
obj-$(CONFIG_ARCH_STI) += sti/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o

View file

@ -32,6 +32,9 @@ static LIST_HEAD(reset_controller_list);
* @refcnt: Number of gets of this reset_control
* @shared: Is this a shared (1), or an exclusive (0) reset_control?
* @deassert_cnt: Number of times this reset line has been deasserted
* @triggered_count: Number of times this reset line has been reset. Currently
* only used for shared resets, which means that the value
* will be either 0 or 1.
*/
struct reset_control {
struct reset_controller_dev *rcdev;
@ -40,6 +43,7 @@ struct reset_control {
unsigned int refcnt;
int shared;
atomic_t deassert_count;
atomic_t triggered_count;
};
/**
@ -134,18 +138,35 @@ EXPORT_SYMBOL_GPL(devm_reset_controller_register);
* reset_control_reset - reset the controlled device
* @rstc: reset controller
*
* Calling this on a shared reset controller is an error.
* On a shared reset line the actual reset pulse is only triggered once for the
* lifetime of the reset_control instance: for all but the first caller this is
* a no-op.
* Consumers must not use reset_control_(de)assert on shared reset lines when
* reset_control_reset has been used.
*/
int reset_control_reset(struct reset_control *rstc)
{
if (WARN_ON(IS_ERR_OR_NULL(rstc)) ||
WARN_ON(rstc->shared))
int ret;
if (WARN_ON(IS_ERR_OR_NULL(rstc)))
return -EINVAL;
if (rstc->rcdev->ops->reset)
return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id);
if (!rstc->rcdev->ops->reset)
return -ENOTSUPP;
return -ENOTSUPP;
if (rstc->shared) {
if (WARN_ON(atomic_read(&rstc->deassert_count) != 0))
return -EINVAL;
if (atomic_inc_return(&rstc->triggered_count) != 1)
return 0;
}
ret = rstc->rcdev->ops->reset(rstc->rcdev, rstc->id);
if (rstc->shared && !ret)
atomic_dec(&rstc->triggered_count);
return ret;
}
EXPORT_SYMBOL_GPL(reset_control_reset);
@ -159,6 +180,8 @@ EXPORT_SYMBOL_GPL(reset_control_reset);
*
* For shared reset controls a driver cannot expect the hw's registers and
* internal state to be reset, but must be prepared for this to happen.
* Consumers must not use reset_control_reset on shared reset lines when
* reset_control_(de)assert has been used.
*/
int reset_control_assert(struct reset_control *rstc)
{
@ -169,6 +192,9 @@ int reset_control_assert(struct reset_control *rstc)
return -ENOTSUPP;
if (rstc->shared) {
if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
return -EINVAL;
if (WARN_ON(atomic_read(&rstc->deassert_count) == 0))
return -EINVAL;
@ -185,6 +211,8 @@ EXPORT_SYMBOL_GPL(reset_control_assert);
* @rstc: reset controller
*
* After calling this function, the reset is guaranteed to be deasserted.
* Consumers must not use reset_control_reset on shared reset lines when
* reset_control_(de)assert has been used.
*/
int reset_control_deassert(struct reset_control *rstc)
{
@ -195,6 +223,9 @@ int reset_control_deassert(struct reset_control *rstc)
return -ENOTSUPP;
if (rstc->shared) {
if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
return -EINVAL;
if (atomic_inc_return(&rstc->deassert_count) != 1)
return 0;
}

View file

@ -1,6 +1,8 @@
/*
* Copyright (C) 2014 Marvell Technology Group Ltd.
*
* Marvell Berlin reset driver
*
* Antoine Tenart <antoine.tenart@free-electrons.com>
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
*
@ -12,7 +14,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
@ -91,7 +93,6 @@ static const struct of_device_id berlin_reset_dt_match[] = {
{ .compatible = "marvell,berlin2-reset" },
{ },
};
MODULE_DEVICE_TABLE(of, berlin_reset_dt_match);
static struct platform_driver berlin_reset_driver = {
.probe = berlin2_reset_probe,
@ -100,9 +101,4 @@ static struct platform_driver berlin_reset_driver = {
.of_match_table = berlin_reset_dt_match,
},
};
module_platform_driver(berlin_reset_driver);
MODULE_AUTHOR("Antoine Tenart <[email protected]>");
MODULE_AUTHOR("Sebastian Hesselbarth <[email protected]>");
MODULE_DESCRIPTION("Marvell Berlin reset driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(berlin_reset_driver);

View file

@ -13,7 +13,7 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
@ -218,39 +218,17 @@ dis_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(&rc->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,
.name = "lpc18xx-reset",
.of_match_table = lpc18xx_rgu_match,
.suppress_bind_attrs = true,
},
};
module_platform_driver(lpc18xx_rgu_driver);
MODULE_AUTHOR("Joachim Eastwood <[email protected]>");
MODULE_DESCRIPTION("Reset driver for LPC18xx/43xx RGU");
MODULE_LICENSE("GPL v2");
builtin_platform_driver(lpc18xx_rgu_driver);

View file

@ -80,6 +80,7 @@ static const struct reset_control_ops oxnas_reset_ops = {
static const struct of_device_id oxnas_reset_dt_ids[] = {
{ .compatible = "oxsemi,ox810se-reset", },
{ .compatible = "oxsemi,ox820-reset", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, oxnas_reset_dt_ids);

View file

@ -1,4 +1,6 @@
/*
* Socfpga Reset Controller Driver
*
* Copyright 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
*
* based on
@ -16,7 +18,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
@ -148,8 +150,4 @@ static struct platform_driver socfpga_reset_driver = {
.of_match_table = socfpga_reset_dt_ids,
},
};
module_platform_driver(socfpga_reset_driver);
MODULE_AUTHOR("Steffen Trumtrar <[email protected]");
MODULE_DESCRIPTION("Socfpga Reset Controller Driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(socfpga_reset_driver);

View file

@ -13,7 +13,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
@ -142,7 +142,6 @@ static const struct of_device_id sunxi_reset_dt_ids[] = {
{ .compatible = "allwinner,sun6i-a31-clock-reset", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, sunxi_reset_dt_ids);
static int sunxi_reset_probe(struct platform_device *pdev)
{
@ -175,8 +174,4 @@ static struct platform_driver sunxi_reset_driver = {
.of_match_table = sunxi_reset_dt_ids,
},
};
module_platform_driver(sunxi_reset_driver);
MODULE_AUTHOR("Maxime Ripard <[email protected]");
MODULE_DESCRIPTION("Allwinner SoCs Reset Controller Driver");
MODULE_LICENSE("GPL");
builtin_platform_driver(sunxi_reset_driver);

View file

@ -3,6 +3,8 @@
*
* Xilinx Zynq Reset controller driver
*
* Author: Moritz Fischer <moritz.fischer@ettus.com>
*
* 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.
@ -15,7 +17,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@ -137,8 +139,4 @@ static struct platform_driver zynq_reset_driver = {
.of_match_table = zynq_reset_dt_ids,
},
};
module_platform_driver(zynq_reset_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Moritz Fischer <[email protected]>");
MODULE_DESCRIPTION("Zynq Reset Controller Driver");
builtin_platform_driver(zynq_reset_driver);

View file

@ -3,14 +3,6 @@ if ARCH_STI
config STI_RESET_SYSCFG
bool
config STIH415_RESET
bool
select STI_RESET_SYSCFG
config STIH416_RESET
bool
select STI_RESET_SYSCFG
config STIH407_RESET
bool
select STI_RESET_SYSCFG

View file

@ -1,5 +1,3 @@
obj-$(CONFIG_STI_RESET_SYSCFG) += reset-syscfg.o
obj-$(CONFIG_STIH415_RESET) += reset-stih415.o
obj-$(CONFIG_STIH416_RESET) += reset-stih416.o
obj-$(CONFIG_STIH407_RESET) += reset-stih407.o

View file

@ -1,112 +0,0 @@
/*
* Copyright (C) 2013 STMicroelectronics (R&D) Limited
* Author: Stephen Gallimore <stephen.gallimore@st.com>
* Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
*
* 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.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <dt-bindings/reset/stih415-resets.h>
#include "reset-syscfg.h"
/*
* STiH415 Peripheral powerdown definitions.
*/
static const char stih415_front[] = "st,stih415-front-syscfg";
static const char stih415_rear[] = "st,stih415-rear-syscfg";
static const char stih415_sbc[] = "st,stih415-sbc-syscfg";
static const char stih415_lpm[] = "st,stih415-lpm-syscfg";
#define STIH415_PDN_FRONT(_bit) \
_SYSCFG_RST_CH(stih415_front, SYSCFG_114, _bit, SYSSTAT_187, _bit)
#define STIH415_PDN_REAR(_cntl, _stat) \
_SYSCFG_RST_CH(stih415_rear, SYSCFG_336, _cntl, SYSSTAT_384, _stat)
#define STIH415_SRST_REAR(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih415_rear, _reg, _bit)
#define STIH415_SRST_SBC(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih415_sbc, _reg, _bit)
#define STIH415_SRST_FRONT(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih415_front, _reg, _bit)
#define STIH415_SRST_LPM(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih415_lpm, _reg, _bit)
#define SYSCFG_114 0x38 /* Powerdown request EMI/NAND/Keyscan */
#define SYSSTAT_187 0x15c /* Powerdown status EMI/NAND/Keyscan */
#define SYSCFG_336 0x90 /* Powerdown request USB/SATA/PCIe */
#define SYSSTAT_384 0x150 /* Powerdown status USB/SATA/PCIe */
#define SYSCFG_376 0x130 /* Reset generator 0 control 0 */
#define SYSCFG_166 0x108 /* Softreset Ethernet 0 */
#define SYSCFG_31 0x7c /* Softreset Ethernet 1 */
#define LPM_SYSCFG_1 0x4 /* Softreset IRB */
static const struct syscfg_reset_channel_data stih415_powerdowns[] = {
[STIH415_EMISS_POWERDOWN] = STIH415_PDN_FRONT(0),
[STIH415_NAND_POWERDOWN] = STIH415_PDN_FRONT(1),
[STIH415_KEYSCAN_POWERDOWN] = STIH415_PDN_FRONT(2),
[STIH415_USB0_POWERDOWN] = STIH415_PDN_REAR(0, 0),
[STIH415_USB1_POWERDOWN] = STIH415_PDN_REAR(1, 1),
[STIH415_USB2_POWERDOWN] = STIH415_PDN_REAR(2, 2),
[STIH415_SATA0_POWERDOWN] = STIH415_PDN_REAR(3, 3),
[STIH415_SATA1_POWERDOWN] = STIH415_PDN_REAR(4, 4),
[STIH415_PCIE_POWERDOWN] = STIH415_PDN_REAR(5, 8),
};
static const struct syscfg_reset_channel_data stih415_softresets[] = {
[STIH415_ETH0_SOFTRESET] = STIH415_SRST_FRONT(SYSCFG_166, 0),
[STIH415_ETH1_SOFTRESET] = STIH415_SRST_SBC(SYSCFG_31, 0),
[STIH415_IRB_SOFTRESET] = STIH415_SRST_LPM(LPM_SYSCFG_1, 6),
[STIH415_USB0_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 9),
[STIH415_USB1_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 10),
[STIH415_USB2_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 11),
[STIH415_KEYSCAN_SOFTRESET] = STIH415_SRST_LPM(LPM_SYSCFG_1, 8),
};
static struct syscfg_reset_controller_data stih415_powerdown_controller = {
.wait_for_ack = true,
.nr_channels = ARRAY_SIZE(stih415_powerdowns),
.channels = stih415_powerdowns,
};
static struct syscfg_reset_controller_data stih415_softreset_controller = {
.wait_for_ack = false,
.active_low = true,
.nr_channels = ARRAY_SIZE(stih415_softresets),
.channels = stih415_softresets,
};
static const struct of_device_id stih415_reset_match[] = {
{ .compatible = "st,stih415-powerdown",
.data = &stih415_powerdown_controller, },
{ .compatible = "st,stih415-softreset",
.data = &stih415_softreset_controller, },
{},
};
static struct platform_driver stih415_reset_driver = {
.probe = syscfg_reset_probe,
.driver = {
.name = "reset-stih415",
.of_match_table = stih415_reset_match,
},
};
static int __init stih415_reset_init(void)
{
return platform_driver_register(&stih415_reset_driver);
}
arch_initcall(stih415_reset_init);

View file

@ -1,143 +0,0 @@
/*
* Copyright (C) 2013 STMicroelectronics (R&D) Limited
* Author: Stephen Gallimore <stephen.gallimore@st.com>
* Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
*
* 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.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <dt-bindings/reset/stih416-resets.h>
#include "reset-syscfg.h"
/*
* STiH416 Peripheral powerdown definitions.
*/
static const char stih416_front[] = "st,stih416-front-syscfg";
static const char stih416_rear[] = "st,stih416-rear-syscfg";
static const char stih416_sbc[] = "st,stih416-sbc-syscfg";
static const char stih416_lpm[] = "st,stih416-lpm-syscfg";
static const char stih416_cpu[] = "st,stih416-cpu-syscfg";
#define STIH416_PDN_FRONT(_bit) \
_SYSCFG_RST_CH(stih416_front, SYSCFG_1500, _bit, SYSSTAT_1578, _bit)
#define STIH416_PDN_REAR(_cntl, _stat) \
_SYSCFG_RST_CH(stih416_rear, SYSCFG_2525, _cntl, SYSSTAT_2583, _stat)
#define SYSCFG_1500 0x7d0 /* Powerdown request EMI/NAND/Keyscan */
#define SYSSTAT_1578 0x908 /* Powerdown status EMI/NAND/Keyscan */
#define SYSCFG_2525 0x834 /* Powerdown request USB/SATA/PCIe */
#define SYSSTAT_2583 0x91c /* Powerdown status USB/SATA/PCIe */
#define SYSCFG_2552 0x8A0 /* Reset Generator control 0 */
#define SYSCFG_1539 0x86c /* Softreset Ethernet 0 */
#define SYSCFG_510 0x7f8 /* Softreset Ethernet 1 */
#define LPM_SYSCFG_1 0x4 /* Softreset IRB */
#define SYSCFG_2553 0x8a4 /* Softreset SATA0/1, PCIE0/1 */
#define SYSCFG_7563 0x8cc /* MPE softresets 0 */
#define SYSCFG_7564 0x8d0 /* MPE softresets 1 */
#define STIH416_SRST_CPU(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih416_cpu, _reg, _bit)
#define STIH416_SRST_FRONT(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih416_front, _reg, _bit)
#define STIH416_SRST_REAR(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih416_rear, _reg, _bit)
#define STIH416_SRST_LPM(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih416_lpm, _reg, _bit)
#define STIH416_SRST_SBC(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih416_sbc, _reg, _bit)
static const struct syscfg_reset_channel_data stih416_powerdowns[] = {
[STIH416_EMISS_POWERDOWN] = STIH416_PDN_FRONT(0),
[STIH416_NAND_POWERDOWN] = STIH416_PDN_FRONT(1),
[STIH416_KEYSCAN_POWERDOWN] = STIH416_PDN_FRONT(2),
[STIH416_USB0_POWERDOWN] = STIH416_PDN_REAR(0, 0),
[STIH416_USB1_POWERDOWN] = STIH416_PDN_REAR(1, 1),
[STIH416_USB2_POWERDOWN] = STIH416_PDN_REAR(2, 2),
[STIH416_USB3_POWERDOWN] = STIH416_PDN_REAR(6, 5),
[STIH416_SATA0_POWERDOWN] = STIH416_PDN_REAR(3, 3),
[STIH416_SATA1_POWERDOWN] = STIH416_PDN_REAR(4, 4),
[STIH416_PCIE0_POWERDOWN] = STIH416_PDN_REAR(7, 9),
[STIH416_PCIE1_POWERDOWN] = STIH416_PDN_REAR(5, 8),
};
static const struct syscfg_reset_channel_data stih416_softresets[] = {
[STIH416_ETH0_SOFTRESET] = STIH416_SRST_FRONT(SYSCFG_1539, 0),
[STIH416_ETH1_SOFTRESET] = STIH416_SRST_SBC(SYSCFG_510, 0),
[STIH416_IRB_SOFTRESET] = STIH416_SRST_LPM(LPM_SYSCFG_1, 6),
[STIH416_USB0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 9),
[STIH416_USB1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 10),
[STIH416_USB2_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 11),
[STIH416_USB3_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 28),
[STIH416_SATA0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 7),
[STIH416_SATA1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 3),
[STIH416_PCIE0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 15),
[STIH416_PCIE1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 2),
[STIH416_AUD_DAC_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 14),
[STIH416_HDTVOUT_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 5),
[STIH416_VTAC_M_RX_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 25),
[STIH416_VTAC_A_RX_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 26),
[STIH416_SYNC_HD_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 5),
[STIH416_SYNC_SD_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 6),
[STIH416_BLITTER_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 10),
[STIH416_GPU_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 11),
[STIH416_VTAC_M_TX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 18),
[STIH416_VTAC_A_TX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 19),
[STIH416_VTG_AUX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 21),
[STIH416_JPEG_DEC_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 23),
[STIH416_HVA_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 2),
[STIH416_COMPO_M_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 3),
[STIH416_COMPO_A_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 4),
[STIH416_VP8_DEC_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 10),
[STIH416_VTG_MAIN_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 16),
[STIH416_KEYSCAN_SOFTRESET] = STIH416_SRST_LPM(LPM_SYSCFG_1, 8),
};
static struct syscfg_reset_controller_data stih416_powerdown_controller = {
.wait_for_ack = true,
.nr_channels = ARRAY_SIZE(stih416_powerdowns),
.channels = stih416_powerdowns,
};
static struct syscfg_reset_controller_data stih416_softreset_controller = {
.wait_for_ack = false,
.active_low = true,
.nr_channels = ARRAY_SIZE(stih416_softresets),
.channels = stih416_softresets,
};
static const struct of_device_id stih416_reset_match[] = {
{ .compatible = "st,stih416-powerdown",
.data = &stih416_powerdown_controller, },
{ .compatible = "st,stih416-softreset",
.data = &stih416_softreset_controller, },
{},
};
static struct platform_driver stih416_reset_driver = {
.probe = syscfg_reset_probe,
.driver = {
.name = "reset-stih416",
.of_match_table = stih416_reset_match,
},
};
static int __init stih416_reset_init(void)
{
return platform_driver_register(&stih416_reset_driver);
}
arch_initcall(stih416_reset_init);

View file

@ -0,0 +1,2 @@
config RESET_TEGRA_BPMP
def_bool TEGRA_BPMP

View file

@ -0,0 +1 @@
obj-$(CONFIG_RESET_TEGRA_BPMP) += reset-bpmp.o

View file

@ -0,0 +1,71 @@
/*
* Copyright (C) 2016 NVIDIA Corporation
*
* 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/reset-controller.h>
#include <soc/tegra/bpmp.h>
#include <soc/tegra/bpmp-abi.h>
static struct tegra_bpmp *to_tegra_bpmp(struct reset_controller_dev *rstc)
{
return container_of(rstc, struct tegra_bpmp, rstc);
}
static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
enum mrq_reset_commands command,
unsigned int id)
{
struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc);
struct mrq_reset_request request;
struct tegra_bpmp_message msg;
memset(&request, 0, sizeof(request));
request.cmd = command;
request.reset_id = id;
memset(&msg, 0, sizeof(msg));
msg.mrq = MRQ_RESET;
msg.tx.data = &request;
msg.tx.size = sizeof(request);
return tegra_bpmp_transfer(bpmp, &msg);
}
static int tegra_bpmp_reset_module(struct reset_controller_dev *rstc,
unsigned long id)
{
return tegra_bpmp_reset_common(rstc, CMD_RESET_MODULE, id);
}
static int tegra_bpmp_reset_assert(struct reset_controller_dev *rstc,
unsigned long id)
{
return tegra_bpmp_reset_common(rstc, CMD_RESET_ASSERT, id);
}
static int tegra_bpmp_reset_deassert(struct reset_controller_dev *rstc,
unsigned long id)
{
return tegra_bpmp_reset_common(rstc, CMD_RESET_DEASSERT, id);
}
static const struct reset_control_ops tegra_bpmp_reset_ops = {
.reset = tegra_bpmp_reset_module,
.assert = tegra_bpmp_reset_assert,
.deassert = tegra_bpmp_reset_deassert,
};
int tegra_bpmp_init_resets(struct tegra_bpmp *bpmp)
{
bpmp->rstc.ops = &tegra_bpmp_reset_ops;
bpmp->rstc.owner = THIS_MODULE;
bpmp->rstc.of_node = bpmp->dev->of_node;
bpmp->rstc.nr_resets = bpmp->soc->num_resets;
return devm_reset_controller_register(bpmp->dev, &bpmp->rstc);
}