Commit 7eccfebf authored by Arnd Bergmann's avatar Arnd Bergmann

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

Merge "Reset controller changes for v4.5" from Philipp Zabel:

- oftree support for getting reset devices by index
- fixed return value consistency of of_reset_control_get
- added support for STi co-processor resets
- added STi status callback
- various fixes

* tag 'reset-for-4.5' of git://git.pengutronix.de/git/pza/linux:
  reset: check return value of reset_controller_register()
  reset: remove redundant $(CONFIG_RESET_CONTROLLER) from Makefile
  reset: use ENOTSUPP instead of ENOSYS
  reset: sunxi: mark the of_device_id array as __initconst
  reset: sti: add a missing blank line after declaration
  reset: sti: Provide ops .status() call-back
  reset: sti: Add support for resetting co-processors
  ARM: STi: Add DT defines for co-processor reset lines
  reset: Fix of_reset_control_get() for consistent return values
  reset: add of_reset_control_get_by_index()
parents 31ade3b8 d1f15aa0
obj-$(CONFIG_RESET_CONTROLLER) += core.o obj-y += core.o
obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.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
......
...@@ -95,7 +95,7 @@ int reset_control_reset(struct reset_control *rstc) ...@@ -95,7 +95,7 @@ int reset_control_reset(struct reset_control *rstc)
if (rstc->rcdev->ops->reset) if (rstc->rcdev->ops->reset)
return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id);
return -ENOSYS; return -ENOTSUPP;
} }
EXPORT_SYMBOL_GPL(reset_control_reset); EXPORT_SYMBOL_GPL(reset_control_reset);
...@@ -108,7 +108,7 @@ int reset_control_assert(struct reset_control *rstc) ...@@ -108,7 +108,7 @@ int reset_control_assert(struct reset_control *rstc)
if (rstc->rcdev->ops->assert) if (rstc->rcdev->ops->assert)
return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id);
return -ENOSYS; return -ENOTSUPP;
} }
EXPORT_SYMBOL_GPL(reset_control_assert); EXPORT_SYMBOL_GPL(reset_control_assert);
...@@ -121,7 +121,7 @@ int reset_control_deassert(struct reset_control *rstc) ...@@ -121,7 +121,7 @@ int reset_control_deassert(struct reset_control *rstc)
if (rstc->rcdev->ops->deassert) if (rstc->rcdev->ops->deassert)
return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id);
return -ENOSYS; return -ENOTSUPP;
} }
EXPORT_SYMBOL_GPL(reset_control_deassert); EXPORT_SYMBOL_GPL(reset_control_deassert);
...@@ -136,32 +136,29 @@ int reset_control_status(struct reset_control *rstc) ...@@ -136,32 +136,29 @@ int reset_control_status(struct reset_control *rstc)
if (rstc->rcdev->ops->status) if (rstc->rcdev->ops->status)
return rstc->rcdev->ops->status(rstc->rcdev, rstc->id); return rstc->rcdev->ops->status(rstc->rcdev, rstc->id);
return -ENOSYS; return -ENOTSUPP;
} }
EXPORT_SYMBOL_GPL(reset_control_status); EXPORT_SYMBOL_GPL(reset_control_status);
/** /**
* of_reset_control_get - Lookup and obtain a reference to a reset controller. * of_reset_control_get_by_index - Lookup and obtain a reference to a reset
* controller by index.
* @node: device to be reset by the controller * @node: device to be reset by the controller
* @id: reset line name * @index: index of the reset controller
*
* Returns a struct reset_control or IS_ERR() condition containing errno.
* *
* Use of id names is optional. * This is to be used to perform a list of resets for a device or power domain
* in whatever order. Returns a struct reset_control or IS_ERR() condition
* containing errno.
*/ */
struct reset_control *of_reset_control_get(struct device_node *node, struct reset_control *of_reset_control_get_by_index(struct device_node *node,
const char *id) int index)
{ {
struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER);
struct reset_controller_dev *r, *rcdev; struct reset_controller_dev *r, *rcdev;
struct of_phandle_args args; struct of_phandle_args args;
int index = 0;
int rstc_id; int rstc_id;
int ret; int ret;
if (id)
index = of_property_match_string(node,
"reset-names", id);
ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
index, &args); index, &args);
if (ret) if (ret)
...@@ -202,6 +199,30 @@ struct reset_control *of_reset_control_get(struct device_node *node, ...@@ -202,6 +199,30 @@ struct reset_control *of_reset_control_get(struct device_node *node,
return rstc; return rstc;
} }
EXPORT_SYMBOL_GPL(of_reset_control_get_by_index);
/**
* of_reset_control_get - Lookup and obtain a reference to a reset controller.
* @node: device to be reset by the controller
* @id: reset line name
*
* Returns a struct reset_control or IS_ERR() condition containing errno.
*
* Use of id names is optional.
*/
struct reset_control *of_reset_control_get(struct device_node *node,
const char *id)
{
int index = 0;
if (id) {
index = of_property_match_string(node,
"reset-names", id);
if (index < 0)
return ERR_PTR(-ENOENT);
}
return of_reset_control_get_by_index(node, index);
}
EXPORT_SYMBOL_GPL(of_reset_control_get); EXPORT_SYMBOL_GPL(of_reset_control_get);
/** /**
......
...@@ -87,9 +87,7 @@ static int berlin2_reset_probe(struct platform_device *pdev) ...@@ -87,9 +87,7 @@ static int berlin2_reset_probe(struct platform_device *pdev)
priv->rcdev.of_reset_n_cells = 2; priv->rcdev.of_reset_n_cells = 2;
priv->rcdev.of_xlate = berlin_reset_xlate; priv->rcdev.of_xlate = berlin_reset_xlate;
reset_controller_register(&priv->rcdev); return reset_controller_register(&priv->rcdev);
return 0;
} }
static const struct of_device_id berlin_reset_dt_match[] = { static const struct of_device_id berlin_reset_dt_match[] = {
......
...@@ -133,9 +133,8 @@ static int socfpga_reset_probe(struct platform_device *pdev) ...@@ -133,9 +133,8 @@ static int socfpga_reset_probe(struct platform_device *pdev)
data->rcdev.nr_resets = NR_BANKS * BITS_PER_LONG; data->rcdev.nr_resets = NR_BANKS * BITS_PER_LONG;
data->rcdev.ops = &socfpga_reset_ops; data->rcdev.ops = &socfpga_reset_ops;
data->rcdev.of_node = pdev->dev.of_node; data->rcdev.of_node = pdev->dev.of_node;
reset_controller_register(&data->rcdev);
return 0; return reset_controller_register(&data->rcdev);
} }
static int socfpga_reset_remove(struct platform_device *pdev) static int socfpga_reset_remove(struct platform_device *pdev)
......
...@@ -108,9 +108,8 @@ static int sunxi_reset_init(struct device_node *np) ...@@ -108,9 +108,8 @@ static int sunxi_reset_init(struct device_node *np)
data->rcdev.nr_resets = size * 32; data->rcdev.nr_resets = size * 32;
data->rcdev.ops = &sunxi_reset_ops; data->rcdev.ops = &sunxi_reset_ops;
data->rcdev.of_node = np; data->rcdev.of_node = np;
reset_controller_register(&data->rcdev);
return 0; return reset_controller_register(&data->rcdev);
err_alloc: err_alloc:
kfree(data); kfree(data);
...@@ -122,7 +121,7 @@ static int sunxi_reset_init(struct device_node *np) ...@@ -122,7 +121,7 @@ static int sunxi_reset_init(struct device_node *np)
* our system, before we can even think of using a regular device * our system, before we can even think of using a regular device
* driver for it. * driver for it.
*/ */
static const struct of_device_id sunxi_early_reset_dt_ids[] __initdata = { static const struct of_device_id sunxi_early_reset_dt_ids[] __initconst = {
{ .compatible = "allwinner,sun6i-a31-ahb1-reset", }, { .compatible = "allwinner,sun6i-a31-ahb1-reset", },
{ /* sentinel */ }, { /* sentinel */ },
}; };
......
...@@ -121,9 +121,8 @@ static int zynq_reset_probe(struct platform_device *pdev) ...@@ -121,9 +121,8 @@ static int zynq_reset_probe(struct platform_device *pdev)
priv->rcdev.nr_resets = resource_size(res) / 4 * BITS_PER_LONG; priv->rcdev.nr_resets = resource_size(res) / 4 * BITS_PER_LONG;
priv->rcdev.ops = &zynq_reset_ops; priv->rcdev.ops = &zynq_reset_ops;
priv->rcdev.of_node = pdev->dev.of_node; priv->rcdev.of_node = pdev->dev.of_node;
reset_controller_register(&priv->rcdev);
return 0; return reset_controller_register(&priv->rcdev);
} }
static int zynq_reset_remove(struct platform_device *pdev) static int zynq_reset_remove(struct platform_device *pdev)
......
...@@ -52,6 +52,7 @@ static const struct syscfg_reset_channel_data stih407_powerdowns[] = { ...@@ -52,6 +52,7 @@ static const struct syscfg_reset_channel_data stih407_powerdowns[] = {
}; };
/* Reset Generator control 0/1 */ /* Reset Generator control 0/1 */
#define SYSCFG_5128 0x200
#define SYSCFG_5131 0x20c #define SYSCFG_5131 0x20c
#define SYSCFG_5132 0x210 #define SYSCFG_5132 0x210
...@@ -96,6 +97,10 @@ static const struct syscfg_reset_channel_data stih407_softresets[] = { ...@@ -96,6 +97,10 @@ static const struct syscfg_reset_channel_data stih407_softresets[] = {
[STIH407_ERAM_HVA_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 1), [STIH407_ERAM_HVA_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 1),
[STIH407_LPM_SOFTRESET] = STIH407_SRST_SBC(SYSCFG_4002, 2), [STIH407_LPM_SOFTRESET] = STIH407_SRST_SBC(SYSCFG_4002, 2),
[STIH407_KEYSCAN_SOFTRESET] = STIH407_SRST_LPM(LPM_SYSCFG_1, 8), [STIH407_KEYSCAN_SOFTRESET] = STIH407_SRST_LPM(LPM_SYSCFG_1, 8),
[STIH407_ST231_AUD_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 26),
[STIH407_ST231_DMU_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 27),
[STIH407_ST231_GP0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 28),
[STIH407_ST231_GP1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5128, 2),
}; };
/* PicoPHY reset/control */ /* PicoPHY reset/control */
......
...@@ -103,17 +103,42 @@ static int syscfg_reset_deassert(struct reset_controller_dev *rcdev, ...@@ -103,17 +103,42 @@ static int syscfg_reset_deassert(struct reset_controller_dev *rcdev,
static int syscfg_reset_dev(struct reset_controller_dev *rcdev, static int syscfg_reset_dev(struct reset_controller_dev *rcdev,
unsigned long idx) unsigned long idx)
{ {
int err = syscfg_reset_assert(rcdev, idx); int err;
err = syscfg_reset_assert(rcdev, idx);
if (err) if (err)
return err; return err;
return syscfg_reset_deassert(rcdev, idx); return syscfg_reset_deassert(rcdev, idx);
} }
static int syscfg_reset_status(struct reset_controller_dev *rcdev,
unsigned long idx)
{
struct syscfg_reset_controller *rst = to_syscfg_reset_controller(rcdev);
const struct syscfg_reset_channel *ch;
u32 ret_val = 0;
int err;
if (idx >= rcdev->nr_resets)
return -EINVAL;
ch = &rst->channels[idx];
if (ch->ack)
err = regmap_field_read(ch->ack, &ret_val);
else
err = regmap_field_read(ch->reset, &ret_val);
if (err)
return err;
return rst->active_low ? !ret_val : !!ret_val;
}
static struct reset_control_ops syscfg_reset_ops = { static struct reset_control_ops syscfg_reset_ops = {
.reset = syscfg_reset_dev, .reset = syscfg_reset_dev,
.assert = syscfg_reset_assert, .assert = syscfg_reset_assert,
.deassert = syscfg_reset_deassert, .deassert = syscfg_reset_deassert,
.status = syscfg_reset_status,
}; };
static int syscfg_reset_controller_register(struct device *dev, static int syscfg_reset_controller_register(struct device *dev,
......
...@@ -52,6 +52,10 @@ ...@@ -52,6 +52,10 @@
#define STIH407_KEYSCAN_SOFTRESET 26 #define STIH407_KEYSCAN_SOFTRESET 26
#define STIH407_USB2_PORT0_SOFTRESET 27 #define STIH407_USB2_PORT0_SOFTRESET 27
#define STIH407_USB2_PORT1_SOFTRESET 28 #define STIH407_USB2_PORT1_SOFTRESET 28
#define STIH407_ST231_AUD_SOFTRESET 29
#define STIH407_ST231_DMU_SOFTRESET 30
#define STIH407_ST231_GP0_SOFTRESET 31
#define STIH407_ST231_GP1_SOFTRESET 32
/* Picophy reset defines */ /* Picophy reset defines */
#define STIH407_PICOPHY0_RESET 0 #define STIH407_PICOPHY0_RESET 0
......
...@@ -38,6 +38,9 @@ static inline struct reset_control *devm_reset_control_get_optional( ...@@ -38,6 +38,9 @@ static inline struct reset_control *devm_reset_control_get_optional(
struct reset_control *of_reset_control_get(struct device_node *node, struct reset_control *of_reset_control_get(struct device_node *node,
const char *id); const char *id);
struct reset_control *of_reset_control_get_by_index(
struct device_node *node, int index);
#else #else
static inline int reset_control_reset(struct reset_control *rstc) static inline int reset_control_reset(struct reset_control *rstc)
...@@ -71,7 +74,7 @@ static inline void reset_control_put(struct reset_control *rstc) ...@@ -71,7 +74,7 @@ static inline void reset_control_put(struct reset_control *rstc)
static inline int device_reset_optional(struct device *dev) static inline int device_reset_optional(struct device *dev)
{ {
return -ENOSYS; return -ENOTSUPP;
} }
static inline struct reset_control *__must_check reset_control_get( static inline struct reset_control *__must_check reset_control_get(
...@@ -91,19 +94,25 @@ static inline struct reset_control *__must_check devm_reset_control_get( ...@@ -91,19 +94,25 @@ static inline struct reset_control *__must_check devm_reset_control_get(
static inline struct reset_control *reset_control_get_optional( static inline struct reset_control *reset_control_get_optional(
struct device *dev, const char *id) struct device *dev, const char *id)
{ {
return ERR_PTR(-ENOSYS); return ERR_PTR(-ENOTSUPP);
} }
static inline struct reset_control *devm_reset_control_get_optional( static inline struct reset_control *devm_reset_control_get_optional(
struct device *dev, const char *id) struct device *dev, const char *id)
{ {
return ERR_PTR(-ENOSYS); return ERR_PTR(-ENOTSUPP);
} }
static inline struct reset_control *of_reset_control_get( static inline struct reset_control *of_reset_control_get(
struct device_node *node, const char *id) struct device_node *node, const char *id)
{ {
return ERR_PTR(-ENOSYS); return ERR_PTR(-ENOTSUPP);
}
static inline struct reset_control *of_reset_control_get_by_index(
struct device_node *node, int index)
{
return ERR_PTR(-ENOTSUPP);
} }
#endif /* CONFIG_RESET_CONTROLLER */ #endif /* CONFIG_RESET_CONTROLLER */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment