Reset controller changes for v3.19

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJUctX9AAoJEFDCiBxwnmDrYzQQANVqyYFY/VRMvS5pPuPuA51L
 K5NQRZ7AFpZCCyfYffiC8DfFHB4WibfXUUwT8ElJVFgRnzs7u3OmMX7rKbFR0QfY
 rtt1nhrG77SP+/rriE9uc+mHOBO0+pauEsRROqOJleqEWwO4jXUz/g6x/34IRcuC
 CFrLqz/bhmn7w9eTz27UnVwJSJMNvAVpnBIScSMClZFWtmNIF8pMgqjDqOc8XF2U
 2k7vMU0Af2BGkyKdrvqKcSOUoF16iC18rbuj6EBOHR87Ymd2s4gqZ5jcDv3kww7K
 /TVV9gIeS5zFXpK8obSMkvVsRhfZmJzbdRyj2tZQD8vh1KRA+Efiq5Jsq9m+iztN
 kyCpwnt3FX7KHgXlj/8m2aDOTd4HjT4x4661CMTHSbYDvRVxWkJS7eLcCKwt/F9Z
 o6lYw0AOiCC8tP21wK5xjxuYlbmnWKQIkIHE8JPZkRSw9bcGB4UgMsy0/4iHbUoW
 T9YtvAE2qSJOrER1xHRnl1dfFMhIHVX4XaOCbb3EnOSlSxQMmyzJJZUHwSUwdr1I
 IXxW+3Wc41Rqklv8PQbI0Gv6/hR+Tb8BMB8r0dq4qeCfdobFTEvtGuLa0KSeFXgy
 439aM2zSUIXAYOOEyG7GsUkgaMj1enQsj/azB6aJl5C6yWBdFcF5ZcTM0uTbwuKt
 Xcs/9Nu7BNTDo3UcPhBx
 =FuM7
 -----END PGP SIGNATURE-----

Merge tag 'reset-for-3.19-2' of git://git.pengutronix.de/git/pza/linux into next/drivers

Pull "Reset controller changes for v3.19" from Philipp Zabel:

This adds a new driver for the sti soc family, and creates
a reset_control_status interface, which is added to the existing
drivers.

* tag 'reset-for-3.19-2' of git://git.pengutronix.de/git/pza/linux:
  reset: add socfpga_reset_status
  reset: sti: Document sti-picophyreset controllers bindings.
  reset: stih407: Add softreset, powerdown and picophy controllers
  reset: stih407: Add reset controllers DT bindings
  reset: add reset_control_status helper function

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2014-12-04 16:57:36 +01:00
commit a8afa2645c
9 changed files with 305 additions and 0 deletions

View File

@ -0,0 +1,42 @@
STMicroelectronics STi family Sysconfig Picophy SoftReset Controller
=============================================================================
This binding describes a reset controller device that is used to enable and
disable on-chip PicoPHY USB2 phy(s) using "softreset" control bits found in
the STi family SoC system configuration registers.
The actual action taken when softreset is asserted is hardware dependent.
However, when asserted it may not be possible to access the hardware's
registers and after an assert/deassert sequence the hardware's previous state
may no longer be valid.
Please refer to Documentation/devicetree/bindings/reset/reset.txt
for common reset controller binding usage.
Required properties:
- compatible: Should be "st,stih407-picophyreset"
- #reset-cells: 1, see below
Example:
picophyreset: picophyreset-controller {
compatible = "st,stih407-picophyreset";
#reset-cells = <1>;
};
Specifying picophyreset control of devices
=======================================
Device nodes should specify the reset channel required in their "resets"
property, containing a phandle to the picophyreset device node and an
index specifying which channel to use, as described in
Documentation/devicetree/bindings/reset/reset.txt.
Example:
usb2_picophy0: usbpicophy@0 {
resets = <&picophyreset STIH407_PICOPHY0_RESET>;
};
Macro definitions for the supported reset channels can be found in:
include/dt-bindings/reset-controller/stih407-resets.h

View File

