* [PATCH v3 03/10] USB: ohci: da8xx: Allow a regulator to handle VBUS
From: Axel Haslam @ 2016-11-07 20:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107203948.28324-1-ahaslam@baylibre.com>
We need to remove the platform callbacks to be able to probe
the driver using device tree. Using a regulator to handle VBUS will
eliminate the need for these callbacks once all users are converted
to use a regulator.
The regulator equivalents to the platform callbacks are:
set_power -> regulator_enable/regulator_disable
get_power -> regulator_is_enabled
get_oci -> regulator_get_error_flags
ocic_notify -> regulator event notification
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
drivers/usb/host/ohci-da8xx.c | 97 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 9ed43c7..0a4b885 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/phy/phy.h>
#include <linux/platform_data/usb-davinci.h>
+#include <linux/regulator/consumer.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <asm/unaligned.h>
@@ -36,8 +37,12 @@ static int (*orig_ohci_hub_control)(struct usb_hcd *hcd, u16 typeReq,
static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
struct da8xx_ohci_hcd {
+ struct usb_hcd *hcd;
struct clk *usb11_clk;
struct phy *usb11_phy;
+ struct regulator *vbus_reg;
+ struct notifier_block nb;
+ unsigned int is_powered;
};
#define to_da8xx_ohci(hcd) (struct da8xx_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
@@ -82,56 +87,105 @@ static void ohci_da8xx_disable(struct usb_hcd *hcd)
static int ohci_da8xx_set_power(struct usb_hcd *hcd, int on)
{
+ struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
struct device *dev = hcd->self.controller;
struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+ int ret;
if (hub && hub->set_power)
return hub->set_power(1, on);
+ if (!da8xx_ohci->vbus_reg)
+ return 0;
+
+ if (on && !da8xx_ohci->is_powered) {
+ ret = regulator_enable(da8xx_ohci->vbus_reg);
+ if (ret) {
+ dev_err(dev, "Fail to enable regulator: %d\n", ret);
+ return ret;
+ }
+ da8xx_ohci->is_powered = 1;
+
+ } else if (!on && da8xx_ohci->is_powered) {
+ ret = regulator_disable(da8xx_ohci->vbus_reg);
+ if (ret) {
+ dev_err(dev, "Fail to disable regulator: %d\n", ret);
+ return ret;
+ }
+ da8xx_ohci->is_powered = 0;
+ }
+
return 0;
}
static int ohci_da8xx_get_power(struct usb_hcd *hcd)
{
+ struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
struct device *dev = hcd->self.controller;
struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
if (hub && hub->get_power)
return hub->get_power(1);
+ if (da8xx_ohci->vbus_reg)
+ return regulator_is_enabled(da8xx_ohci->vbus_reg);
+
return 1;
}
static int ohci_da8xx_get_oci(struct usb_hcd *hcd)
{
+ struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
struct device *dev = hcd->self.controller;
struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+ unsigned int flags;
+ int ret;
if (hub && hub->get_oci)
return hub->get_oci(1);
+ if (!da8xx_ohci->vbus_reg)
+ return 0;
+
+ ret = regulator_get_error_flags(da8xx_ohci->vbus_reg, &flags);
+ if (ret) {
+ dev_err(dev, "could not get regulator error flags: %d\n", ret);
+ return ret;
+ }
+
+ if (flags && REGULATOR_ERROR_OVER_CURRENT)
+ return 1;
+
return 0;
}
static int ohci_da8xx_has_set_power(struct usb_hcd *hcd)
{
+ struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
struct device *dev = hcd->self.controller;
struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
if (hub && hub->set_power)
return 1;
+ if (da8xx_ohci->vbus_reg)
+ return 1;
+
return 0;
}
static int ohci_da8xx_has_oci(struct usb_hcd *hcd)
{
+ struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
struct device *dev = hcd->self.controller;
struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
if (hub && hub->get_oci)
return 1;
+ if (da8xx_ohci->vbus_reg)
+ return 1;
+
return 0;
}
@@ -159,15 +213,41 @@ static void ohci_da8xx_ocic_handler(struct da8xx_ohci_root_hub *hub,
hub->set_power(port, 0);
}
+static int ohci_da8xx_regulator_event(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct da8xx_ohci_hcd *da8xx_ohci =
+ container_of(nb, struct da8xx_ohci_hcd, nb);
+ struct device *dev = da8xx_ohci->hcd->self.controller;
+
+ if (event & REGULATOR_EVENT_OVER_CURRENT) {
+ dev_warn(dev, "over current event\n");
+ ocic_mask |= 1;
+ ohci_da8xx_set_power(da8xx_ohci->hcd, 0);
+ }
+
+ return 0;
+}
+
static int ohci_da8xx_register_notify(struct usb_hcd *hcd)
{
+ struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
struct device *dev = hcd->self.controller;
struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+ int ret = 0;
if (hub && hub->ocic_notify)
- return hub->ocic_notify(ohci_da8xx_ocic_handler);
+ ret = hub->ocic_notify(ohci_da8xx_ocic_handler);
+ else if (da8xx_ohci->vbus_reg) {
+ da8xx_ohci->nb.notifier_call = ohci_da8xx_regulator_event;
+ ret = devm_regulator_register_notifier(da8xx_ohci->vbus_reg,
+ &da8xx_ohci->nb);
+ }
- return 0;
+ if (ret)
+ dev_err(dev, "Failed to register notifier: %d\n", ret);
+
+ return ret;
}
static void ohci_da8xx_unregister_notify(struct usb_hcd *hcd)
@@ -330,6 +410,7 @@ static int ohci_da8xx_probe(struct platform_device *pdev)
return -ENOMEM;
da8xx_ohci = to_da8xx_ohci(hcd);
+ da8xx_ohci->hcd = hcd;
da8xx_ohci->usb11_clk = devm_clk_get(&pdev->dev, "usb11");
if (IS_ERR(da8xx_ohci->usb11_clk)) {
@@ -347,6 +428,18 @@ static int ohci_da8xx_probe(struct platform_device *pdev)
goto err;
}
+ da8xx_ohci->vbus_reg = devm_regulator_get_optional(&pdev->dev, "vbus");
+ if (IS_ERR(da8xx_ohci->vbus_reg)) {
+ error = PTR_ERR(da8xx_ohci->vbus_reg);
+ if (error == -ENODEV)
+ da8xx_ohci->vbus_reg = NULL;
+ else {
+ dev_err(&pdev->dev,
+ "Failed to get regulator: %d\n", error);
+ goto err;
+ }
+ }
+
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd->regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(hcd->regs)) {
--
2.10.1
^ permalink raw reply related
* [PATCH v3 02/10] USB: ohci: da8xx: Prepare to remove platform callbacks
From: Axel Haslam @ 2016-11-07 20:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107203948.28324-1-ahaslam@baylibre.com>
Wrap the platform data callbacks into separate functions.
This will help migrate to using a regulator by providing a well defined
place to implement the regulator functions while the platform calls
are still in place and users have not been converted.
The platform callbacks will be removed on a following patch.
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
drivers/usb/host/ohci-da8xx.c | 125 ++++++++++++++++++++++++++++++++++--------
1 file changed, 102 insertions(+), 23 deletions(-)
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 0442c64..9ed43c7 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -80,6 +80,72 @@ static void ohci_da8xx_disable(struct usb_hcd *hcd)
clk_disable_unprepare(da8xx_ohci->usb11_clk);
}
+static int ohci_da8xx_set_power(struct usb_hcd *hcd, int on)
+{
+ struct device *dev = hcd->self.controller;
+ struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+
+ if (hub && hub->set_power)
+ return hub->set_power(1, on);
+
+ return 0;
+}
+
+static int ohci_da8xx_get_power(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+
+ if (hub && hub->get_power)
+ return hub->get_power(1);
+
+ return 1;
+}
+
+static int ohci_da8xx_get_oci(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+
+ if (hub && hub->get_oci)
+ return hub->get_oci(1);
+
+ return 0;
+}
+
+static int ohci_da8xx_has_set_power(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+
+ if (hub && hub->set_power)
+ return 1;
+
+ return 0;
+}
+
+static int ohci_da8xx_has_oci(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+
+ if (hub && hub->get_oci)
+ return 1;
+
+ return 0;
+}
+
+static int ohci_da8xx_has_potpgt(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+
+ if (hub && hub->potpgt)
+ return 1;
+
+ return 0;
+}
+
/*
* Handle the port over-current indicator change.
*/
@@ -93,6 +159,26 @@ static void ohci_da8xx_ocic_handler(struct da8xx_ohci_root_hub *hub,
hub->set_power(port, 0);
}
+static int ohci_da8xx_register_notify(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+
+ if (hub && hub->ocic_notify)
+ return hub->ocic_notify(ohci_da8xx_ocic_handler);
+
+ return 0;
+}
+
+static void ohci_da8xx_unregister_notify(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+
+ if (hub && hub->ocic_notify)
+ hub->ocic_notify(NULL);
+}
+
static int ohci_da8xx_reset(struct usb_hcd *hcd)
{
struct device *dev = hcd->self.controller;
@@ -126,16 +212,18 @@ static int ohci_da8xx_reset(struct usb_hcd *hcd)
* the correct hub descriptor...
*/
rh_a = ohci_readl(ohci, &ohci->regs->roothub.a);
- if (hub->set_power) {
+ if (ohci_da8xx_has_set_power(hcd)) {
rh_a &= ~RH_A_NPS;
rh_a |= RH_A_PSM;
}
- if (hub->get_oci) {
+ if (ohci_da8xx_has_oci(hcd)) {
rh_a &= ~RH_A_NOCP;
rh_a |= RH_A_OCPM;
}
- rh_a &= ~RH_A_POTPGT;
- rh_a |= hub->potpgt << 24;
+ if (ohci_da8xx_has_potpgt(hcd)) {
+ rh_a &= ~RH_A_POTPGT;
+ rh_a |= hub->potpgt << 24;
+ }
ohci_writel(ohci, rh_a, &ohci->regs->roothub.a);
return result;
@@ -168,7 +256,6 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
u16 wIndex, char *buf, u16 wLength)
{
struct device *dev = hcd->self.controller;
- struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
int temp;
switch (typeReq) {
@@ -182,11 +269,11 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = roothub_portstatus(hcd_to_ohci(hcd), wIndex - 1);
/* The port power status (PPS) bit defaults to 1 */
- if (hub->get_power && hub->get_power(wIndex) == 0)
+ if (!ohci_da8xx_get_power(hcd))
temp &= ~RH_PS_PPS;
/* The port over-current indicator (POCI) bit is always 0 */
- if (hub->get_oci && hub->get_oci(wIndex) > 0)
+ if (ohci_da8xx_get_oci(hcd))
temp |= RH_PS_POCI;
/* The over-current indicator change (OCIC) bit is 0 too */
@@ -211,10 +298,7 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
dev_dbg(dev, "%sPortFeature(%u): %s\n",
temp ? "Set" : "Clear", wIndex, "POWER");
- if (!hub->set_power)
- return -EPIPE;
-
- return hub->set_power(wIndex, temp) ? -EPIPE : 0;
+ return ohci_da8xx_set_power(hcd, temp) ? -EPIPE : 0;
case USB_PORT_FEAT_C_OVER_CURRENT:
dev_dbg(dev, "%sPortFeature(%u): %s\n",
temp ? "Set" : "Clear", wIndex,
@@ -236,15 +320,10 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
static int ohci_da8xx_probe(struct platform_device *pdev)
{
- struct da8xx_ohci_root_hub *hub = dev_get_platdata(&pdev->dev);
struct da8xx_ohci_hcd *da8xx_ohci;
struct usb_hcd *hcd;
struct resource *mem;
int error, irq;
-
- if (hub == NULL)
- return -ENODEV;
-
hcd = usb_create_hcd(&ohci_da8xx_hc_driver, &pdev->dev,
dev_name(&pdev->dev));
if (!hcd)
@@ -290,12 +369,13 @@ static int ohci_da8xx_probe(struct platform_device *pdev)
device_wakeup_enable(hcd->self.controller);
- if (hub->ocic_notify) {
- error = hub->ocic_notify(ohci_da8xx_ocic_handler);
- if (!error)
- return 0;
- }
+ error = ohci_da8xx_register_notify(hcd);
+ if (error)
+ goto err_remove_hcd;
+
+ return 0;
+err_remove_hcd:
usb_remove_hcd(hcd);
err:
usb_put_hcd(hcd);
@@ -305,9 +385,8 @@ static int ohci_da8xx_probe(struct platform_device *pdev)
static int ohci_da8xx_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
- struct da8xx_ohci_root_hub *hub = dev_get_platdata(&pdev->dev);
- hub->ocic_notify(NULL);
+ ohci_da8xx_unregister_notify(hcd);
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
--
2.10.1
^ permalink raw reply related
* [PATCH v3 01/10] USB: ohci: da8xx: use ohci priv data instead of globals
From: Axel Haslam @ 2016-11-07 20:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107203948.28324-1-ahaslam@baylibre.com>
Instead of global variables, use the extra_priv_size of
the ohci driver.
We cannot yet move the ocic mask because this is used on
the interrupt handler which is registerded through platform
data and does not have an hcd pointer. This will be moved
on a later patch.
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
drivers/usb/host/ohci-da8xx.c | 72 +++++++++++++++++++++++++------------------
1 file changed, 42 insertions(+), 30 deletions(-)
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 429d58b..0442c64 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -35,43 +35,49 @@ static int (*orig_ohci_hub_control)(struct usb_hcd *hcd, u16 typeReq,
u16 wValue, u16 wIndex, char *buf, u16 wLength);
static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
-static struct clk *usb11_clk;
-static struct phy *usb11_phy;
+struct da8xx_ohci_hcd {
+ struct clk *usb11_clk;
+ struct phy *usb11_phy;
+};
+#define to_da8xx_ohci(hcd) (struct da8xx_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
/* Over-current indicator change bitmask */
static volatile u16 ocic_mask;
-static int ohci_da8xx_enable(void)
+static int ohci_da8xx_enable(struct usb_hcd *hcd)
{
+ struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
int ret;
- ret = clk_prepare_enable(usb11_clk);
+ ret = clk_prepare_enable(da8xx_ohci->usb11_clk);
if (ret)
return ret;
- ret = phy_init(usb11_phy);
+ ret = phy_init(da8xx_ohci->usb11_phy);
if (ret)
goto err_phy_init;
- ret = phy_power_on(usb11_phy);
+ ret = phy_power_on(da8xx_ohci->usb11_phy);
if (ret)
goto err_phy_power_on;
return 0;
err_phy_power_on:
- phy_exit(usb11_phy);
+ phy_exit(da8xx_ohci->usb11_phy);
err_phy_init:
- clk_disable_unprepare(usb11_clk);
+ clk_disable_unprepare(da8xx_ohci->usb11_clk);
return ret;
}
-static void ohci_da8xx_disable(void)
+static void ohci_da8xx_disable(struct usb_hcd *hcd)
{
- phy_power_off(usb11_phy);
- phy_exit(usb11_phy);
- clk_disable_unprepare(usb11_clk);
+ struct da8xx_ohci_hcd *da8xx_ohci = to_da8xx_ohci(hcd);
+
+ phy_power_off(da8xx_ohci->usb11_phy);
+ phy_exit(da8xx_ohci->usb11_phy);
+ clk_disable_unprepare(da8xx_ohci->usb11_clk);
}
/*
@@ -97,7 +103,7 @@ static int ohci_da8xx_reset(struct usb_hcd *hcd)
dev_dbg(dev, "starting USB controller\n");
- result = ohci_da8xx_enable();
+ result = ohci_da8xx_enable(hcd);
if (result < 0)
return result;
@@ -109,7 +115,7 @@ static int ohci_da8xx_reset(struct usb_hcd *hcd)
result = ohci_setup(hcd);
if (result < 0) {
- ohci_da8xx_disable();
+ ohci_da8xx_disable(hcd);
return result;
}
@@ -231,6 +237,7 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
static int ohci_da8xx_probe(struct platform_device *pdev)
{
struct da8xx_ohci_root_hub *hub = dev_get_platdata(&pdev->dev);
+ struct da8xx_ohci_hcd *da8xx_ohci;
struct usb_hcd *hcd;
struct resource *mem;
int error, irq;
@@ -238,25 +245,29 @@ static int ohci_da8xx_probe(struct platform_device *pdev)
if (hub == NULL)
return -ENODEV;
- usb11_clk = devm_clk_get(&pdev->dev, "usb11");
- if (IS_ERR(usb11_clk)) {
- if (PTR_ERR(usb11_clk) != -EPROBE_DEFER)
+ hcd = usb_create_hcd(&ohci_da8xx_hc_driver, &pdev->dev,
+ dev_name(&pdev->dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ da8xx_ohci = to_da8xx_ohci(hcd);
+
+ da8xx_ohci->usb11_clk = devm_clk_get(&pdev->dev, "usb11");
+ if (IS_ERR(da8xx_ohci->usb11_clk)) {
+ if (PTR_ERR(da8xx_ohci->usb11_clk) != -EPROBE_DEFER)
dev_err(&pdev->dev, "Failed to get clock.\n");
- return PTR_ERR(usb11_clk);
+ error = PTR_ERR(da8xx_ohci->usb11_clk);
+ goto err;
}
- usb11_phy = devm_phy_get(&pdev->dev, "usb-phy");
- if (IS_ERR(usb11_phy)) {
- if (PTR_ERR(usb11_phy) != -EPROBE_DEFER)
+ da8xx_ohci->usb11_phy = devm_phy_get(&pdev->dev, "usb-phy");
+ if (IS_ERR(da8xx_ohci->usb11_phy)) {
+ if (PTR_ERR(da8xx_ohci->usb11_phy) != -EPROBE_DEFER)
dev_err(&pdev->dev, "Failed to get phy.\n");
- return PTR_ERR(usb11_phy);
+ error = PTR_ERR(da8xx_ohci->usb11_phy);
+ goto err;
}
- hcd = usb_create_hcd(&ohci_da8xx_hc_driver, &pdev->dev,
- dev_name(&pdev->dev));
- if (!hcd)
- return -ENOMEM;
-
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd->regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(hcd->regs)) {
@@ -321,7 +332,7 @@ static int ohci_da8xx_suspend(struct platform_device *pdev,
if (ret)
return ret;
- ohci_da8xx_disable();
+ ohci_da8xx_disable(hcd);
hcd->state = HC_STATE_SUSPENDED;
return ret;
@@ -337,7 +348,7 @@ static int ohci_da8xx_resume(struct platform_device *dev)
msleep(5);
ohci->next_statechange = jiffies;
- ret = ohci_da8xx_enable();
+ ret = ohci_da8xx_enable(hcd);
if (ret)
return ret;
@@ -349,7 +360,8 @@ static int ohci_da8xx_resume(struct platform_device *dev)
#endif
static const struct ohci_driver_overrides da8xx_overrides __initconst = {
- .reset = ohci_da8xx_reset,
+ .reset = ohci_da8xx_reset,
+ .extra_priv_size = sizeof(struct da8xx_ohci_hcd),
};
/*
--
2.10.1
^ permalink raw reply related
* [PATCH v3 00/10] Add DT support for ohci-da8xx
From: Axel Haslam @ 2016-11-07 20:39 UTC (permalink / raw)
To: linux-arm-kernel
The purpose of this patch series is to add DT support for the davinci
ohci driver.
To be able to use device tree to probe the driver, we need to remove
the platform callbacks that are handling vbus and over current.
The first four patches prepare the stage by allowing to use a regulator
instead of the callbacks.
The next three patches convert the callback users to use a regulator
instead and then remove the callbacks from the driver and platform code.
Finally, we add device tree bindings and support in the driver.
DEPENDENCIES:
This series has depends on some patches currently under review
but mostly accepted:
1. [PATCH 0/3] fix ohci phy name [1] (accepted)
2. [PATCH/RFC v2 0/3] regulator: handling of error conditions for usb drivers [2] (accepted)
3. [PATCH] gpio: davinci: Use unique labels for each gpio chip [3] (review pending)
Also the current davinci baranches soon to be pulled to linux-next:
davinci-for-v4.10/soc
davinci-for-v4.10/dt
davinci-for-v4.10/defconfig
davinci-for-v4.10/cleanup
A branch with all the dependencies can be found here [4].
Changes form v2->v3
* drop patches that have been integrated to arch/arm
* drop regulator patches which will be integrated through regulator tree
* use of the accepted regulator API to get over current status
* better patch separation with the use of wrappers
Changes from v1->v2
* Rebased and added patch to make ohci a separate driver
* Use a regulator instead of handling Gpios (David Lechner)
* Add an over current mode to regulator framework
* Fixed regulator is able to register for and over current irq
* Added patch by Alexandre to remove build warnings
* Moved global variables into private hcd structure.
[1] https://lkml.org/lkml/2016/11/2/208
[2] https://lkml.org/lkml/2016/11/3/188
[3] http://www.spinics.net/lists/linux-gpio/msg17710.html
[4] https://github.com/axelhaslamx/linux-axel/commits/ohci-da8xx-dt-v3
Axel Haslam (10):
USB: ohci: da8xx: use ohci priv data instead of globals
USB: ohci: da8xx: Prepare to remove platform callbacks
USB: ohci: da8xx: Allow a regulator to handle VBUS
ARM: davinci: da830: Handle vbus with a regulator
ARM: davinci: hawk: Remove vbus and over current gpios
USB: ohci: da8xx: Remove ohci platform callbacks
USB: ohci: da8xx: use a flag instead of mask for ocic
USB: ohci: da8xx: Add devicetree bindings
USB: ohci: da8xx: Allow probing from DT
ARM: dts: da850: add usb device node
.../devicetree/bindings/usb/ohci-da8xx.txt | 39 ++++
arch/arm/boot/dts/da850-lcdk.dts | 8 +
arch/arm/boot/dts/da850.dtsi | 8 +
arch/arm/mach-davinci/board-da830-evm.c | 108 ++++-----
arch/arm/mach-davinci/board-omapl138-hawk.c | 99 +-------
arch/arm/mach-davinci/include/mach/da8xx.h | 2 +-
arch/arm/mach-davinci/usb-da8xx.c | 3 +-
drivers/usb/host/ohci-da8xx.c | 253 +++++++++++++++------
include/linux/platform_data/usb-davinci.h | 20 --
9 files changed, 283 insertions(+), 257 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/ohci-da8xx.txt
--
2.10.1
^ permalink raw reply
* [PATCH v1 03/11] drivers: soc: hisi: Add support for Hisilicon Djtag driver
From: Arnd Bergmann @ 2016-11-07 20:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2a8dc40f-be75-b010-3ec7-6912f02e3c90@huawei.com>
On Monday, November 7, 2016 2:15:10 PM CET John Garry wrote:
>
> Hi Arnd,
>
> The new bus type tries to model the djtag in a similar way to I2C/USB
> driver arch, where we have a host bus adapter and child devices attached
> to the bus. The child devices are bus driver devices and have bus
> addresses. We think of the djtag as a separate bus, so we are modelling
> it as such.
>
> The bus driver offers a simple host interface for clients to read/write
> to the djtag bus: bus accesses are hidden from the client, the host
> drives the bus.
Ok, in that case we should probably start out by having a bus specific
DT binding, and separating the description from that of the bus master
device.
I'd suggest requiring #address-cells=<1> and #size-cells=<0> in the master
node, and listing the children by reg property. If the address is not
easily expressed as a single integer, use a larger #address-cells value.
Another option that we have previously used was to actually pretend that
a vendor specific bus is an i2c bus and use the i2c probing infrastructure,
but that only makes sense if the software side closely resembles i2c
(this was the case for Allwinner I think, but I have not looked at
your driver in enough detail to know if it is true here as well).
Arnd
^ permalink raw reply
* [linux-sunxi] [PATCH v5 4/7] ASoC: sunxi: Add sun8i I2S driver
From: Maxime Ripard @ 2016-11-07 20:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161106190248.48b59e166bcd9d6f0ebb4d04@free.fr>
Hi,
On Sun, Nov 06, 2016 at 07:02:48PM +0100, Jean-Francois Moine wrote:
> On Sun, 23 Oct 2016 09:33:16 +0800
> Chen-Yu Tsai <wens@csie.org> wrote:
>
> > On Fri, Oct 21, 2016 at 4:36 PM, Jean-Francois Moine <moinejf@free.fr> wrote:
> > > This patch adds I2S support to sun8i SoCs as the A83T and H3.
> > >
> > > Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
> > > ---
> > > Note: This driver is closed to the sun4i-i2s except that:
> > > - it handles the H3
> >
> > If it's close to sun4i-i2s, you should probably rework that one to support
> > the newer SoCs.
>
> I started to add the H3 into the sun4i-i2s, but I am blocked with
> regmap.
> Many H3 registers are common with the A10, but some of them have more
> or less fields, the fields may be at different offsets. And, finally,
> some registers are completely different.
> This would not raise any problem, except with regmap which is really
> painful.
That's weird, because regmap's regmap_field should make that much
easier.
> As I may understood, regmap is used to simplify suspend/resume, but, is
> it useful to save the I2S register on suspend?
> Practically, I am streaming some tune on my device. I suspend it for
> any reason. The next morning, I resume it. Are you sure I want to
> continue to hear the end of the tune?
>
> I better think that streaming should be simply stopped on suspend.
You're mistaken. The code in there is for *runtime* suspend, ie when
the device is no longer used, so that case shouldn't even happen at
all.
(And real suspend isn't supported anyway)
> Then, there is no need to save the playing registers, and, here I am,
> there is no need to use regmap.
>
> May I go this way?
No, please don't. regmap is also providing very useful features, such
as access to all the registers through debugfs, or tracing. What
exactly feels painful to you?
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161107/a27a59e7/attachment.sig>
^ permalink raw reply
* [kernel-hardening] Re: [PATCHv4 0/4] WX checking for arm64
From: Ard Biesheuvel @ 2016-11-07 19:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107194910.GM19796@leverpostej>
On 7 November 2016 at 19:49, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Nov 07, 2016 at 03:38:02PM +0000, Mark Rutland wrote:
>> On Sun, Oct 30, 2016 at 03:03:07PM +0000, Catalin Marinas wrote:
>> > On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
>> > > Laura Abbott (4):
>> > > arm64: dump: Make ptdump debugfs a separate option
>> > > arm64: dump: Make the page table dumping seq_file optional
>> > > arm64: dump: Remove max_addr
>> > > arm64: dump: Add checking for writable and exectuable pages
>> >
>> > Queued for 4.10. Thanks.
>>
>> Catalin mentioned to me that he saw some KASAN splats when testing; it
>> looks like need a fixup something like the below.
>
> As an aside, it looks like any ptdump usage when KASAN is enabled takes
> several minutes, which at boot time looks like a hang.
>
> AFAICT, this is because KASAN allocates *huge* VA ranges (4TB+) worth of
> zeroed shadow memory at pte granularity (reusing the same pmd, pud,
> tables), and the ptdump code dutifully walks this with, with the added
> KASAN instrumentation overhead.
>
> I'll try to dig into that tomorrow; I suspect/hope it's not necessary to
> keep all of that mapped.
>
I have noticed that in the past, but I see how this delay at boot time
is an issue. However, I don't think there is a huge cost involved in
terms of memory footprint: AFAIK, the same PMD/PTE/kasan zero page are
mapped over and over across the range.
^ permalink raw reply
* [PATCH RFC 1/7] dma: pl08x: Add support for the DMA slave map
From: Arnd Bergmann @ 2016-11-07 19:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3d10d013-b18c-e10e-b596-d4d0f8b6e973@samsung.com>
On Monday, November 7, 2016 4:41:58 PM CET Sylwester Nawrocki wrote:
> On 11/05/2016 12:26 AM, Arnd Bergmann wrote:
>
> static const struct dma_slave_map s3c64xx_dma1_slave_map[] = {
> - { "samsung-pcm.1", "tx", (void *)"pcm1_tx" },
> - { "samsung-pcm.1", "rx", (void *)"pcm1_rx" },
> - { "samsung-i2s.1", "tx", (void *)"i2s1_tx" },
> - { "samsung-i2s.1", "rx", (void *)"i2s1_rx" },
> - { "s3c6410-spi.1", "tx", (void *)"spi1_tx" },
> - { "s3c6410-spi.1", "rx", (void *)"spi1_rx" },
> + { "samsung-pcm.1", "tx", (void *)&s3c64xx_dma1_info[0] },
> + { "samsung-pcm.1", "rx", (void *)&s3c64xx_dma1_info[1] },
> + { "samsung-i2s.1", "tx", (void *)&s3c64xx_dma1_info[2] },
> + { "samsung-i2s.1", "rx", (void *)&s3c64xx_dma1_info[3] },
> + { "s3c6410-spi.1", "tx", (void *)&s3c64xx_dma1_info[4] },
> + { "s3c6410-spi.1", "rx", (void *)&s3c64xx_dma1_info[5] },
> };
>
I think you can drop the (void*) cast either way (before and after
this change).
> diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
> index d5c75c8..0d1eb2e 100644
> --- a/drivers/dma/amba-pl08x.c
> +++ b/drivers/dma/amba-pl08x.c
> @@ -1793,6 +1793,23 @@ bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
> }
> EXPORT_SYMBOL_GPL(pl08x_filter_id);
>
> +static bool pl08x_filter_fn(struct dma_chan *chan, void *chan_id)
> +{
> + struct pl08x_dma_chan *plchan;
> +
> + /* Reject channels for devices not bound to this driver */
> + if (chan->device->dev->driver != &pl08x_amba_driver.drv)
> + return false;
This check should not be needed, you only get channels for the
device itself.
> + plchan = to_pl08x_chan(chan);
> +
> + /* Check that the channel is not taken! */
> + if (plchan->cd == chan_id)
> + return true;
What I had in mind was a bit different: Instead of comparing the
channel, I was thinking of modifying the channel itself, something
like:
plchan->signal = chan_id->signal;
plchan->periph_buses = chan_id->periph_buses;
after that, remove the plchan->cd data. Unfortunately, the muxing in
arch/arm/mach-spear/ makes this a bit harder. I'd have to think
about it some more. It may be easier to do this after moving
spear and lpc32xx over to use dma_slave_map.
Arnd
^ permalink raw reply
* [PATCH v3 1/3] Documentation: DT: add dma compatible for sun50i A64 SOC.
From: Maxime Ripard @ 2016-11-07 19:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107181457.GA3619@arx12>
On Tue, Nov 08, 2016 at 02:14:57AM +0800, Hao Zhang wrote:
> This adds documentation of the sun50i a64 dma binding compatible.
>
> Signed-off-by: Hao Zhang <hao5781286@gmail.com>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Thanks,
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161107/ab8769ab/attachment.sig>
^ permalink raw reply
* [kernel-hardening] Re: [PATCHv4 0/4] WX checking for arm64
From: Mark Rutland @ 2016-11-07 19:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107153802.GJ19796@leverpostej>
On Mon, Nov 07, 2016 at 03:38:02PM +0000, Mark Rutland wrote:
> On Sun, Oct 30, 2016 at 03:03:07PM +0000, Catalin Marinas wrote:
> > On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
> > > Laura Abbott (4):
> > > arm64: dump: Make ptdump debugfs a separate option
> > > arm64: dump: Make the page table dumping seq_file optional
> > > arm64: dump: Remove max_addr
> > > arm64: dump: Add checking for writable and exectuable pages
> >
> > Queued for 4.10. Thanks.
>
> Catalin mentioned to me that he saw some KASAN splats when testing; it
> looks like need a fixup something like the below.
As an aside, it looks like any ptdump usage when KASAN is enabled takes
several minutes, which at boot time looks like a hang.
AFAICT, this is because KASAN allocates *huge* VA ranges (4TB+) worth of
zeroed shadow memory at pte granularity (reusing the same pmd, pud,
tables), and the ptdump code dutifully walks this with, with the added
KASAN instrumentation overhead.
I'll try to dig into that tomorrow; I suspect/hope it's not necessary to
keep all of that mapped.
Thanks,
Mark.
^ permalink raw reply
* [PATCH V3 0/8] IOMMU probe deferral support
From: Robin Murphy @ 2016-11-07 19:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <006f01d236ae$61751c40$245f54c0$@codeaurora.org>
Hi Sricharan,
On 04/11/16 15:16, Sricharan wrote:
> Hi Robin,
>
>>>> Yikes, on second look, that definitely shouldn't be happening.
>>>> Everything below is probably the resulting fallout.
>>>
>>> [ 40.206703] vfio-pci 0000:08:00.0: Failed to setup iommu ops
>>>
>>> I think the above print which says "failed to setup iommu_ops"
>>> because the call ops->add_device failed in of_pci_iommu_configure
>>> is the reason for the failure, in my case i simply do not get this even with
>>> your scripts. ops->add_device succeeds in the rebind as well. So still
>>> checking what could be happening in your case.
>>
>> I was looking at your code base from [1].The ops->add_device
>> callback from of_pci_iommu_configure on the rebind is the
>> one which is causing the failure. But not able to spot out
>>from code which point is causing the failure. It would be very helpful
>> if i can know which is the return value from the add_device callback
>> or point inside add_device callback which fails in your setup.
>>
>>
>> [1] git://linux-arm.org/linux-rm iommu/misc
>
> With little more try, i saw an issue where i had an failure
> similar to what you reported. The issue happens when multiple
> devices fall in to same group due to matching sids. I ended up
> doing a fix like below and it would be nice to verify if it is the same
> that we are seeing in your setup and if the fix makes a difference ?
>
> From: Sricharan R <sricharan@codeaurora.org>
> Date: Fri, 4 Nov 2016 20:28:49 +0530
> Subject: [PATCH] iommu/arm-smmu: Fix group's reference counting
>
> iommu_group_get_for_dev which gets called in the add_device
> callback, increases the reference count of the iommu_group,
> so we do an iommu_group_put after that. iommu_group_get_for_dev
> inturn calls device_group callback and in the case of arm-smmu
> we call generic_device_group/pci_device_group which takes
> care of increasing the group's reference. But when we return
> an already existing group(when multiple devices have same group)
> the reference is not incremented, resulting in issues when the
> remove_device callback for the devices is invoked.
> Fixing the same here.
Bah, yes, this does look like my fault - after flip-flopping between
about 3 different ways to keep refcounts for the S2CR entries, none of
which would quite work, I ripped it all out but apparently still got
things wrong, oh well. Thanks for figuring it out.
On the probe-deferral angle, whilst it's useful to have uncovered this
bug, I don't think we should actually be calling remove_device() from
DMA teardown. I think it's preferable from a user perspective if group
numbering remains stable, rather than changing depending on the order in
which they unbind/rebind VFIO drivers. I'm really keen to try and get
this in shape for 4.10, so I've taken the liberty of hacking up my own
branch (iommu/defer) based on v3 - would you mind taking a look at the
two "iommu/of:" commits to see what you think? (Ignore the PCI changes
to your later patches - that was an experiment which didn't really work out)
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
> drivers/iommu/arm-smmu.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 71ce4b6..a1d0b3c 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -1516,8 +1516,10 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
> group = smmu->s2crs[idx].group;
> }
>
> - if (group)
> + if (group) {
> + iommu_group_get_by_id(iommu_group_id(group));
> return group;
This might as well just be inline, i.e.:
return iommu_group_get_by_id(iommu_group_id(group));
It's a shame we have to go all round the houses when we have the group
right there, but this is probably the most expedient fix. I guess we can
extend the API with some sort of iommu_group_get(group) overload in
future if we really want to.
Robin.
> + }
>
> if (dev_is_pci(dev))
> group = pci_device_group(dev);
>
^ permalink raw reply
* [PATCH V3 0/8] IOMMU probe deferral support
From: Will Deacon @ 2016-11-07 19:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <006f01d236ae$61751c40$245f54c0$@codeaurora.org>
On Fri, Nov 04, 2016 at 08:46:06PM +0530, Sricharan wrote:
> >>>Yikes, on second look, that definitely shouldn't be happening.
> >>>Everything below is probably the resulting fallout.
> >>
> >>[ 40.206703] vfio-pci 0000:08:00.0: Failed to setup iommu ops
> >>
> >>I think the above print which says "failed to setup iommu_ops"
> >>because the call ops->add_device failed in of_pci_iommu_configure
> >>is the reason for the failure, in my case i simply do not get this even with
> >>your scripts. ops->add_device succeeds in the rebind as well. So still
> >>checking what could be happening in your case.
> >
> >I was looking at your code base from [1].The ops->add_device
> >callback from of_pci_iommu_configure on the rebind is the
> >one which is causing the failure. But not able to spot out
> >from code which point is causing the failure. It would be very helpful
> >if i can know which is the return value from the add_device callback
> >or point inside add_device callback which fails in your setup.
> >
> >
> >[1] git://linux-arm.org/linux-rm iommu/misc
So this also applies to mainline.
> With little more try, i saw an issue where i had an failure
> similar to what you reported. The issue happens when multiple
> devices fall in to same group due to matching sids. I ended up
> doing a fix like below and it would be nice to verify if it is the same
> that we are seeing in your setup and if the fix makes a difference ?
>
> From: Sricharan R <sricharan@codeaurora.org>
> Date: Fri, 4 Nov 2016 20:28:49 +0530
> Subject: [PATCH] iommu/arm-smmu: Fix group's reference counting
>
> iommu_group_get_for_dev which gets called in the add_device
> callback, increases the reference count of the iommu_group,
> so we do an iommu_group_put after that. iommu_group_get_for_dev
> inturn calls device_group callback and in the case of arm-smmu
> we call generic_device_group/pci_device_group which takes
> care of increasing the group's reference. But when we return
> an already existing group(when multiple devices have same group)
> the reference is not incremented, resulting in issues when the
> remove_device callback for the devices is invoked.
> Fixing the same here.
>
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
> drivers/iommu/arm-smmu.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 71ce4b6..a1d0b3c 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -1516,8 +1516,10 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
> group = smmu->s2crs[idx].group;
> }
>
> - if (group)
> + if (group) {
> + iommu_group_get_by_id(iommu_group_id(group));
> return group;
> + }
This is foul :(
I think we should either add a function for incrementing the refcount on a
group, or we should get a handle on the existing aliasing device and get
the group from that. As written, this patch is far too subtle.
Joerg -- do you have any preference?
Will
^ permalink raw reply
* [PATCH 2/3] ipmi/bt-bmc: maintain a request expiry list
From: Corey Minyard @ 2016-11-07 19:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478073426-3714-3-git-send-email-clg@kaod.org>
On 11/02/2016 02:57 AM, C?dric Le Goater wrote:
> Regarding the response expiration handling, the IPMI spec says :
>
> The BMC must not return a given response once the corresponding
> Request-to-Response interval has passed. The BMC can ensure this
> by maintaining its own internal list of outstanding requests through
> the interface. The BMC could age and expire the entries in the list
> by expiring the entries at an interval that is somewhat shorter than
> the specified Request-to-Response interval....
>
> To handle such case, we maintain list of received requests using the
> seq number of the BT message to identify them. The list is updated
> each time a request is received and a response is sent. The expiration
> of the reponses is handled at each updates but also with a timer.
This looks correct, but it seems awfully complicated.
Why can't you get the current time before the wait_event_interruptible()
and then compare the time before you do the write? That would seem to
accomplish the same thing without any lists or extra locks.
Also, if you are going to have multiple writers on this interface, I don't
think the interface will work correctly. I think you need to claim the
mutex first. Otherwise you might get into a situation where two writers
will wake up at the same time, the first writes and releases the mutex,
then the second will find that the interface is busy and fail.
If I am correct, the mutex will need to become interruptible and come
first, I think. (And the timing would have to start before the mutex,
of course.) This applies to both the read and write interface.
Another thing is that this is request-to-release time. If a request takes
a long time to process (say, a write to a flash device) the timeout would
need to be decreased by the processing time. It's probably ok to not
do that for the moment, but you may want to add a note. Fixing that
would require adding a timeout for each message.
-corey
> Signed-off-by: C?dric Le Goater <clg@kaod.org>
> ---
> drivers/char/ipmi/bt-bmc.c | 132 +++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 132 insertions(+)
>
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index fc9e8891eae3..e751e4a754b7 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -17,6 +17,7 @@
> #include <linux/platform_device.h>
> #include <linux/poll.h>
> #include <linux/sched.h>
> +#include <linux/slab.h>
> #include <linux/timer.h>
>
> /*
> @@ -57,6 +58,15 @@
>
> #define BT_BMC_BUFFER_SIZE 256
>
> +#define BT_BMC_RESPONSE_TIME 5 /* seconds */
> +
> +struct ipmi_request {
> + struct list_head list;
> +
> + u8 seq;
> + unsigned long expires;
> +};
> +
> struct bt_bmc {
> struct device dev;
> struct miscdevice miscdev;
> @@ -65,6 +75,11 @@ struct bt_bmc {
> wait_queue_head_t queue;
> struct timer_list poll_timer;
> struct mutex mutex;
> +
> + unsigned int response_time;
> + struct timer_list requests_timer;
> + spinlock_t requests_lock;
> + struct list_head requests;
> };
>
> static atomic_t open_count = ATOMIC_INIT(0);
> @@ -163,6 +178,94 @@ static int bt_bmc_open(struct inode *inode, struct file *file)
> }
>
> /*
> + * lock should be held
> + */
> +static void drop_expired_requests(struct bt_bmc *bt_bmc)
> +{
> + unsigned long flags = 0;
> + struct ipmi_request *req, *next;
> + unsigned long next_expires = 0;
> + int start_timer = 0;
> +
> + spin_lock_irqsave(&bt_bmc->requests_lock, flags);
> + list_for_each_entry_safe(req, next, &bt_bmc->requests, list) {
> + if (time_after_eq(jiffies, req->expires)) {
> + pr_warn("BT: request seq:%d has expired. dropping\n",
> + req->seq);
> + list_del(&req->list);
> + kfree(req);
> + continue;
> + }
> + if (!start_timer) {
> + start_timer = 1;
> + next_expires = req->expires;
> + } else {
> + next_expires = min(next_expires, req->expires);
> + }
> + }
> + spin_unlock_irqrestore(&bt_bmc->requests_lock, flags);
> +
> + /* and possibly restart */
> + if (start_timer)
> + mod_timer(&bt_bmc->requests_timer, next_expires);
> +}
> +
> +static void requests_timer(unsigned long data)
> +{
> + struct bt_bmc *bt_bmc = (void *)data;
> +
> + drop_expired_requests(bt_bmc);
> +}
> +
> +static int bt_bmc_add_request(struct bt_bmc *bt_bmc, u8 seq)
> +{
> + struct ipmi_request *req;
> +
> + req = kmalloc(sizeof(*req), GFP_KERNEL);
> + if (!req)
> + return -ENOMEM;
> +
> + req->seq = seq;
> + req->expires = jiffies +
> + msecs_to_jiffies(bt_bmc->response_time * 1000);
> +
> + spin_lock(&bt_bmc->requests_lock);
> + list_add(&req->list, &bt_bmc->requests);
> + spin_unlock(&bt_bmc->requests_lock);
> +
> + drop_expired_requests(bt_bmc);
> + return 0;
> +}
> +
> +static int bt_bmc_remove_request(struct bt_bmc *bt_bmc, u8 seq)
> +{
> + struct ipmi_request *req, *next;
> + int ret = -EBADRQC; /* Invalid request code */
> +
> + spin_lock(&bt_bmc->requests_lock);
> + list_for_each_entry_safe(req, next, &bt_bmc->requests, list) {
> + /*
> + * The sequence number should be unique, so remove the
> + * first matching request found. If there are others,
> + * they should expire
> + */
> + if (req->seq == seq) {
> + list_del(&req->list);
> + kfree(req);
> + ret = 0;
> + break;
> + }
> + }
> + spin_unlock(&bt_bmc->requests_lock);
> +
> + if (ret)
> + pr_warn("BT: request seq:%d is invalid\n", seq);
> +
> + drop_expired_requests(bt_bmc);
> + return ret;
> +}
> +
> +/*
> * The BT (Block Transfer) interface means that entire messages are
> * buffered by the host before a notification is sent to the BMC that
> * there is data to be read. The first byte is the length and the
> @@ -231,6 +334,13 @@ static ssize_t bt_bmc_read(struct file *file, char __user *buf,
> len_byte = 0;
> }
>
> + if (ret > 0) {
> + int ret2 = bt_bmc_add_request(bt_bmc, kbuffer[2]);
> +
> + if (ret2)
> + ret = ret2;
> + }
> +
> clr_b_busy(bt_bmc);
>
> out_unlock:
> @@ -283,12 +393,20 @@ static ssize_t bt_bmc_write(struct file *file, const char __user *buf,
> clr_wr_ptr(bt_bmc);
>
> while (count) {
> + int ret2;
> +
> nwritten = min_t(ssize_t, count, sizeof(kbuffer));
> if (copy_from_user(&kbuffer, buf, nwritten)) {
> ret = -EFAULT;
> break;
> }
>
> + ret2 = bt_bmc_remove_request(bt_bmc, kbuffer[2]);
> + if (ret2) {
> + ret = ret2;
> + break;
> + }
> +
> bt_writen(bt_bmc, kbuffer, nwritten);
>
> count -= nwritten;
> @@ -438,6 +556,8 @@ static int bt_bmc_probe(struct platform_device *pdev)
>
> mutex_init(&bt_bmc->mutex);
> init_waitqueue_head(&bt_bmc->queue);
> + INIT_LIST_HEAD(&bt_bmc->requests);
> + spin_lock_init(&bt_bmc->requests_lock);
>
> bt_bmc->miscdev.minor = MISC_DYNAMIC_MINOR,
> bt_bmc->miscdev.name = DEVICE_NAME,
> @@ -451,6 +571,8 @@ static int bt_bmc_probe(struct platform_device *pdev)
>
> bt_bmc_config_irq(bt_bmc, pdev);
>
> + bt_bmc->response_time = BT_BMC_RESPONSE_TIME;
> +
> if (bt_bmc->irq) {
> dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
> } else {
> @@ -468,6 +590,9 @@ static int bt_bmc_probe(struct platform_device *pdev)
> BT_CR0_ENABLE_IBT,
> bt_bmc->base + BT_CR0);
>
> + setup_timer(&bt_bmc->requests_timer, requests_timer,
> + (unsigned long)bt_bmc);
> +
> clr_b_busy(bt_bmc);
>
> return 0;
> @@ -476,10 +601,17 @@ static int bt_bmc_probe(struct platform_device *pdev)
> static int bt_bmc_remove(struct platform_device *pdev)
> {
> struct bt_bmc *bt_bmc = dev_get_drvdata(&pdev->dev);
> + struct ipmi_request *req, *next;
>
> misc_deregister(&bt_bmc->miscdev);
> if (!bt_bmc->irq)
> del_timer_sync(&bt_bmc->poll_timer);
> +
> + del_timer_sync(&bt_bmc->requests_timer);
> + list_for_each_entry_safe(req, next, &bt_bmc->requests, list) {
> + list_del(&req->list);
> + kfree(req);
> + }
> return 0;
> }
>
^ permalink raw reply
* [PATCH 3/3] ipmi/bt-bmc: add a sysfs file to configure a maximum response time
From: Corey Minyard @ 2016-11-07 18:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478073426-3714-4-git-send-email-clg@kaod.org>
Sorry, I was at Plumbers and extra busy with other stuff. Just getting
around to reviewing this.
On 11/02/2016 02:57 AM, C?dric Le Goater wrote:
> We could also use an ioctl for that purpose. sysfs seems a better
> approach.
>
> Signed-off-by: C?dric Le Goater <clg@kaod.org>
> ---
> drivers/char/ipmi/bt-bmc.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index e751e4a754b7..d7146f0e900e 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -84,6 +84,33 @@ struct bt_bmc {
>
> static atomic_t open_count = ATOMIC_INIT(0);
>
> +static ssize_t bt_bmc_show_response_time(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct bt_bmc *bt_bmc = dev_get_drvdata(dev);
> +
> + return snprintf(buf, PAGE_SIZE - 1, "%d\n", bt_bmc->response_time);
> +}
> +
> +static ssize_t bt_bmc_set_response_time(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct bt_bmc *bt_bmc = dev_get_drvdata(dev);
> + unsigned long val;
> + int err;
> +
> + err = kstrtoul(buf, 0, &val);
> + if (err)
> + return err;
> + bt_bmc->response_time = val;
> + return count;
> +}
> +
> +static DEVICE_ATTR(response_time, 0644,
> + bt_bmc_show_response_time, bt_bmc_set_response_time);
> +
> static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
> {
> return ioread8(bt_bmc->base + reg);
> @@ -572,6 +599,10 @@ static int bt_bmc_probe(struct platform_device *pdev)
> bt_bmc_config_irq(bt_bmc, pdev);
>
> bt_bmc->response_time = BT_BMC_RESPONSE_TIME;
> + rc = device_create_file(&pdev->dev, &dev_attr_response_time);
> + if (rc)
> + dev_warn(&pdev->dev, "can't create response_time file\n");
> +
You added an extra space here.
>
> if (bt_bmc->irq) {
> dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
^ permalink raw reply
* [PATCH] arm/vdso: introduce vdso_mremap hook
From: Dmitry Safonov @ 2016-11-07 18:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107182734.GL1041@n2100.armlinux.org.uk>
On 11/07/2016 09:27 PM, Russell King - ARM Linux wrote:
> On Tue, Nov 01, 2016 at 08:22:14PM +0300, Dmitry Safonov wrote:
>> diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
>> index 53cf86cf2d1a..d1001f87c2f6 100644
>> --- a/arch/arm/kernel/vdso.c
>> +++ b/arch/arm/kernel/vdso.c
>> @@ -54,8 +54,11 @@ static const struct vm_special_mapping vdso_data_mapping = {
>> .pages = &vdso_data_page,
>> };
>>
>> +static int vdso_mremap(const struct vm_special_mapping *sm,
>> + struct vm_area_struct *new_vma);
>
> I'd much rather avoid this forward declaration. Is there any reason the
> function body can't be here?
>
Well, I didn't want it to be in the middle of static file variables -
those looks nice at this moment just on top of the file.
No other than that.
--
Dmitry
^ permalink raw reply
* [PATCH v2 0/7] soc: renesas: Identify SoC and register with the SoC bus
From: Krzysztof Kozlowski @ 2016-11-07 18:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMuHMdV4HG0aOr4Qp_OZXU=3jLeOJ2QaMKp09a3v4489ABbRcA@mail.gmail.com>
On Mon, Nov 07, 2016 at 10:35:31AM +0100, Geert Uytterhoeven wrote:
> On Mon, Oct 31, 2016 at 12:30 PM, Geert Uytterhoeven
> <geert+renesas@glider.be> wrote:
> > Some Renesas SoCs may exist in different revisions, providing slightly
> > different functionalities (e.g. R-Car H3 ES1.x and ES2.0), and behavior
> > (errate and quirks). This needs to be catered for by drivers and/or
> > platform code. The recently proposed soc_device_match() API seems like
> > a good fit to handle this.
> >
> > This patch series implements the core infrastructure to provide SoC and
> > revision information through the SoC bus for Renesas ARM SoCs. It
> > consists of 7 patches:
> > - Patches 1-4 provide soc_device_match(), with some related fixes,
> > - Patches 5-7 implement identification of Renesas SoCs and
> > registration with the SoC bus,
> >
> > Changes compared to v1:
> > - Add Acked-by,
> > - New patches:
> > - "[4/7] base: soc: Provide a dummy implementation of
> > soc_device_match()",
> > - "[5/7] ARM: shmobile: Document DT bindings for CCCR and PRR",
> > - "[6/7] arm64: dts: r8a7795: Add device node for PRR"
> > (more similar patches available, I'm not yet spamming you all
> > with them),
> > - Drop SoC families and family names; use fixed "Renesas" instead,
> > - Drop EMEV2, which doesn't have a chip ID register, and doesn't share
> > devices with other SoCs,
> > - Drop RZ/A1H and R-CAR M1A, which don't have chip ID registers (for
> > M1A: not accessible from the ARM core?),
> > - On arm, move "select SOC_BUS" from ARCH_RENESAS to Kconfig symbols
> > for SoCs that provide a chip ID register,
> > - Build renesas-soc only if SOC_BUS is enabled,
> > - Use "renesas,prr" and "renesas,cccr" device nodes in DT if
> > available, else fall back to hardcoded addresses for compatibility
> > with existing DTBs,
> > - Remove verification of product IDs; just print the ID instead,
> > - Don't register the SoC bus if the chip ID register is missing,
> > - Change R-Mobile APE6 fallback to use PRR instead of CCCR (it has
> > both).
> >
> > Merge strategy:
> > - In theory, patches 1-4 should go through Greg's driver core tree.
> > But it's a hard dependency for all users.
> > If people agree, I can provide an immutable branch in my
> > renesas-drivers repository, to be merged by all interested parties.
> > So far I'm aware of Freescale/NXP, and Renesas.
>
> And Samsung.
Yes, I would need it as well.
> Shall I create the immutable branch now?
...or the applying person could provide one.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v3 6/6] ARM: dts: sun6i: sina31s: Enable internal audio codec
From: Maxime Ripard @ 2016-11-07 18:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107100703.5586-7-wens@csie.org>
On Mon, Nov 07, 2016 at 06:07:03PM +0800, Chen-Yu Tsai wrote:
> The SinA31s routes the SoC's LINEOUT pins to a line out jack, and MIC1
> to a microphone jack, with MBIAS providing phantom power.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Applied, thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161107/7de58d87/attachment.sig>
^ permalink raw reply
* [PATCH v3 5/6] ARM: dts: sun6i: hummingbird: Enable internal audio codec
From: Maxime Ripard @ 2016-11-07 18:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107100703.5586-6-wens@csie.org>
On Mon, Nov 07, 2016 at 06:07:02PM +0800, Chen-Yu Tsai wrote:
> The Hummingbird A31 has headset and line in audio jacks and an onboard
> mic routed to the pins for the SoC's internal codec. The line out pins
> are routed to an onboard speaker amp, whose output is available on a
> pin header.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Applied, thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161107/42bbd2c7/attachment.sig>
^ permalink raw reply
* [PATCH v3 4/6] ARM: dts: sun6i: Add audio codec device node
From: Maxime Ripard @ 2016-11-07 18:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107100703.5586-5-wens@csie.org>
On Mon, Nov 07, 2016 at 06:07:01PM +0800, Chen-Yu Tsai wrote:
> The A31 SoC includes the Allwinner audio codec, capable of 24-bit
> playback up to 192 kHz and 24-bit capture up to 48 kHz.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> arch/arm/boot/dts/sun6i-a31.dtsi | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
> index 2e8bf93dcfb2..f68e6102b01b 100644
> --- a/arch/arm/boot/dts/sun6i-a31.dtsi
> +++ b/arch/arm/boot/dts/sun6i-a31.dtsi
> @@ -784,6 +784,19 @@
> reset-names = "ahb";
> };
>
> + codec: codec at 01c22c00 {
> + #sound-dai-cells = <0>;
> + compatible = "allwinner,sun6i-a31-codec";
> + reg = <0x01c22c00 0x98>;
The memory mapped region is 0x400. I fixed this and applied.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161107/81a10d8c/attachment.sig>
^ permalink raw reply
* [PATCH v3 3/3] ARM: dmaengine: sun6i: share the dma driver with sun50i
From: Hao Zhang @ 2016-11-07 18:28 UTC (permalink / raw)
To: linux-arm-kernel
According to the datasheet, the dma of A64 support 8/16/32/64 bits
so, we can add the condition of device compatible in convert_buswidth
function and other place to determine the device whether is for A64,
and then accept the 8 bytes bus width to it.
Signed-off-by: Hao Zhang <hao5781286@gmail.com>
---
drivers/dma/sun6i-dma.c | 43 +++++++++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 10 deletions(-)
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 8346199..8a95a1a 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -247,13 +247,17 @@ static inline s8 convert_burst(u32 maxburst)
}
}
-static inline s8 convert_buswidth(enum dma_slave_buswidth addr_width)
+static inline s8 convert_buswidth(enum dma_slave_buswidth addr_width,
+ struct sun6i_dma_dev *sdev)
{
- if ((addr_width < DMA_SLAVE_BUSWIDTH_1_BYTE) ||
- (addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
+ if (((addr_width >= DMA_SLAVE_BUSWIDTH_1_BYTE) &&
+ (addr_width <= DMA_SLAVE_BUSWIDTH_4_BYTES)) ||
+ ((addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES) &&
+ (of_device_is_compatible(sdev->slave.dev->of_node,
+ "allwinner,sun50i-a64-dma"))))
+ return addr_width >> 1;
+ else
return -EINVAL;
-
- return addr_width >> 1;
}
static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
@@ -508,19 +512,19 @@ static int set_config(struct sun6i_dma_dev *sdev,
src_width = convert_buswidth(sconfig->src_addr_width !=
DMA_SLAVE_BUSWIDTH_UNDEFINED ?
sconfig->src_addr_width :
- DMA_SLAVE_BUSWIDTH_4_BYTES);
+ DMA_SLAVE_BUSWIDTH_4_BYTES, sdev);
dst_burst = convert_burst(sconfig->dst_maxburst);
- dst_width = convert_buswidth(sconfig->dst_addr_width);
+ dst_width = convert_buswidth(sconfig->dst_addr_width, sdev);
break;
case DMA_DEV_TO_MEM:
src_burst = convert_burst(sconfig->src_maxburst);
- src_width = convert_buswidth(sconfig->src_addr_width);
+ src_width = convert_buswidth(sconfig->src_addr_width, sdev);
dst_burst = convert_burst(sconfig->dst_maxburst ?
sconfig->dst_maxburst : 8);
dst_width = convert_buswidth(sconfig->dst_addr_width !=
DMA_SLAVE_BUSWIDTH_UNDEFINED ?
sconfig->dst_addr_width :
- DMA_SLAVE_BUSWIDTH_4_BYTES);
+ DMA_SLAVE_BUSWIDTH_4_BYTES, sdev);
break;
default:
return -EINVAL;
@@ -577,7 +581,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
v_lli->para = NORMAL_WAIT;
burst = convert_burst(8);
- width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES, sdev);
v_lli->cfg |= DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
DMA_CHAN_CFG_DST_LINEAR_MODE |
@@ -1028,11 +1032,23 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = {
.nr_max_vchans = 34,
};
+/*
+ * The A64 has 8 physical channels, a maximum DRQ port id of 27,
+ * and a total of 38 usable source and destination endpoints.
+ */
+
+static struct sun6i_dma_config sun50i_a64_dma_cfg = {
+ .nr_max_channels = 8,
+ .nr_max_requests = 27,
+ .nr_max_vchans = 38,
+};
+
static const struct of_device_id sun6i_dma_match[] = {
{ .compatible = "allwinner,sun6i-a31-dma", .data = &sun6i_a31_dma_cfg },
{ .compatible = "allwinner,sun8i-a23-dma", .data = &sun8i_a23_dma_cfg },
{ .compatible = "allwinner,sun8i-a83t-dma", .data = &sun8i_a83t_dma_cfg },
{ .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg },
+ { .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sun6i_dma_match);
@@ -1112,6 +1128,13 @@ static int sun6i_dma_probe(struct platform_device *pdev)
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
sdc->slave.directions = BIT(DMA_DEV_TO_MEM) |
BIT(DMA_MEM_TO_DEV);
+
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "allwinner,sun50i-a64-dma")) {
+ sdc->slave.src_addr_widths |= BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
+ sdc->slave.dst_addr_widths |= BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
+ }
+
sdc->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
sdc->slave.dev = &pdev->dev;
--
2.7.4
^ permalink raw reply related
* [PATCH] arm/vdso: introduce vdso_mremap hook
From: Russell King - ARM Linux @ 2016-11-07 18:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161101172214.2938-1-dsafonov@virtuozzo.com>
On Tue, Nov 01, 2016 at 08:22:14PM +0300, Dmitry Safonov wrote:
> diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
> index 53cf86cf2d1a..d1001f87c2f6 100644
> --- a/arch/arm/kernel/vdso.c
> +++ b/arch/arm/kernel/vdso.c
> @@ -54,8 +54,11 @@ static const struct vm_special_mapping vdso_data_mapping = {
> .pages = &vdso_data_page,
> };
>
> +static int vdso_mremap(const struct vm_special_mapping *sm,
> + struct vm_area_struct *new_vma);
I'd much rather avoid this forward declaration. Is there any reason the
function body can't be here?
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH v2] iommu/arm-smmu: Fix out-of-bounds dereference
From: Robin Murphy @ 2016-11-07 18:25 UTC (permalink / raw)
To: linux-arm-kernel
When we iterate a master's config entries, what we generally care
about is the entry's stream map index, rather than the entry index
itself, so it's nice to have the iterator automatically assign the
former from the latter. Unfortunately, booting with KASAN reveals
the oversight that using a simple comma operator results in the
entry index being dereferenced before being checked for validity,
so we always access one element past the end of the fwspec array.
Flip things around so that the check always happens before the index
may be dereferenced.
Fixes: adfec2e709d2 ("iommu/arm-smmu: Convert to iommu_fwspec")
Reported-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/arm-smmu.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index f86683eec446..786d33900382 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -324,8 +324,10 @@ struct arm_smmu_master_cfg {
#define INVALID_SMENDX -1
#define __fwspec_cfg(fw) ((struct arm_smmu_master_cfg *)fw->iommu_priv)
#define fwspec_smmu(fw) (__fwspec_cfg(fw)->smmu)
+#define fwspec_smendx(fw, i) \
+ (i >= fw->num_ids ? INVALID_SMENDX : __fwspec_cfg(fw)->smendx[i])
#define for_each_cfg_sme(fw, i, idx) \
- for (i = 0; idx = __fwspec_cfg(fw)->smendx[i], i < fw->num_ids; ++i)
+ for (i = 0; idx = fwspec_smendx(fw, i), i < fw->num_ids; ++i)
struct arm_smmu_device {
struct device *dev;
--
2.10.2.dirty
^ permalink raw reply related
* [PATCH v7 2/2] ARM: EXYNOS: refactoring of mach-exynos to enable chipid driver
From: Krzysztof Kozlowski @ 2016-11-07 18:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478347427-28409-3-git-send-email-pankaj.dubey@samsung.com>
On Sat, Nov 05, 2016 at 05:33:47PM +0530, Pankaj Dubey wrote:
> This patch enables chipid driver for ARCH_EXYNOS and refactors
> machine code for using chipid driver for identification of
> SoC ID and SoC rev.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
> arch/arm/mach-exynos/Kconfig | 1 +
> arch/arm/mach-exynos/common.h | 92 ----------------------------
> arch/arm/mach-exynos/exynos.c | 31 ----------
> arch/arm/mach-exynos/firmware.c | 10 +--
> arch/arm/mach-exynos/include/mach/map.h | 21 -------
> arch/arm/mach-exynos/platsmp.c | 22 ++++---
> arch/arm/mach-exynos/pm.c | 41 ++++++++-----
> arch/arm/plat-samsung/cpu.c | 14 -----
> arch/arm/plat-samsung/include/plat/cpu.h | 2 -
> arch/arm/plat-samsung/include/plat/map-s5p.h | 2 -
> 10 files changed, 47 insertions(+), 189 deletions(-)
> delete mode 100644 arch/arm/mach-exynos/include/mach/map.h
>
> diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> index b085855..a76c679 100644
> --- a/arch/arm/mach-exynos/Kconfig
> +++ b/arch/arm/mach-exynos/Kconfig
> @@ -16,6 +16,7 @@ menuconfig ARCH_EXYNOS
> select ARM_AMBA
> select ARM_GIC
> select COMMON_CLK_SAMSUNG
> + select EXYNOS_CHIPID
> select EXYNOS_THERMAL
> select EXYNOS_PMU
> select EXYNOS_SROM
> diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
> index d19064b..9d76cf8 100644
> --- a/arch/arm/mach-exynos/common.h
> +++ b/arch/arm/mach-exynos/common.h
> @@ -14,97 +14,6 @@
>
> #include <linux/platform_data/cpuidle-exynos.h>
>
> -#define EXYNOS3250_SOC_ID 0xE3472000
> -#define EXYNOS3_SOC_MASK 0xFFFFF000
> -
> -#define EXYNOS4210_CPU_ID 0x43210000
> -#define EXYNOS4212_CPU_ID 0x43220000
> -#define EXYNOS4412_CPU_ID 0xE4412200
> -#define EXYNOS4_CPU_MASK 0xFFFE0000
> -
> -#define EXYNOS5250_SOC_ID 0x43520000
> -#define EXYNOS5410_SOC_ID 0xE5410000
> -#define EXYNOS5420_SOC_ID 0xE5420000
> -#define EXYNOS5440_SOC_ID 0xE5440000
> -#define EXYNOS5800_SOC_ID 0xE5422000
> -#define EXYNOS5_SOC_MASK 0xFFFFF000
> -
> -extern unsigned long samsung_cpu_id;
> -
> -#define IS_SAMSUNG_CPU(name, id, mask) \
> -static inline int is_samsung_##name(void) \
> -{ \
> - return ((samsung_cpu_id & mask) == (id & mask)); \
> -}
> -
> -IS_SAMSUNG_CPU(exynos3250, EXYNOS3250_SOC_ID, EXYNOS3_SOC_MASK)
> -IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS4_CPU_MASK)
> -IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK)
> -IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
> -IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
> -IS_SAMSUNG_CPU(exynos5410, EXYNOS5410_SOC_ID, EXYNOS5_SOC_MASK)
> -IS_SAMSUNG_CPU(exynos5420, EXYNOS5420_SOC_ID, EXYNOS5_SOC_MASK)
> -IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
> -IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
> -
> -#if defined(CONFIG_SOC_EXYNOS3250)
> -# define soc_is_exynos3250() is_samsung_exynos3250()
> -#else
> -# define soc_is_exynos3250() 0
> -#endif
> -
> -#if defined(CONFIG_CPU_EXYNOS4210)
> -# define soc_is_exynos4210() is_samsung_exynos4210()
> -#else
> -# define soc_is_exynos4210() 0
> -#endif
> -
> -#if defined(CONFIG_SOC_EXYNOS4212)
> -# define soc_is_exynos4212() is_samsung_exynos4212()
> -#else
> -# define soc_is_exynos4212() 0
> -#endif
> -
> -#if defined(CONFIG_SOC_EXYNOS4412)
> -# define soc_is_exynos4412() is_samsung_exynos4412()
> -#else
> -# define soc_is_exynos4412() 0
> -#endif
> -
> -#define EXYNOS4210_REV_0 (0x0)
> -#define EXYNOS4210_REV_1_0 (0x10)
> -#define EXYNOS4210_REV_1_1 (0x11)
> -
> -#if defined(CONFIG_SOC_EXYNOS5250)
> -# define soc_is_exynos5250() is_samsung_exynos5250()
> -#else
> -# define soc_is_exynos5250() 0
> -#endif
> -
> -#if defined(CONFIG_SOC_EXYNOS5410)
> -# define soc_is_exynos5410() is_samsung_exynos5410()
> -#else
> -# define soc_is_exynos5410() 0
> -#endif
> -
> -#if defined(CONFIG_SOC_EXYNOS5420)
> -# define soc_is_exynos5420() is_samsung_exynos5420()
> -#else
> -# define soc_is_exynos5420() 0
> -#endif
> -
> -#if defined(CONFIG_SOC_EXYNOS5440)
> -# define soc_is_exynos5440() is_samsung_exynos5440()
> -#else
> -# define soc_is_exynos5440() 0
> -#endif
> -
> -#if defined(CONFIG_SOC_EXYNOS5800)
> -# define soc_is_exynos5800() is_samsung_exynos5800()
> -#else
> -# define soc_is_exynos5800() 0
> -#endif
> -
> extern u32 cp15_save_diag;
> extern u32 cp15_save_power;
>
> @@ -161,7 +70,6 @@ extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
>
> extern void exynos_set_delayed_reset_assertion(bool enable);
>
> -extern unsigned int samsung_rev(void);
> extern void exynos_core_restart(u32 core_id);
> extern int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr);
> extern int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr);
> diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
> index fa08ef9..942131e 100644
> --- a/arch/arm/mach-exynos/exynos.c
> +++ b/arch/arm/mach-exynos/exynos.c
> @@ -23,9 +23,6 @@
> #include <asm/mach/arch.h>
> #include <asm/mach/map.h>
>
> -#include <mach/map.h>
> -#include <plat/cpu.h>
> -
> #include "common.h"
>
> static struct platform_device exynos_cpuidle = {
> @@ -67,37 +64,9 @@ static void __init exynos_init_late(void)
> exynos_pm_init();
> }
>
> -static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
> - int depth, void *data)
> -{
> - struct map_desc iodesc;
> - const __be32 *reg;
> - int len;
> -
> - if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
> - !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
> - return 0;
> -
> - reg = of_get_flat_dt_prop(node, "reg", &len);
> - if (reg == NULL || len != (sizeof(unsigned long) * 2))
> - return 0;
> -
> - iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
> - iodesc.length = be32_to_cpu(reg[1]) - 1;
> - iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
> - iodesc.type = MT_DEVICE;
> - iotable_init(&iodesc, 1);
> - return 1;
> -}
> -
> static void __init exynos_init_io(void)
> {
> debug_ll_io_init();
> -
> - of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
> -
> - /* detect cpu id and rev. */
> - s5p_init_cpu(S5P_VA_CHIPID);
> }
>
> /*
> diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
> index fd6da54..a9f8504e 100644
> --- a/arch/arm/mach-exynos/firmware.c
> +++ b/arch/arm/mach-exynos/firmware.c
> @@ -44,7 +44,7 @@ static int exynos_do_idle(unsigned long mode)
> writel_relaxed(virt_to_phys(exynos_cpu_resume_ns),
> sysram_ns_base_addr + 0x24);
> writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
> - if (soc_is_exynos3250()) {
> + if (of_machine_is_compatible("samsung,exynos3250")) {
> flush_cache_all();
> exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
> SMC_POWERSTATE_IDLE, 0);
> @@ -65,7 +65,7 @@ static int exynos_cpu_boot(int cpu)
> * Exynos3250 doesn't need to send smc command for secondary CPU boot
> * because Exynos3250 removes WFE in secure mode.
> */
> - if (soc_is_exynos3250())
> + if (of_machine_is_compatible("samsung,exynos3250"))
> return 0;
>
> /*
> @@ -73,7 +73,7 @@ static int exynos_cpu_boot(int cpu)
> * But, Exynos4212 has only one secondary CPU so second parameter
> * isn't used for informing secure firmware about CPU id.
> */
> - if (soc_is_exynos4212())
> + if (of_machine_is_compatible("samsung,exynos4212"))
> cpu = 0;
>
> exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
> @@ -94,7 +94,7 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
> * additional offset for every CPU, with Exynos4412 being the only
> * exception.
> */
> - if (soc_is_exynos4412())
> + if (of_machine_is_compatible("samsung,exynos4412"))
> boot_reg += 4 * cpu;
>
> writel_relaxed(boot_addr, boot_reg);
> @@ -110,7 +110,7 @@ static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
>
> boot_reg = sysram_ns_base_addr + 0x1c;
>
> - if (soc_is_exynos4412())
> + if (of_machine_is_compatible("samsung,exynos4412"))
> boot_reg += 4 * cpu;
>
> *boot_addr = readl_relaxed(boot_reg);
> diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
> deleted file mode 100644
> index 0eef407..0000000
> --- a/arch/arm/mach-exynos/include/mach/map.h
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -/*
> - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
> - * http://www.samsung.com/
> - *
> - * EXYNOS - Memory map definitions
> - *
> - * 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.
> -*/
> -
> -#ifndef __ASM_ARCH_MAP_H
> -#define __ASM_ARCH_MAP_H __FILE__
> -
> -#include <plat/map-base.h>
> -
> -#include <plat/map-s5p.h>
> -
> -#define EXYNOS_PA_CHIPID 0x10000000
> -
> -#endif /* __ASM_ARCH_MAP_H */
> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
> index 553d0d9..884e885 100644
> --- a/arch/arm/mach-exynos/platsmp.c
> +++ b/arch/arm/mach-exynos/platsmp.c
> @@ -19,6 +19,7 @@
> #include <linux/smp.h>
> #include <linux/io.h>
> #include <linux/of_address.h>
> +#include <linux/sys_soc.h>
> #include <linux/soc/samsung/exynos-regs-pmu.h>
>
> #include <asm/cacheflush.h>
> @@ -27,8 +28,6 @@
> #include <asm/smp_scu.h>
> #include <asm/firmware.h>
>
> -#include <mach/map.h>
> -
> #include "common.h"
>
> extern void exynos4_secondary_startup(void);
> @@ -93,7 +92,8 @@ void exynos_cpu_power_down(int cpu)
> {
> u32 core_conf;
>
> - if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) {
> + if (cpu == 0 && (of_machine_is_compatible("samsung,exynos5420") ||
> + of_machine_is_compatible("samsung,exynos5800"))) {
NACK
Please see:
ca489c58ef0b ("ARM: EXYNOS: Don't use LDREX and STREX after disabling
cache coherency")
Such cases has to be fixed in different way...
> /*
> * Bypass power down for CPU0 during suspend. Check for
> * the SYS_PWR_REG value to decide if we are suspending
> @@ -120,7 +120,7 @@ void exynos_cpu_power_up(int cpu)
> {
> u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
>
> - if (soc_is_exynos3250())
> + if (of_machine_is_compatible("samsung,exynos3250"))
> core_conf |= S5P_CORE_AUTOWAKEUP_EN;
>
> pmu_raw_writel(core_conf,
> @@ -168,9 +168,14 @@ int exynos_cluster_power_state(int cluster)
> S5P_CORE_LOCAL_PWR_EN);
> }
>
> +static struct soc_device_attribute exynos4210_rev11[] = {
> + { .soc_id = "EXYNOS4210", .revision = "11", },
> + { },
> +};
> +
> static void __iomem *cpu_boot_reg_base(void)
> {
> - if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
> + if (soc_device_match(exynos4210_rev11))
> return pmu_base_addr + S5P_INFORM5;
> return sysram_base_addr;
> }
> @@ -182,9 +187,10 @@ static inline void __iomem *cpu_boot_reg(int cpu)
> boot_reg = cpu_boot_reg_base();
> if (!boot_reg)
> return IOMEM_ERR_PTR(-ENODEV);
> - if (soc_is_exynos4412())
> + if (of_machine_is_compatible("samsung,exynos4412"))
> boot_reg += 4*cpu;
> - else if (soc_is_exynos5420() || soc_is_exynos5800())
> + else if (of_machine_is_compatible("samsung,exynos5420") ||
> + of_machine_is_compatible("samsung,exynos5800"))
> boot_reg += 4;
> return boot_reg;
> }
> @@ -356,7 +362,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>
> call_firmware_op(cpu_boot, core_id);
>
> - if (soc_is_exynos3250())
> + if (of_machine_is_compatible("samsung,exynos3250"))
> dsb_sev();
> else
> arch_send_wakeup_ipi_mask(cpumask_of(cpu));
> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
> index 60e6827..430b3e2 100644
> --- a/arch/arm/mach-exynos/pm.c
> +++ b/arch/arm/mach-exynos/pm.c
> @@ -19,6 +19,7 @@
> #include <linux/io.h>
> #include <linux/of.h>
> #include <linux/of_address.h>
> +#include <linux/sys_soc.h>
> #include <linux/soc/samsung/exynos-regs-pmu.h>
> #include <linux/soc/samsung/exynos-pmu.h>
>
> @@ -29,20 +30,30 @@
>
> #include "common.h"
>
> +static struct soc_device_attribute exynos4210_rev11[] = {
> + { .soc_id = "EXYNOS4210", .revision = "11", },
> + { },
> +};
This (and all others) look like static const.
> +
> +static struct soc_device_attribute exynos4210_rev10[] = {
> + { .soc_id = "EXYNOS4210", .revision = "10", },
> + { },
> +};
> +
> static inline void __iomem *exynos_boot_vector_addr(void)
> {
> - if (samsung_rev() == EXYNOS4210_REV_1_1)
> + if (soc_device_match(exynos4210_rev11))
> return pmu_base_addr + S5P_INFORM7;
> - else if (samsung_rev() == EXYNOS4210_REV_1_0)
> + else if (soc_device_match(exynos4210_rev10))
> return sysram_base_addr + 0x24;
> return pmu_base_addr + S5P_INFORM0;
> }
>
> static inline void __iomem *exynos_boot_vector_flag(void)
> {
> - if (samsung_rev() == EXYNOS4210_REV_1_1)
> + if (soc_device_match(exynos4210_rev11))
> return pmu_base_addr + S5P_INFORM6;
> - else if (samsung_rev() == EXYNOS4210_REV_1_0)
> + else if (soc_device_match(exynos4210_rev10))
> return sysram_base_addr + 0x20;
> return pmu_base_addr + S5P_INFORM1;
> }
> @@ -122,11 +133,13 @@ int exynos_pm_central_resume(void)
> }
>
> /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
> -static void exynos_set_wakeupmask(long mask)
> +static void exynos_set_wakeupmask(void)
> {
> - pmu_raw_writel(mask, S5P_WAKEUP_MASK);
> - if (soc_is_exynos3250())
> + if (of_machine_is_compatible("samsung,exynos3250")) {
> + pmu_raw_writel(0x40003ffe, S5P_WAKEUP_MASK);
> pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
> + } else
> + pmu_raw_writel(0x0000ff3e, S5P_WAKEUP_MASK);
> }
>
> static void exynos_cpu_set_boot_vector(long flags)
> @@ -140,7 +153,7 @@ static int exynos_aftr_finisher(unsigned long flags)
> {
> int ret;
>
> - exynos_set_wakeupmask(soc_is_exynos3250() ? 0x40003ffe : 0x0000ff3e);
> + exynos_set_wakeupmask();
> /* Set value of power down register for aftr mode */
> exynos_sys_powerdown_conf(SYS_AFTR);
>
> @@ -163,7 +176,7 @@ void exynos_enter_aftr(void)
>
> cpu_pm_enter();
>
> - if (soc_is_exynos3250())
> + if (of_machine_is_compatible("samsung,exynos3250"))
> exynos_set_boot_flag(cpuid, C2_STATE);
>
> exynos_pm_central_suspend();
> @@ -192,7 +205,7 @@ void exynos_enter_aftr(void)
>
> exynos_pm_central_resume();
>
> - if (soc_is_exynos3250())
> + if (of_machine_is_compatible("samsung,exynos3250"))
> exynos_clear_boot_flag(cpuid, C2_STATE);
>
> cpu_pm_exit();
> @@ -263,7 +276,7 @@ abort:
> while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN)
> cpu_relax();
>
> - if (soc_is_exynos3250()) {
> + if (of_machine_is_compatible("samsung,exynos3250")) {
> while (!pmu_raw_readl(S5P_PMU_SPARE2) &&
> !atomic_read(&cpu1_wakeup))
> cpu_relax();
> @@ -285,7 +298,7 @@ abort:
>
> call_firmware_op(cpu_boot, 1);
>
> - if (soc_is_exynos3250())
> + if (of_machine_is_compatible("samsung,exynos3250"))
> dsb_sev();
> else
> arch_send_wakeup_ipi_mask(cpumask_of(1));
> @@ -297,7 +310,7 @@ fail:
>
> static int exynos_wfi_finisher(unsigned long flags)
> {
> - if (soc_is_exynos3250())
> + if (of_machine_is_compatible("samsung,exynos3250"))
> flush_cache_all();
> cpu_do_idle();
>
> @@ -319,7 +332,7 @@ static int exynos_cpu1_powerdown(void)
> */
> exynos_cpu_power_down(1);
>
> - if (soc_is_exynos3250())
> + if (of_machine_is_compatible("samsung,exynos3250"))
> pmu_raw_writel(0, S5P_PMU_SPARE2);
>
> ret = cpu_suspend(0, exynos_wfi_finisher);
> diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
> index a107b3a..e58f0f6 100644
> --- a/arch/arm/plat-samsung/cpu.c
> +++ b/arch/arm/plat-samsung/cpu.c
> @@ -21,12 +21,6 @@
> unsigned long samsung_cpu_id;
> static unsigned int samsung_cpu_rev;
>
> -unsigned int samsung_rev(void)
> -{
> - return samsung_cpu_rev;
> -}
> -EXPORT_SYMBOL(samsung_rev);
> -
> void __init s3c64xx_init_cpu(void)
> {
> samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0x118);
> @@ -43,11 +37,3 @@ void __init s3c64xx_init_cpu(void)
>
> pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
> }
> -
> -void __init s5p_init_cpu(const void __iomem *cpuid_addr)
> -{
> - samsung_cpu_id = readl_relaxed(cpuid_addr);
> - samsung_cpu_rev = samsung_cpu_id & 0xFF;
> -
> - pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
Actually I kind of liked the CPU ID. :) You won't find this in
cpuinfo... How about leaving this for debug purposes?
Best regards,
Krzysztof
> -}
> diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
> index b7b702a..913c176 100644
> --- a/arch/arm/plat-samsung/include/plat/cpu.h
> +++ b/arch/arm/plat-samsung/include/plat/cpu.h
> @@ -115,8 +115,6 @@ extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
> extern void s3c64xx_init_cpu(void);
> extern void s5p_init_cpu(const void __iomem *cpuid_addr);
>
> -extern unsigned int samsung_rev(void);
> -
> extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
>
> extern void s3c24xx_init_clocks(int xtal);
> diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h
> index 512ed1f..d6853f1 100644
> --- a/arch/arm/plat-samsung/include/plat/map-s5p.h
> +++ b/arch/arm/plat-samsung/include/plat/map-s5p.h
> @@ -13,8 +13,6 @@
> #ifndef __ASM_PLAT_MAP_S5P_H
> #define __ASM_PLAT_MAP_S5P_H __FILE__
>
> -#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
> -
> #define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
> #define VA_VIC0 VA_VIC(0)
> #define VA_VIC1 VA_VIC(1)
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v3 2/3] ARM64: dts: sun6i: add dma node for a64.
From: Hao Zhang @ 2016-11-07 18:22 UTC (permalink / raw)
To: linux-arm-kernel
This adds the dma node for sun50i a64.
Signed-off-by: Hao Zhang <hao5781286@gmail.com>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index e3c3d7d8..855ae2c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -227,6 +227,15 @@
};
};
+ dma: dma-controller at 01c02000 {
+ compatible = "allwinner,sun50i-a64-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_DMA>;
+ resets = <&ccu RST_BUS_DMA>;
+ #dma-cells = <1>;
+ };
+
uart0: serial at 1c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
--
2.7.4
^ permalink raw reply related
* [PATCH v11 14/14] dmaengine: st_fdma: Update st_fdma to 'depends on REMOTEPROC'.
From: Peter Griffin @ 2016-11-07 18:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478542665-17089-1-git-send-email-peter.griffin@linaro.org>
During randconfig builds you can get the following warning
"warning: (ST_FDMA) selects ST_SLIM_REMOTEPROC which has unmet direct
dependencies (REMOTEPROC)"
randconfig builds should always build without any warnings so
update fdma to depend on REMOTEPROC so this can not happen.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Reported-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/dma/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 661f217..6b96710 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -438,6 +438,7 @@ config STE_DMA40
config ST_FDMA
tristate "ST FDMA dmaengine support"
depends on ARCH_STI
+ depends on REMOTEPROC
select ST_SLIM_REMOTEPROC
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox