[PATCH] mfd: da9053: fix typo in variable name

2019-11-21 Thread Lucas Stach
Fixes: 06928c7d1758 (mfd: da9053: use new reset_source_set_device)
Signed-off-by: Lucas Stach 
---
 drivers/mfd/da9053.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/da9053.c b/drivers/mfd/da9053.c
index 1faba813bee8..4c31beb26701 100644
--- a/drivers/mfd/da9053.c
+++ b/drivers/mfd/da9053.c
@@ -235,7 +235,7 @@ static void da9053_detect_reset_source(struct da9053_priv 
*da9053)
else
return;
 
-   reset_source_set_device(da9053->dev, ltype);
+   reset_source_set_device(da9053->dev, type);
 
ret = da9053_reg_write(da9053, DA9053_FAULTLOG_REG, val);
if (ret < 0)
-- 
2.20.1


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 1/5] usb: dwc3: remove unnecessary warning

2019-11-21 Thread Sascha Hauer
The dwc3 driver warns when the value written to DWC3_GFLADJ happens to
be same as already read from the register. This always happens when the
driver was previously running when started 2nd stage from another
barebox.

Signed-off-by: Sascha Hauer 
---
 drivers/usb/dwc3/core.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c17327c791..ad84708da2 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -348,12 +348,9 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
 
reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
dft = reg & DWC3_GFLADJ_30MHZ_MASK;
-   if (!WARN(dft == dwc->fladj,
-   "request value same as default, ignoring\n")) {
-   reg &= ~DWC3_GFLADJ_30MHZ_MASK;
-   reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
-   dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
-   }
+   reg &= ~DWC3_GFLADJ_30MHZ_MASK;
+   reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
+   dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
 }
 
 static void dwc3_core_num_eps(struct dwc3 *dwc)
-- 
2.24.0


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 3/5] usb: dwc3: register otg device

2019-11-21 Thread Sascha Hauer
When the role in the device tree is specified as "otg" then register
a otg device in barebox so that the user can configure the desired mode.

Signed-off-by: Sascha Hauer 
---
 drivers/usb/dwc3/Kconfig |  1 +
 drivers/usb/dwc3/core.c  | 14 +++---
 drivers/usb/dwc3/core.h  |  1 -
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 09da121374..2eb8e9c85a 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -2,6 +2,7 @@ config USB_DWC3
tristate "DesignWare USB3 DRD Core Support"
depends on USB && HAS_DMA
select USB_XHCI
+   select USB_OTGDEV
help
  Say Y or M here if your system has a Dual Role SuperSpeed
  USB controller based on the DesignWare USB3 IP Core.
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ad84708da2..04b700d12d 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -936,12 +936,13 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
return 0;
 }
 
-static int dwc3_core_init_mode(struct dwc3 *dwc)
+static int dwc3_set_mode(void *ctx, enum usb_dr_mode mode)
 {
+   struct dwc3 *dwc = ctx;
struct device_d *dev = dwc->dev;
int ret;
 
-   switch (dwc->dr_mode) {
+   switch (mode) {
case USB_DR_MODE_PERIPHERAL:
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
 
@@ -963,13 +964,20 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
}
break;
default:
-   dev_err(dev, "Unsupported mode of operation %d\n", 
dwc->dr_mode);
return -EINVAL;
}
 
return 0;
 }
 
+static int dwc3_core_init_mode(struct dwc3 *dwc)
+{
+   if (dwc->dr_mode == USB_DR_MODE_OTG)
+   return usb_register_otg_device(dwc->dev, dwc3_set_mode, dwc);
+   else
+   return dwc3_set_mode(dwc, dwc->dr_mode);
+}
+
 static void dwc3_get_properties(struct dwc3 *dwc)
 {
struct device_d *dev = dwc->dev;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index df0a188a63..f2f7a311d1 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1336,7 +1336,6 @@ struct dwc3_gadget_ep_cmd_params {
 /* prototypes */
 int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
 void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode);
-void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
 
 /* check whether we are on the DWC_usb3 core */
 static inline bool dwc3_is_usb3(struct dwc3 *dwc)
-- 
2.24.0


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 5/5] usb: musb: use usb_register_otg_device()

2019-11-21 Thread Sascha Hauer
We now have usb_register_otg_device() to register an "otg" device. Use
it and drop the custom code.

Signed-off-by: Sascha Hauer 
---
 drivers/usb/musb/Kconfig |  1 +
 drivers/usb/musb/musb_dsps.c | 44 ++--
 2 files changed, 8 insertions(+), 37 deletions(-)

diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index b795f30275..127d6d1955 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -6,6 +6,7 @@ if USB_MUSB
 config USB_MUSB_DSPS
tristate
select OFDEVICE
+   select USB_OTGDEV
 
 config USB_MUSB_AM335X
tristate "AM335x USB support"
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 5fe3bcb7cd..3b76b6cc61 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -303,50 +303,20 @@ static int get_musb_port_mode(struct device_d *dev)
}
 }
 
-static int dsps_set_mode(struct param_d *param, void *priv)
+static int dsps_set_mode(void *ctx, enum usb_dr_mode mode)
 {
-   struct dsps_glue *glue = priv;
+   struct dsps_glue *glue = ctx;
 
-   if (glue->pdata.mode != MUSB_PORT_MODE_DUAL_ROLE)
-   return -EBUSY;
-
-   switch (glue->otgmode) {
-   case 0:
-   default:
-   return -EINVAL;
-   case 1:
+   if (mode == USB_DR_MODE_HOST)
glue->pdata.mode = MUSB_PORT_MODE_HOST;
-   break;
-   case 2:
+   else if (mode == USB_DR_MODE_PERIPHERAL)
glue->pdata.mode = MUSB_PORT_MODE_GADGET;
-   break;
-   }
+   else
+   return -EINVAL;
 
return musb_init_controller(&glue->musb, &glue->pdata);
 }
 
-static const char *dsps_mode_names[] = {
-   "otg", "host", "peripheral"
-};
-
-static int dsps_register_otg_device(struct dsps_glue *glue)
-{
-   int ret;
-
-   dev_set_name(&glue->otg_dev, "otg");
-   glue->otg_dev.id = DEVICE_ID_DYNAMIC,
-   glue->otg_dev.parent = glue->dev;
-
-   ret = register_device(&glue->otg_dev);
-   if (ret)
-   return ret;
-
-   dev_add_param_enum(&glue->otg_dev, "mode",
-   dsps_set_mode, NULL, &glue->otgmode,
-   dsps_mode_names, ARRAY_SIZE(dsps_mode_names), glue);
-   return 0;
-}
-
 static int dsps_probe(struct device_d *dev)
 {
struct resource *iores;
@@ -405,7 +375,7 @@ static int dsps_probe(struct device_d *dev)
config->multipoint = of_property_read_bool(dn, "mentor,multipoint");
 
if (pdata->mode == MUSB_PORT_MODE_DUAL_ROLE) {
-   ret = dsps_register_otg_device(glue);
+   ret = usb_register_otg_device(dev, dsps_set_mode, glue);
if (ret)
return ret;
return 0;
-- 
2.24.0


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 2/5] usb: Add function to register otg dev

2019-11-21 Thread Sascha Hauer
We have two drivers in the tree which register an "otg" device to
configure the host/peripheral switching. Before introducing a third
driver create a common function for it.

Signed-off-by: Sascha Hauer 
---
 drivers/usb/otg/Kconfig  |  4 +++
 drivers/usb/otg/Makefile |  2 +-
 drivers/usb/otg/otgdev.c | 69 
 include/usb/usb.h|  3 ++
 4 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/otg/otgdev.c

diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 2c9fb46e4d..2c094452b6 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -6,3 +6,7 @@ config USB_ULPI
 config USB_TWL4030
depends on MFD_TWL4030
bool "TWL4030 Transceiver support"
+
+config USB_OTGDEV
+   bool
+
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile
index 465a7f098c..49c2491e58 100644
--- a/drivers/usb/otg/Makefile
+++ b/drivers/usb/otg/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_USB_ULPI) += ulpi.o
 obj-$(CONFIG_USB_TWL4030)  += twl4030.o
-
+obj-$(CONFIG_USB_OTGDEV)   += otgdev.o
diff --git a/drivers/usb/otg/otgdev.c b/drivers/usb/otg/otgdev.c
new file mode 100644
index 00..7017796e8c
--- /dev/null
+++ b/drivers/usb/otg/otgdev.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+
+static int (*set_mode_callback)(void *ctx, enum usb_dr_mode mode);
+static unsigned int otg_mode;
+
+static int otg_set_mode(struct param_d *param, void *ctx)
+{
+   static int cur_mode = USB_DR_MODE_OTG;
+   int ret;
+
+   if (otg_mode == USB_DR_MODE_UNKNOWN)
+   return -EINVAL;
+
+   if (otg_mode == cur_mode)
+   return 0;
+
+   if (cur_mode != USB_DR_MODE_OTG)
+   return -EBUSY;
+
+   ret = set_mode_callback(ctx, otg_mode);
+   if (ret)
+   return ret;
+
+   cur_mode = otg_mode;
+
+   return 0;
+}
+
+static const char *otg_mode_names[] = {
+   [USB_DR_MODE_UNKNOWN] = "unknown",
+   [USB_DR_MODE_HOST] = "host",
+   [USB_DR_MODE_PERIPHERAL] = "peripheral",
+   [USB_DR_MODE_OTG] = "otg",
+};
+
+static struct device_d otg_device = {
+   .name = "otg",
+   .id = DEVICE_ID_SINGLE,
+};
+
+int usb_register_otg_device(struct device_d *parent,
+   int (*set_mode)(void *ctx, enum usb_dr_mode mode), 
void *ctx)
+{
+   int ret;
+   struct param_d *param_mode;
+
+   if (otg_device.parent)
+   return -EBUSY;
+
+   otg_device.parent = parent;
+   set_mode_callback = set_mode;
+   otg_mode = USB_DR_MODE_OTG;
+
+   ret = register_device(&otg_device);
+   if (ret)
+   return ret;
+
+   param_mode = dev_add_param_enum(&otg_device, "mode",
+   otg_set_mode, NULL, &otg_mode,
+   otg_mode_names, ARRAY_SIZE(otg_mode_names), ctx);
+   if (IS_ERR(param_mode))
+   return PTR_ERR(param_mode);
+
+   return 0;
+}
diff --git a/include/usb/usb.h b/include/usb/usb.h
index 0045608d64..d39de71aff 100644
--- a/include/usb/usb.h
+++ b/include/usb/usb.h
@@ -444,6 +444,9 @@ enum usb_phy_interface of_usb_get_phy_mode(struct 
device_node *np,
 enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np,
const char *propname);
 
+int usb_register_otg_device(struct device_d *parent,
+   int (*set_mode)(void *ctx, enum usb_dr_mode mode), 
void *ctx);
+
 extern struct list_head usb_device_list;
 
 #endif /*_USB_H_ */
-- 
2.24.0


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 4/5] usb: i.MX: Use usb_register_otg_device()

2019-11-21 Thread Sascha Hauer
We now have usb_register_otg_device() to register an "otg" device. Use
it and drop the custom code.

Signed-off-by: Sascha Hauer 
---
 .../boards/eukrea_cpuimx25/eukrea_cpuimx25.c  |  4 +-
 .../boards/eukrea_cpuimx35/eukrea_cpuimx35.c  |  4 +-
 drivers/usb/imx/Kconfig   |  1 +
 drivers/usb/imx/chipidea-imx.c| 85 +++
 include/usb/chipidea-imx.h|  8 +-
 5 files changed, 18 insertions(+), 84 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c 