@ -125,6 +125,21 @@ int reset_control_deassert(struct reset_control *rstc)
} }
EXPORT_SYMBOL_GPL(reset_control_deassert); EXPORT_SYMBOL_GPL(reset_control_deassert);
/**
* reset_control_status - returns a negative errno if not supported, a
* positive value if the reset line is asserted, or zero if the reset
* line is not asserted.
* @rstc: reset controller
*/
int reset_control_status(struct reset_control *rstc)
{
if (rstc->rcdev->ops->status)
return rstc->rcdev->ops->status(rstc->rcdev, rstc->id);
return -ENOSYS;
}
EXPORT_SYMBOL_GPL(reset_control_status);
/** /**
* of_reset_control_get - Lookup and obtain a reference to a reset controller. * of_reset_control_get - Lookup and obtain a reference to a reset controller.
* @node: device to be reset by the controller * @node: device to be reset by the controller

View File

@ -76,9 +76,24 @@ static int socfpga_reset_deassert(struct reset_controller_dev *rcdev,
return 0; return 0;
} }
static int socfpga_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct socfpga_reset_data *data = container_of(rcdev,
struct socfpga_reset_data, rcdev);
int bank = id / BITS_PER_LONG;
int offset = id % BITS_PER_LONG;
u32 reg;
reg = readl(data->membase + OFFSET_MODRST + (bank * NR_BANKS));
return !(reg & BIT(offset));
}
static struct reset_control_ops socfpga_reset_ops = { static struct reset_control_ops socfpga_reset_ops = {
.assert = socfpga_reset_assert, .assert = socfpga_reset_assert,
.deassert = socfpga_reset_deassert, .deassert = socfpga_reset_deassert,
.status = socfpga_reset_status,
}; };
static int socfpga_reset_probe(struct platform_device *pdev) static int socfpga_reset_probe(struct platform_device *pdev)

View File

@ -12,4 +12,8 @@ config STIH416_RESET
bool bool
select STI_RESET_SYSCFG select STI_RESET_SYSCFG
config STIH407_RESET
bool
select STI_RESET_SYSCFG
endif endif

View File

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

View File

@ -0,0 +1,158 @@
/*
* Copyright (C) 2014 STMicroelectronics (R&D) Limited
* Author: Giuseppe Cavallaro <peppe.cavallaro@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-controller/stih407-resets.h>
#include "reset-syscfg.h"
/* STiH407 Peripheral powerdown definitions. */
static const char stih407_core[] = "st,stih407-core-syscfg";
static const char stih407_sbc_reg[] = "st,stih407-sbc-reg-syscfg";
static const char stih407_lpm[] = "st,stih407-lpm-syscfg";
#define STIH407_PDN_0(_bit) \
_SYSCFG_RST_CH(stih407_core, SYSCFG_5000, _bit, SYSSTAT_5500, _bit)
#define STIH407_PDN_1(_bit) \
_SYSCFG_RST_CH(stih407_core, SYSCFG_5001, _bit, SYSSTAT_5501, _bit)
#define STIH407_PDN_ETH(_bit, _stat) \
_SYSCFG_RST_CH(stih407_sbc_reg, SYSCFG_4032, _bit, SYSSTAT_4520, _stat)
/* Powerdown requests control 0 */
#define SYSCFG_5000 0x0
#define SYSSTAT_5500 0x7d0
/* Powerdown requests control 1 (High Speed Links) */
#define SYSCFG_5001 0x4
#define SYSSTAT_5501 0x7d4
/* Ethernet powerdown/status/reset */
#define SYSCFG_4032 0x80
#define SYSSTAT_4520 0x820
#define SYSCFG_4002 0x8
static const struct syscfg_reset_channel_data stih407_powerdowns[] = {
[STIH407_EMISS_POWERDOWN] = STIH407_PDN_0(1),
[STIH407_NAND_POWERDOWN] = STIH407_PDN_0(0),
[STIH407_USB3_POWERDOWN] = STIH407_PDN_1(6),
[STIH407_USB2_PORT1_POWERDOWN] = STIH407_PDN_1(5),
[STIH407_USB2_PORT0_POWERDOWN] = STIH407_PDN_1(4),
[STIH407_PCIE1_POWERDOWN] = STIH407_PDN_1(3),
[STIH407_PCIE0_POWERDOWN] = STIH407_PDN_1(2),
[STIH407_SATA1_POWERDOWN] = STIH407_PDN_1(1),
[STIH407_SATA0_POWERDOWN] = STIH407_PDN_1(0),
[STIH407_ETH1_POWERDOWN] = STIH407_PDN_ETH(0, 2),
};
/* Reset Generator control 0/1 */
#define SYSCFG_5131 0x20c
#define SYSCFG_5132 0x210
#define LPM_SYSCFG_1 0x4 /* Softreset IRB & SBC UART */
#define STIH407_SRST_CORE(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih407_core, _reg, _bit)
#define STIH407_SRST_SBC(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih407_sbc_reg, _reg, _bit)
#define STIH407_SRST_LPM(_reg, _bit) \
_SYSCFG_RST_CH_NO_ACK(stih407_lpm, _reg, _bit)
static const struct syscfg_reset_channel_data stih407_softresets[] = {
[STIH407_ETH1_SOFTRESET] = STIH407_SRST_SBC(SYSCFG_4002, 4),
[STIH407_MMC1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 3),
[STIH407_USB2_PORT0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 28),
[STIH407_USB2_PORT1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 29),
[STIH407_PICOPHY_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 30),
[STIH407_IRB_SOFTRESET] = STIH407_SRST_LPM(LPM_SYSCFG_1, 6),
[STIH407_PCIE0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 6),
[STIH407_PCIE1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 15),
[STIH407_SATA0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 7),
[STIH407_SATA1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 16),
[STIH407_MIPHY0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 4),
[STIH407_MIPHY1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 13),
[STIH407_MIPHY2_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 22),
[STIH407_SATA0_PWR_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 5),
[STIH407_SATA1_PWR_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 14),
[STIH407_DELTA_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 3),
[STIH407_BLITTER_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 10),
[STIH407_HDTVOUT_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 11),
[STIH407_HDQVDP_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 12),
[STIH407_VDP_AUX_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 14),
[STIH407_COMPO_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 15),
[STIH407_HDMI_TX_PHY_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 21),
[STIH407_JPEG_DEC_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 23),
[STIH407_VP8_DEC_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 24),
[STIH407_GPU_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 30),
[STIH407_HVA_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 0),
[STIH407_ERAM_HVA_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 1),
[STIH407_LPM_SOFTRESET] = STIH407_SRST_SBC(SYSCFG_4002, 2),
[STIH407_KEYSCAN_SOFTRESET] = STIH407_SRST_LPM(LPM_SYSCFG_1, 8),
};
/* PicoPHY reset/control */
#define SYSCFG_5061 0x0f4
static const struct syscfg_reset_channel_data stih407_picophyresets[] = {
[STIH407_PICOPHY0_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 5),
[STIH407_PICOPHY1_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 6),
[STIH407_PICOPHY2_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 7),
};
static const struct syscfg_reset_controller_data stih407_powerdown_controller = {
.wait_for_ack = true,
.nr_channels = ARRAY_SIZE(stih407_powerdowns),
.channels = stih407_powerdowns,
};
static const struct syscfg_reset_controller_data stih407_softreset_controller = {
.wait_for_ack = false,
.active_low = true,
.nr_channels = ARRAY_SIZE(stih407_softresets),
.channels = stih407_softresets,
};
static const struct syscfg_reset_controller_data stih407_picophyreset_controller = {
.wait_for_ack = false,
.nr_channels = ARRAY_SIZE(stih407_picophyresets),
.channels = stih407_picophyresets,
};
static struct of_device_id stih407_reset_match[] = {
{
.compatible = "st,stih407-powerdown",
.data = &stih407_powerdown_controller,
},
{
.compatible = "st,stih407-softreset",
.data = &stih407_softreset_controller,
},
{
.compatible = "st,stih407-picophyreset",
.data = &stih407_picophyreset_controller,
},
{ /* sentinel */ },
};
static struct platform_driver stih407_reset_driver = {
.probe = syscfg_reset_probe,
.driver = {
.name = "reset-stih407",
.of_match_table = stih407_reset_match,
},
};
static int __init stih407_reset_init(void)
{
return platform_driver_register(&stih407_reset_driver);
}
arch_initcall(stih407_reset_init);

View File

@ -0,0 +1,61 @@
/*
* This header provides constants for the reset controller
* based peripheral powerdown requests on the STMicroelectronics
* STiH407 SoC.
*/
#ifndef _DT_BINDINGS_RESET_CONTROLLER_STIH407
#define _DT_BINDINGS_RESET_CONTROLLER_STIH407
/* Powerdown requests control 0 */
#define STIH407_EMISS_POWERDOWN 0
#define STIH407_NAND_POWERDOWN 1
/* Synp GMAC PowerDown */
#define STIH407_ETH1_POWERDOWN 2
/* Powerdown requests control 1 */
#define STIH407_USB3_POWERDOWN 3
#define STIH407_USB2_PORT1_POWERDOWN 4
#define STIH407_USB2_PORT0_POWERDOWN 5
#define STIH407_PCIE1_POWERDOWN 6
#define STIH407_PCIE0_POWERDOWN 7
#define STIH407_SATA1_POWERDOWN 8
#define STIH407_SATA0_POWERDOWN 9
/* Reset defines */
#define STIH407_ETH1_SOFTRESET 0
#define STIH407_MMC1_SOFTRESET 1
#define STIH407_PICOPHY_SOFTRESET 2
#define STIH407_IRB_SOFTRESET 3
#define STIH407_PCIE0_SOFTRESET 4
#define STIH407_PCIE1_SOFTRESET 5
#define STIH407_SATA0_SOFTRESET 6
#define STIH407_SATA1_SOFTRESET 7
#define STIH407_MIPHY0_SOFTRESET 8
#define STIH407_MIPHY1_SOFTRESET 9
#define STIH407_MIPHY2_SOFTRESET 10
#define STIH407_SATA0_PWR_SOFTRESET 11
#define STIH407_SATA1_PWR_SOFTRESET 12
#define STIH407_DELTA_SOFTRESET 13
#define STIH407_BLITTER_SOFTRESET 14
#define STIH407_HDTVOUT_SOFTRESET 15
#define STIH407_HDQVDP_SOFTRESET 16
#define STIH407_VDP_AUX_SOFTRESET 17
#define STIH407_COMPO_SOFTRESET 18
#define STIH407_HDMI_TX_PHY_SOFTRESET 19
#define STIH407_JPEG_DEC_SOFTRESET 20
#define STIH407_VP8_DEC_SOFTRESET 21
#define STIH407_GPU_SOFTRESET 22
#define STIH407_HVA_SOFTRESET 23
#define STIH407_ERAM_HVA_SOFTRESET 24
#define STIH407_LPM_SOFTRESET 25
#define STIH407_KEYSCAN_SOFTRESET 26
#define STIH407_USB2_PORT0_SOFTRESET 27
#define STIH407_USB2_PORT1_SOFTRESET 28
/* Picophy reset defines */
#define STIH407_PICOPHY0_RESET 0
#define STIH407_PICOPHY1_RESET 1
#define STIH407_PICOPHY2_RESET 2
#endif /* _DT_BINDINGS_RESET_CONTROLLER_STIH407 */

View File

@ -12,11 +12,13 @@ struct reset_controller_dev;
* things to reset the device * things to reset the device
* @assert: manually assert the reset line, if supported * @assert: manually assert the reset line, if supported
* @deassert: manually deassert the reset line, if supported * @deassert: manually deassert the reset line, if supported
* @status: return the status of the reset line, if supported
*/ */
struct reset_control_ops { struct reset_control_ops {
int (*reset)(struct reset_controller_dev *rcdev, unsigned long id); int (*reset)(struct reset_controller_dev *rcdev, unsigned long id);
int (*assert)(struct reset_controller_dev *rcdev, unsigned long id); int (*assert)(struct reset_controller_dev *rcdev, unsigned long id);
int (*deassert)(struct reset_controller_dev *rcdev, unsigned long id); int (*deassert)(struct reset_controller_dev *rcdev, unsigned long id);
int (*status)(struct reset_controller_dev *rcdev, unsigned long id);
}; };
struct module; struct module;

View File

@ -10,6 +10,7 @@ struct reset_control;
int reset_control_reset(struct reset_control *rstc); int reset_control_reset(struct reset_control *rstc);
int reset_control_assert(struct reset_control *rstc); int reset_control_assert(struct reset_control *rstc);
int reset_control_deassert(struct reset_control *rstc); int reset_control_deassert(struct reset_control *rstc);
int reset_control_status(struct reset_control *rstc);
struct reset_control *reset_control_get(struct device *dev, const char *id); struct reset_control *reset_control_get(struct device *dev, const char *id);
void reset_control_put(struct reset_control *rstc); void reset_control_put(struct reset_control *rstc);
@ -57,6 +58,12 @@ static inline int reset_control_deassert(struct reset_control *rstc)
return 0; return 0;
} }
static inline int reset_control_status(struct reset_control *rstc)
{
WARN_ON(1);
return 0;
}
static inline void reset_control_put(struct reset_control *rstc) static inline void reset_control_put(struct reset_control *rstc)
{ {
WARN_ON(1); WARN_ON(1);