b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
index 76d6f5ba86..77d92f0403 100644
--- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
+++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
@@ -145,14 +145,14 @@ static iomux_v3_cfg_t eukrea_cpuimx25_pads[] = {
 #ifndef CONFIG_USB_GADGET
 struct imxusb_platformdata otg_pdata = {
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
-   .mode = IMX_USB_MODE_HOST,
+   .mode = USB_DR_MODE_HOST,
.phymode = USBPHY_INTERFACE_MODE_UTMI,
 };
 #endif
 
 struct imxusb_platformdata hs_pdata = {
.flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY | 
MXC_EHCI_IPPUE_DOWN,
-   .mode = IMX_USB_MODE_HOST,
+   .mode = USB_DR_MODE_HOST,
 };
 #endif
 
diff --git a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c 
b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
index a10763780e..220a484bde 100644
--- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
+++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
@@ -95,14 +95,14 @@ static struct imx_ipu_fb_platform_data ipu_fb_data = {
 #ifndef CONFIG_USB_GADGET
 struct imxusb_platformdata otg_pdata = {
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
-   .mode = IMX_USB_MODE_HOST,
+   .mode = USB_DR_MODE_HOST,
.phymode = USBPHY_INTERFACE_MODE_UTMI,
 };
 #endif
 
 struct imxusb_platformdata hs_pdata = {
.flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY | 
MXC_EHCI_IPPUE_DOWN,
-   .mode = IMX_USB_MODE_HOST,
+   .mode = USB_DR_MODE_HOST,
 };
 #endif
 
diff --git a/drivers/usb/imx/Kconfig b/drivers/usb/imx/Kconfig
index 05f17fbd2f..34f35e0ff6 100644
--- a/drivers/usb/imx/Kconfig
+++ b/drivers/usb/imx/Kconfig
@@ -2,6 +2,7 @@
 config USB_IMX_CHIPIDEA
bool "i.MX USB support (read help)"
depends on ARCH_IMX
+   select USB_OTGDEV
help
  The Freescale i.MX SoCs have a variant of the chipidea ci13xxx for
  USB support. Traditionally in barebox this is supported through the
diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c
index 6c60c383f0..3cf5d26dcd 100644
--- a/drivers/usb/imx/chipidea-imx.c
+++ b/drivers/usb/imx/chipidea-imx.c
@@ -36,12 +36,11 @@ struct imx_chipidea {
void __iomem *base;
struct ehci_data data;
unsigned long flags;
-   uint32_t mode;
+   enum usb_dr_mode mode;
int portno;
struct device_d *usbmisc;
enum usb_phy_interface phymode;
struct param_d *param_mode;
-   int role_registered;
struct regulator *vbus;
struct phy *phy;
struct usb_phy *usbphy;
@@ -103,7 +102,6 @@ static int imx_chipidea_port_post_init(void *drvdata)
 static int imx_chipidea_probe_dt(struct imx_chipidea *ci)
 {
struct of_phandle_args out_args;
-   enum usb_dr_mode mode;
 
if (of_parse_phandle_with_args(ci->dev->device_node, "fsl,usbmisc",
"#index-cells", 0, &out_args))
@@ -116,29 +114,17 @@ static int imx_chipidea_probe_dt(struct imx_chipidea *ci)
ci->portno = out_args.args[0];
ci->flags = MXC_EHCI_MODE_UTMI_8BIT;
 
-   mode = of_usb_get_dr_mode(ci->dev->device_node, NULL);
+   ci->mode = of_usb_get_dr_mode(ci->dev->device_node, NULL);
 
-   switch (mode) {
-   case USB_DR_MODE_HOST:
-   default:
-   ci->mode = IMX_USB_MODE_HOST;
-   break;
-   case USB_DR_MODE_PERIPHERAL:
-   ci->mode = IMX_USB_MODE_DEVICE;
-   break;
-   case USB_DR_MODE_OTG:
-   ci->mode = IMX_USB_MODE_OTG;
-   break;
-   case USB_DR_MODE_UNKNOWN:
+   if (ci->mode == USB_DR_MODE_UNKNOWN) {
/*
 * No dr_mode specified. This means it can either be OTG
 * for port 0 or host mode for the other host-only ports.
 */
if (ci->portno == 0)
-   ci->mode = IMX_USB_MODE_OTG;
+   ci->mode = USB_DR_MODE_OTG;
else
-   ci->mode = IMX_USB_MODE_HOST;
-   break;
+   ci->mode = USB_DR_MODE_HOST;
}
 
ci->phymode = of_usb_get_phy_mode(ci->dev->device_node, NULL);
@@ -184,18 +170,15 @@ static int ci_ehci_detect(struct device_d *dev)
return ehci_detect(ci->ehci);
 }
 
-static int ci_register_role(struct imx_chipidea *ci)
+static int ci_set_mod

[PATCH 2/3] watchdog: core: use new dev_add_param_tristate helper for .running param

2019-11-21 Thread Ahmad Fatoum
Previous commit added a dev_add_param_tristate_ro that can be readily
used instead of the enum parameter here. Use it.
This also fixes the issue that running_names had external linkage.

Signed-off-by: Ahmad Fatoum 
---
 drivers/watchdog/wd_core.c | 9 +
 include/watchdog.h | 5 -
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index fcead1175558..b6e2a37b1f0c 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -152,12 +152,6 @@ static unsigned int dev_get_watchdog_priority(struct 
device_d *dev)
return priority;
 }
 
-const char *running_names[] = {
-   [WDOG_HW_RUNNING_UNSUPPORTED] = "unknown",
-   [WDOG_HW_RUNNING] = "1",
-   [WDOG_HW_NOT_RUNNING] = "0",
-};
-
 int watchdog_register(struct watchdog *wd)
 {
struct param_d *p;
@@ -176,8 +170,7 @@ int watchdog_register(struct watchdog *wd)
if (ret)
return ret;
 
-   p = dev_add_param_enum_ro(&wd->dev, "running", &wd->running,
- running_names, ARRAY_SIZE(running_names));
+   p = dev_add_param_tristate_ro(&wd->dev, "running", &wd->running);
if (IS_ERR(p))
return PTR_ERR(p);
 
diff --git a/include/watchdog.h b/include/watchdog.h
index 5790205a487b..9741570ce229 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -15,9 +15,12 @@
 
 #include 
 #include 
+#include 
 
 enum wdog_hw_runnning {
-WDOG_HW_RUNNING_UNSUPPORTED, WDOG_HW_RUNNING, WDOG_HW_NOT_RUNNING
+WDOG_HW_RUNNING_UNSUPPORTED = PARAM_TRISTATE_UNKNOWN,
+WDOG_HW_RUNNING = PARAM_TRISTATE_TRUE,
+WDOG_HW_NOT_RUNNING = PARAM_TRISTATE_FALSE
 };
 
 struct watchdog {
-- 
2.20.1


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 1/3] param: add dev_add_param_tristate(_ro) helpers

2019-11-21 Thread Ahmad Fatoum
This is can be considered an extension to the dev_add_param_bool
interfaces with a third value that's "unknown".
This can be used for cases, where barebox can flip a bit somewhere,
but it has no way of knowing what the initial state of the bit was,
e.g. turn on/off the watchdog, but no watchdog status.
Turn on/off a co-processor, but no co-processor online status.
And so on. Not providing a way to customize the "unknown" string
is a deliberate choice, so future device parameters follow the same
naming scheme.

Signed-off-by: Ahmad Fatoum 
---
 include/param.h | 24 
 lib/parameter.c | 22 ++
 2 files changed, 46 insertions(+)

diff --git a/include/param.h b/include/param.h
index 4ac502e726c0..d75f50ea3e60 100644
--- a/include/param.h
+++ b/include/param.h
@@ -63,6 +63,16 @@ struct param_d *dev_add_param_enum(struct device_d *dev, 
const char *name,
int (*get)(struct param_d *p, void *priv),
int *value, const char * const *names, int max, void *priv);
 
+enum param_tristate { PARAM_TRISTATE_UNKNOWN, PARAM_TRISTATE_TRUE, 
PARAM_TRISTATE_FALSE };
+
+struct param_d *dev_add_param_tristate(struct device_d *dev, const char *name,
+   int (*set)(struct param_d *p, void *priv),
+   int (*get)(struct param_d *p, void *priv),
+   int *value, void *priv);
+
+struct param_d *dev_add_param_tristate_ro(struct device_d *dev, const char 
*name,
+   int *value);
+
 struct param_d *dev_add_param_bitmask(struct device_d *dev, const char *name,
int (*set)(struct param_d *p, void *priv),
int (*get)(struct param_d *p, void *priv),
@@ -144,6 +154,20 @@ static inline struct param_d *dev_add_param_bitmask(struct 
device_d *dev, const
return ERR_PTR(-ENOSYS);
 }
 
+static inline struct param_d *dev_add_param_tristate(struct device_d *dev, 
const char *name,
+   int (*set)(struct param_d *p, void *priv),
+   int (*get)(struct param_d *p, void *priv),
+   int *value, void *priv)
+{
+   return ERR_PTR(-ENOSYS);
+}
+
+static inline struct param_d *dev_add_param_tristate_ro(struct device_d *dev, 
const char *name,
+   int *value)
+{
+   return ERR_PTR(-ENOSYS);
+}
+
 static inline struct param_d *dev_add_param_ip(struct device_d *dev, const 
char *name,
int (*set)(struct param_d *p, void *priv),
int (*get)(struct param_d *p, void *priv),
diff --git a/lib/parameter.c b/lib/parameter.c
index fdbb2e71d15d..22695634e5f1 100644
--- a/lib/parameter.c
+++ b/lib/parameter.c
@@ -588,6 +588,28 @@ struct param_d *dev_add_param_enum(struct device_d *dev, 
const char *name,
return &pe->param;
 }
 
+static const char *const tristate_names[] = {
+   [PARAM_TRISTATE_UNKNOWN] = "unknown",
+   [PARAM_TRISTATE_TRUE] = "1",
+   [PARAM_TRISTATE_FALSE] = "0",
+};
+
+struct param_d *dev_add_param_tristate(struct device_d *dev, const char *name,
+   int (*set)(struct param_d *p, void *priv),
+   int (*get)(struct param_d *p, void *priv),
+   int *value, void *priv)
+{
+   return dev_add_param_enum(dev, name, set, get, value, tristate_names,
+ ARRAY_SIZE(tristate_names), priv);
+}
+
+struct param_d *dev_add_param_tristate_ro(struct device_d *dev, const char 
*name,
+   int *value)
+{
+   return dev_add_param_enum_ro(dev, name, value, tristate_names,
+ARRAY_SIZE(tristate_names));
+}
+
 struct param_bitmask {
struct param_d param;
unsigned long *value;
-- 
2.20.1


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 3/3] remoteproc: add .stop device parameter for stopping remote processor

2019-11-21 Thread Ahmad Fatoum
Both the STM32 and i.MX7 remote proc drivers populate the .stop member
in the struct rproc, but it's not used anywhere. The firmware API is not
really fitting to 'unload' firmware. Add instead a device parameter to
stop a remote processor, e.g. remoteproc0.stop=1. This is similar to the
probe command used with MMCs.

Signed-off-by: Ahmad Fatoum 
---
 drivers/remoteproc/remoteproc_core.c | 30 +++-
 include/linux/remoteproc.h   |  2 ++
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 8a28c1bafc1b..e031640bc7a0 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -101,6 +101,8 @@ static int rproc_firmware_finish(struct firmware_handler 
*fh)
fw.size = rproc->fw_buf_ofs;
 
ret = rproc_start(rproc, &fw);
+   if (ret == 0)
+   rproc->stop = PARAM_TRISTATE_FALSE;
 
kfree(rproc->fw_buf);
 
@@ -120,6 +122,19 @@ static int rproc_register_dev(struct rproc *rproc, const 
char *alias)
return register_device(&rproc->dev);
 }
 
+static int rproc_set_stop(struct param_d *param, void *priv)
+{
+   struct rproc *rproc = priv;
+   int (*stop)(struct rproc *);
+
+   stop = rproc->ops->stop;
+
+   if (!stop)
+   return -ENOSYS;
+
+   return stop(rproc);
+}
+
 int rproc_add(struct rproc *rproc)
 {
struct device_d *dev = &rproc->dev;
@@ -142,12 +157,17 @@ int rproc_add(struct rproc *rproc)
fh->close = rproc_firmware_finish;
 
ret = firmwaremgr_register(fh);
-   if (ret)
-   dev_err(dev, "filed to register firmware handler %s\n", 
rproc->name);
-   else
-   dev_info(dev, "%s is available\n", rproc->name);
+   if (ret) {
+   dev_err(dev, "failed to register firmware handler %s\n", 
rproc->name);
+   return ret;
+   }
 
-   return ret;
+   rproc->stop = PARAM_TRISTATE_UNKNOWN;
+   dev_add_param_tristate(&rproc->dev, "stop", rproc_set_stop, NULL,
+  &rproc->stop, rproc);
+
+   dev_info(dev, "%s is available\n", rproc->name);
+   return 0;
 }
 
 struct rproc *rproc_alloc(struct device_d *dev, const char *name,
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index c6264d1c0a49..af35837fb39a 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -41,6 +41,8 @@ struct rproc {
 
void *fw_buf;
size_t fw_buf_ofs;
+
+   int stop;
 };
 
 struct rproc *rproc_alloc(struct device_d *dev, const char *name,
-- 
2.20.1


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox