* [PATCH v2 19/21] pinctrl: mvebu: dove: use remapped pmu_mpp registers
From: Sebastian Hesselbarth @ 2014-01-28 0:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390869573-27624-1-git-send-email-sebastian.hesselbarth@gmail.com>
Now that we have ioremapped pmu_mpp registers, get rid of hardcoded
physical addresses. While at it, also remove DOVE_ prefix from those
macros. Also use common defines for MPP shift and masks and reuse
generic get/set callbacks from pmu specific get/set.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Gregory Clement <gregory.clement@free-electrons.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
drivers/pinctrl/mvebu/pinctrl-dove.c | 59 +++++++++++++++++-------------------
1 file changed, 28 insertions(+), 31 deletions(-)
diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
index 1487bd270401..9126cedec1bc 100644
--- a/drivers/pinctrl/mvebu/pinctrl-dove.c
+++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
@@ -31,8 +31,6 @@
#define GC_REGS_OFFS 0xe802c
#define DOVE_SB_REGS_VIRT_BASE IOMEM(0xfde00000)
-#define DOVE_PMU_SIGNAL_SELECT_0 (DOVE_SB_REGS_VIRT_BASE + 0xd802C)
-#define DOVE_PMU_SIGNAL_SELECT_1 (DOVE_SB_REGS_VIRT_BASE + 0xd8030)
#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C)
#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C)
#define DOVE_TWSI_ENABLE_OPTION1 BIT(7)
@@ -60,9 +58,9 @@
#define SD1_GPIO_SEL BIT(1)
#define SD0_GPIO_SEL BIT(0)
-#define MPPS_PER_REG 8
-#define MPP_BITS 4
-#define MPP_MASK 0xf
+/* PMU Signal Select registers */
+#define PMU_SIGNAL_SELECT_0 0x00
+#define PMU_SIGNAL_SELECT_1 0x04
#define CONFIG_PMU BIT(4)
@@ -98,46 +96,45 @@ static int dove_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
{
- unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
- unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
+ unsigned off = (ctrl->pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+ unsigned shift = (ctrl->pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
- unsigned long func;
if (pmu & (1 << ctrl->pid)) {
- func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
- *config = (func >> shift) & MPP_MASK;
+ unsigned long func =
+ readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
+ *config = (func >> shift) & MVEBU_MPP_MASK;
*config |= CONFIG_PMU;
- } else {
- func = readl(mpp_base + off);
- *config = (func >> shift) & MPP_MASK;
+
+ return 0;
}
- return 0;
+
+ return dove_mpp_ctrl_get(ctrl, config);
}
static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
{
- unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
- unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
+ unsigned off = (ctrl->pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+ unsigned shift = (ctrl->pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
- unsigned long func;
+
+ if (config & CONFIG_PMU)
+ pmu |= (1 << ctrl->pid);
+ else
+ pmu &= ~(1 << ctrl->pid);
if (config & CONFIG_PMU) {
- writel(pmu | (1 << ctrl->pid),
- mpp_base + PMU_MPP_GENERAL_CTRL);
- func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
- func &= ~(MPP_MASK << shift);
- func |= (config & MPP_MASK) << shift;
- writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off);
- } else {
- writel(pmu & ~(1 << ctrl->pid),
- mpp_base + PMU_MPP_GENERAL_CTRL);
- func = readl(mpp_base + off);
- func &= ~(MPP_MASK << shift);
- func |= (config & MPP_MASK) << shift;
- writel(func, mpp_base + off);
+ unsigned long func =
+ readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
+ func &= ~(MVEBU_MPP_MASK << shift);
+ func |= (config & MVEBU_MPP_MASK) << shift;
+ writel(func, pmu_base + PMU_SIGNAL_SELECT_0 + off);
+
+ return 0;
}
- return 0;
+
+ return dove_mpp_ctrl_set(ctrl, config);
}
static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
--
1.8.5.2
^ permalink raw reply related
* [PATCH v2 20/21] pinctrl: mvebu: dove: use global register regmap
From: Sebastian Hesselbarth @ 2014-01-28 0:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390869573-27624-1-git-send-email-sebastian.hesselbarth@gmail.com>
Now that we have a regmap for global registers, get rid of the last
remaining hardcoded physical addresses. While at it, also remove
DOVE_ prefix from those macros.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Gregory Clement <gregory.clement@free-electrons.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
drivers/pinctrl/mvebu/pinctrl-dove.c | 128 ++++++++++++++++-------------------
1 file changed, 60 insertions(+), 68 deletions(-)
diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
index 9126cedec1bc..1823a1a7ec45 100644
--- a/drivers/pinctrl/mvebu/pinctrl-dove.c
+++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
@@ -30,21 +30,6 @@
#define PMU_REGS_OFFS 0xd802c
#define GC_REGS_OFFS 0xe802c
-#define DOVE_SB_REGS_VIRT_BASE IOMEM(0xfde00000)
-#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C)
-#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C)
-#define DOVE_TWSI_ENABLE_OPTION1 BIT(7)
-#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE + 0xe8030)
-#define DOVE_TWSI_ENABLE_OPTION2 BIT(20)
-#define DOVE_TWSI_ENABLE_OPTION3 BIT(21)
-#define DOVE_TWSI_OPTION3_GPIO BIT(22)
-#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE + 0xe8034)
-#define DOVE_SSP_ON_AU1 BIT(0)
-#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xe803c)
-#define DOVE_AU1_SPDIFO_GPIO_EN BIT(1)
-#define DOVE_NAND_GPIO_EN BIT(0)
-#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0400)
-
/* MPP Base registers */
#define PMU_MPP_GENERAL_CTRL 0x10
#define AU0_AC97_SEL BIT(16)
@@ -62,6 +47,19 @@
#define PMU_SIGNAL_SELECT_0 0x00
#define PMU_SIGNAL_SELECT_1 0x04
+/* Global Config regmap registers */
+#define GLOBAL_CONFIG_1 0
+#define TWSI_ENABLE_OPTION1 BIT(7)
+#define GLOBAL_CONFIG_2 1
+#define TWSI_ENABLE_OPTION2 BIT(20)
+#define TWSI_ENABLE_OPTION3 BIT(21)
+#define TWSI_OPTION3_GPIO BIT(22)
+#define SSP_CTRL_STATUS_1 2
+#define SSP_ON_AU1 BIT(0)
+#define MPP_GENERAL_CONFIG 4
+#define AU1_SPDIFO_GPIO_EN BIT(1)
+#define NAND_GPIO_EN BIT(0)
+
#define CONFIG_PMU BIT(4)
static void __iomem *mpp_base;
@@ -206,9 +204,10 @@ static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
{
- unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+ unsigned int gmpp;
- *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0);
+ regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
+ *config = ((gmpp & NAND_GPIO_EN) != 0);
return 0;
}
@@ -216,14 +215,9 @@ static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
{
- unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
-
- gmpp &= ~DOVE_NAND_GPIO_EN;
- if (config)
- gmpp |= DOVE_NAND_GPIO_EN;
-
- writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
-
+ regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
+ NAND_GPIO_EN,
+ (config) ? NAND_GPIO_EN : 0);
return 0;
}
@@ -253,19 +247,23 @@ static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
{
- unsigned long mpp4 = readl(mpp4_base + MPP_CTRL4);
- unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
- unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
- unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+ unsigned int mpp4 = readl(mpp4_base + MPP_CTRL4);
+ unsigned int sspc1;
+ unsigned int gmpp;
+ unsigned int gcfg2;
+
+ regmap_read(gconfmap, SSP_CTRL_STATUS_1, &sspc1);
+ regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
+ regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
*config = 0;
if (mpp4 & AU1_GPIO_SEL)
*config |= BIT(3);
- if (sspc1 & DOVE_SSP_ON_AU1)
+ if (sspc1 & SSP_ON_AU1)
*config |= BIT(2);
- if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN)
+ if (gmpp & AU1_SPDIFO_GPIO_EN)
*config |= BIT(1);
- if (gcfg2 & DOVE_TWSI_OPTION3_GPIO)
+ if (gcfg2 & TWSI_OPTION3_GPIO)
*config |= BIT(0);
/* SSP/TWSI only if I2S1 not set*/
@@ -280,32 +278,22 @@ static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
{
- unsigned long mpp4 = readl(mpp4_base + MPP_CTRL4);
- unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
- unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
- unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+ unsigned int mpp4 = readl(mpp4_base + MPP_CTRL4);
- /*
- * clear all audio1 related bits before configure
- */
- gcfg2 &= ~DOVE_TWSI_OPTION3_GPIO;
- gmpp &= ~DOVE_AU1_SPDIFO_GPIO_EN;
- sspc1 &= ~DOVE_SSP_ON_AU1;
mpp4 &= ~AU1_GPIO_SEL;
-
- if (config & BIT(0))
- gcfg2 |= DOVE_TWSI_OPTION3_GPIO;
- if (config & BIT(1))
- gmpp |= DOVE_AU1_SPDIFO_GPIO_EN;
- if (config & BIT(2))
- sspc1 |= DOVE_SSP_ON_AU1;
if (config & BIT(3))
mpp4 |= AU1_GPIO_SEL;
-
writel(mpp4, mpp4_base + MPP_CTRL4);
- writel(sspc1, DOVE_SSP_CTRL_STATUS_1);
- writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
- writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
+
+ regmap_update_bits(gconfmap, SSP_CTRL_STATUS_1,
+ SSP_ON_AU1,
+ (config & BIT(2)) ? SSP_ON_AU1 : 0);
+ regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
+ AU1_SPDIFO_GPIO_EN,
+ (config & BIT(1)) ? AU1_SPDIFO_GPIO_EN : 0);
+ regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
+ TWSI_OPTION3_GPIO,
+ (config & BIT(0)) ? TWSI_OPTION3_GPIO : 0);
return 0;
}
@@ -353,15 +341,18 @@ static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid,
static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
unsigned long *config)
{
- unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
- unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+ unsigned int gcfg1;
+ unsigned int gcfg2;
+
+ regmap_read(gconfmap, GLOBAL_CONFIG_1, &gcfg1);
+ regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
*config = 0;
- if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1)
+ if (gcfg1 & TWSI_ENABLE_OPTION1)
*config = 1;
- else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2)
+ else if (gcfg2 & TWSI_ENABLE_OPTION2)
*config = 2;
- else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3)
+ else if (gcfg2 & TWSI_ENABLE_OPTION3)
*config = 3;
return 0;
@@ -370,26 +361,27 @@ static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
unsigned long config)
{
- unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
- unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
-
- gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1;
- gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION3);
+ unsigned int gcfg1 = 0;
+ unsigned int gcfg2 = 0;
switch (config) {
case 1:
- gcfg1 |= DOVE_TWSI_ENABLE_OPTION1;
+ gcfg1 = TWSI_ENABLE_OPTION1;
break;
case 2:
- gcfg2 |= DOVE_TWSI_ENABLE_OPTION2;
+ gcfg2 = TWSI_ENABLE_OPTION2;
break;
case 3:
- gcfg2 |= DOVE_TWSI_ENABLE_OPTION3;
+ gcfg2 = TWSI_ENABLE_OPTION3;
break;
}
- writel(gcfg1, DOVE_GLOBAL_CONFIG_1);
- writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
+ regmap_update_bits(gconfmap, GLOBAL_CONFIG_1,
+ TWSI_ENABLE_OPTION1,
+ gcfg1);
+ regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
+ TWSI_ENABLE_OPTION2 | TWSI_ENABLE_OPTION3,
+ gcfg2);
return 0;
}
--
1.8.5.2
^ permalink raw reply related
* [PATCH v2 21/21] pinctrl: mvebu: dove: consolidate auto-numbered pmu mpp ranges
From: Sebastian Hesselbarth @ 2014-01-28 0:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390869573-27624-1-git-send-email-sebastian.hesselbarth@gmail.com>
Passing a NULL name for pin ranges will auto-generate standard names
for each pin. With common pinctrl driver now checking NULL name correctly,
consolidate mpp pins 0-15.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Gregory Clement <gregory.clement@free-electrons.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
drivers/pinctrl/mvebu/pinctrl-dove.c | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
index 1823a1a7ec45..3bfea6ccb39d 100644
--- a/drivers/pinctrl/mvebu/pinctrl-dove.c
+++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
@@ -387,22 +387,7 @@ static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
}
static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
- MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl),
- MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl),
MPP_FUNC_CTRL(16, 23, NULL, dove_mpp_ctrl),
MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
--
1.8.5.2
^ permalink raw reply related
* [RFC PATCH V2 1/4] pci: APM X-Gene PCIe controller driver
From: Bjorn Helgaas @ 2014-01-28 0:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5086198.ZOWZ5xuyna@wuerfel>
We're only seeing Arnd's side of the conversation on linux-pci.
Tanmay, are your messages being rejected because they're too "fancy",
per the definition here: http://vger.kernel.org/majordomo-info.html ?
On Sat, Jan 25, 2014 at 1:11 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 24 January 2014 13:28:22 Tanmay Inamdar wrote:
>> On Thu, Jan 16, 2014 at 5:10 PM, Tanmay Inamdar <tinamdar@apm.com> wrote:
>> > On Wed, Jan 15, 2014 at 4:39 AM, Arnd Bergmann <arnd@arndb.de> wrote:
>> >> On Wednesday 15 January 2014, Tanmay Inamdar wrote:
>
>> >>
>> >>> +static void xgene_pcie_poll_linkup(struct xgene_pcie_port *port, u32 *lanes)
>> >>> +{
>> >>> + void *csr_base = port->csr_base;
>> >>> + u32 val32;
>> >>> + u64 start_time, time;
>> >>> +
>> >>> + /*
>> >>> + * A component enters the LTSSM Detect state within
>> >>> + * 20ms of the end of fundamental core reset.
>> >>> + */
>> >>> + msleep(XGENE_LTSSM_DETECT_WAIT);
>> >>> + port->link_up = 0;
>> >>> + start_time = jiffies;
>> >>> + do {
>> >>> + val32 = readl(csr_base + PCIECORE_CTLANDSTATUS);
>> >>> + if (val32 & LINK_UP_MASK) {
>> >>> + port->link_up = 1;
>> >>> + port->link_speed = PIPE_PHY_RATE_RD(val32);
>> >>> + val32 = readl(csr_base + BRIDGE_STATUS_0);
>> >>> + *lanes = val32 >> 26;
>> >>> + }
>> >>> + time = jiffies_to_msecs(jiffies - start_time);
>> >>> + } while ((!port->link_up) || (time <= XGENE_LTSSM_L0_WAIT));
>> >>> +}
>> >>
>> >> Maybe another msleep() in the loop? It seems weird to first do an
>> >> unconditional sleep but then busy-wait for the result.
>> >
>> > ok.
>>
>> This loop can execute for maximum 4 msec. So putting msleep(1) won't
>> get us much.
>
> 4 msec is still quite a long time for a busy loop that can be spent doing
> useful work in another thread.
>
>> >>
>> >> Another general note: Your "compatible" strings are rather unspecific.
>> >> Do you have a version number for this IP block? I suppose that it's related
>> >> to one that has been used in other chips before, or will be used in future
>> >> chips, if it's not actually licensed from some other company.
>> >
>> > I will have to check this.
>> >
>>
>> We have decided to stick with current compatible string for now.
>
> Can you elaborate on your reasoning? Does this mean X-Gene is a one-off
> product and you won't be doing any new chips based on the same hardware
> components?
>
> Arnd
^ permalink raw reply
* [PATCH V2 0/4] misc: xgene: Add support for APM X-Gene SoC Queue Manager/Traffic Manager
From: Ravi Patel @ 2014-01-28 0:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201401141615.55820.arnd@arndb.de>
On Tue, Jan 14, 2014 at 7:15 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> Now that I have a better understanding of what the driver is good for and
> how it's used, let's have a look at how we can make it fit into the Linux
> driver APIs and the DT bindings. We don't have anything exactly like this
> yet, but I think the "mailbox" framework is a close enough match that we
> can fit it in there, with some extensions. This framework is still in the
> process of being created (so far there is only a TI OMAP specific driver,
> and one for pl320), and I've not seen any mailboxes that support IRQ
> mitigation or multiple software interfaces per hardware mailbox, but those
> should be easy enough to add.
OK. We will put Queue Manager driver under drivers/mailbox directory along
with TI OMAP and pl320 drivers.
> For the DT binding, I would suggest using something along the lines of
> what we have for clocks, pinctrl and dmaengine. OMAP doesn't use this
> (yet), but now would be a good time to standardize it. The QMTM node
> should define a "#mailbox-cells" property that indicates how many
> 32-bit cells a qmtm needs to describe the connection between the
> controller and the slave. My best guess is that this would be hardcoded
> to <3>, using two cells for a 64-bit FIFO bus address, and a 32-bit cell
> for the slave-id signal number. All other parameters that you have in
> the big table in the qmtm driver at the moment can then get moved into
> the slave drivers, as they are constant per type of slave. This will
> simplify the QMTM driver.
>
> In the slave, you should have a "mailboxes" property with a phandle
> to the qmtm followed by the three cells to identify the actual
> queue. If it's possible that a device uses more than one rx and
> one tx queue, we also need a "mailbox-names" property to identify
> the individual queues.
We explored on DT bindings suggestion given by you. We have come
up with a sample DT binding for how it will look like. Herewith we have
provided the same. Would you please review and give us your
comments before we change our driver and DTS file to accomodate it?
Sample DTS node for QM:
qmlite: qmtm at 17030000 {
compatible = "apm,xgene-qmtm-lite";
reg = <0x0 0x17030000 0x0 0x10000>,
<0x0 0x10000000 0x0 0x400000>;
interrupts = <0x0 0x40 0x4>,
<0x0 0x3c 0x4>;
status = "ok";
#clock-cells = <1>;
clocks = <&qmlclk 0>;
#mailbox-cells = <3>;
};
Sample DTS node for Ethernet:
menet: ethernet at 17020000 {
compatible = "apm,xgene-enet";
status = "disabled";
reg = <0x0 0x17020000 0x0 0x30>,
<0x0 0x17020000 0x0 0x10000>,
<0x0 0x17020000 0x0 0x20>;
mailboxes = <&qmlite 0x0 0x1000002c 0x0000>,
<&qmlite 0x0 0x10000052 0x0020>,
<&qmlite 0x0 0x10000060 0x0f00>
mailbox-names = "mb-tx", "mb-fp", "mb-rx";
interrupts = <0x0 0x38 0x4>,
<0x0 0x39 0x4>,
<0x0 0x3a 0x4>;
#clock-cells = <1>;
clocks = <ð8clk 0>;
local-mac-address = <0x0 0x11 0x3a 0x8a 0x5a 0x78>;
max-frame-size = <0x233a>;
phyid = <3>;
phy-mode = "rgmii";
};
The mailbox node in DTS has following format:
mailbox = <&parent 'higher 32 bit bus address' 'lower 32 bit bus
address' 'signal id'>
Ethernet driver will call following function in platform_probe:
mailbox_get(dev, "mb-tx");
mailbox_get API will return the the context of allocated and configured mailbox.
For now, mailbox_get API will be implemented in xgene QMTM driver.
Eventually when mailbox framework in Linux will be standardized, we
will use it instead.
> For the in-kernel interfaces, we should probably start a conversation
> with the owners of the mailbox drivers to get a common API, for now
> I'd suggest you just leave it as it is, and only adapt for the new
> binding.
Sure. For now we will put our driver mostly as is in the
drivers/mailbox. Can you please help us identify the owners of the
mailbox drivers? As you suggested, we can start conversation with them
to define common in kernel APIs.
Ravi
On Tue, Jan 14, 2014 at 7:15 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Monday 13 January 2014, Ravi Patel wrote:
>> > Examples for local resource management (I had to think about this
>> > a long time, but probably some of these are wrong) would be
>> > * balancing between multiple non-busmaster devices connected to
>> > a dma-engine
>> > * distributing incoming ethernet data to the available CPUs based on
>> > a flow classifier in the MAC, e.g. by IOV MAC address, VLAN tag
>> > or even individual TCP connection depending on the NIC's capabilities.
>> > * 802.1p flow control for incoming ethernet data based on the amount
>> > of data queued up between the MAC and the driver
>> > * interrupt mitigation for both inbound data and outbound completion,
>> > by delaying the IRQ to the OS until multiple messages have arrived
>> > or a queue specific amount of time has passed.
>> > * controlling the amount of outbound buffer space per flow to minimize
>> > buffer-bloat between an ethernet driver and the NIC hardware.
>> > * reordering data from outbound flows based on priority.
>> >
>> > This is basically my current interpretation, I hope I got at least
>> > some of it right this time ;-)
>>
>> You have got them right. Although we have taken Ethernet examples here,
>> most of the local resource management apply to other slave devices also.
>
> I'm very suprised I got all those right, it seems it's a quite sophisticated
> piece of hardware then. I guess most other slave devices only use a subset
> of the capabilities that ethernet wants.
>
> Now that I have a better understanding of what the driver is good for and
> how it's used, let's have a look at how we can make it fit into the Linux
> driver APIs and the DT bindings. We don't have anything exactly like this
> yet, but I think the "mailbox" framework is a close enough match that we
> can fit it in there, with some extensions. This framework is still in the
> process of being created (so far there is only a TI OMAP specific driver,
> and one for pl320), and I've not seen any mailboxes that support IRQ
> mitigation or multiple software interfaces per hardware mailbox, but those
> should be easy enough to add.
>
> For the DT binding, I would suggest using something along the lines of
> what we have for clocks, pinctrl and dmaengine. OMAP doesn't use this
> (yet), but now would be a good time to standardize it. The QMTM node
> should define a "#mailbox-cells" property that indicates how many
> 32-bit cells a qmtm needs to describe the connection between the
> controller and the slave. My best guess is that this would be hardcoded
> to <3>, using two cells for a 64-bit FIFO bus address, and a 32-bit cell
> for the slave-id signal number. All other parameters that you have in
> the big table in the qmtm driver at the moment can then get moved into
> the slave drivers, as they are constant per type of slave. This will
> simplify the QMTM driver.
>
> In the slave, you should have a "mailboxes" property with a phandle
> to the qmtm followed by the three cells to identify the actual
> queue. If it's possible that a device uses more than one rx and
> one tx queue, we also need a "mailbox-names" property to identify
> the individual queues.
>
> For the in-kernel interfaces, we should probably start a conversation
> with the owners of the mailbox drivers to get a common API, for now
> I'd suggest you just leave it as it is, and only adapt for the new
> binding.
>
> Arnd
^ permalink raw reply
* [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Tomasz Figa @ 2014-01-28 0:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPDyKFqpOLZiUSDvxVtYrBM8DtrZDLE27LKzyoWaf29Ni2vcFQ@mail.gmail.com>
On 27.01.2014 11:19, Ulf Hansson wrote:
> On 26 January 2014 18:26, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>> On 21.01.2014 19:34, Tomasz Figa wrote:
>>>
>>> Hi,
>>>
>>> On 20.01.2014 04:56, Olof Johansson wrote:
>>>>
>>>> This patch enables support for power-on sequencing of SDIO peripherals
>>>> through DT.
>>>>
>>>> In general, it's quite common that wifi modules and other similar
>>>> peripherals have several signals in addition to the SDIO interface that
>>>> needs wiggling before the module will power on. It's common to have a
>>>> reference clock, one or several power rails and one or several lines
>>>> for reset/enable type functions.
>>>>
>>>> The binding as written today introduces a number of reset gpios,
>>>> a regulator and a clock specifier. The code will handle up to 2 gpio
>>>> reset lines, but it's trivial to increase to more than that if needed
>>>> at some point.
>>>>
>>>> Implementation-wise, the MMC core has been changed to handle this during
>>>> host power up, before the host interface is powered on. I have not yet
>>>> implemented the power-down side, I wanted people to have a chance for
>>>> reporting back w.r.t. issues (or comments on the bindings) first.
>>>>
>>>> I have not tested the regulator portion, since the system and module
>>>> I'm working on doesn't need one (Samsung Chromebook with Marvell
>>>> 8797-based wifi). Testing of those portions (and reporting back) would
>>>> be appreciated.
>>>
>>>
>>> While I fully agree that this is an important problem that needs to be
>>> solved, I really don't think this is the right way, because:
>>>
>>> a) power-up sequence is really specific to the MMC device and often it's
>>> not simply a matter of switching on one regulator or one clock, e.g.
>>> specific time constraints need to be met.
>>>
>>> b) you can have WLAN chips in which SDIO is just one of the options to
>>> use as host interface, which may be also HSIC, I2C or UART. Really. See
>>> [1].
>>>
>>> c) this is leaking device specific details to generic host code, which
>>> isn't really elegant.
>>>
>>> Now, to make this a bit more constructive, [2] is a solution that I came
>>> up with (not perfect either), which simply adds a separate platform
>>> device for the low level part of the chip. I believe this is a better
>>> solution because:
>>>
>>> a) you can often see such WLAN/BT combo chip as a set of separate
>>> devices, e.g. SDIO WLAN, UART BT and a simple PMIC or management IC,
>>> which provides power/reset control, out of band signalling and etc. for
>>> the first two, so it isn't that bad to have a separate device node for
>>> the last one,
>>>
>>> b) you have full freedom of defining your DT binding with whatever data
>>> you need, any number of clocks, regulators, GPIOs and even out of band
>>> interrupts (IMHO the most important one).
>>>
>>> c) you can implement power-on, power-off sequences as needed for your
>>> particular device,
>>>
>>> d) you have full separation of device-specific data from MMC core (or
>>> any other subsystem simply used as a way to perform I/O to the chip).
>>>
>>> Now what's missing there is a way to signal the MMC core or any other
>>> transport that a device showed up and the controller should be woken up
>>> out of standby and scan of the bus initialized. This could be done by
>>> explicitly specifying the device as a subnode of the
>>> MMC/UART/USB(HSIC)/I2C or whatever with a link (phandle) to the power
>>> controller of the chip or the other way around - a link to the
>>> MMC/UART/... controller from the power controller node.
>>
>>
>> I've looked a bit around MMC core code and got some basic idea how things
>> look. I will definitely need some guidance, or at least some opinions, from
>> MMC guys, as some MMC core changes are unavoidable.
>>
>> Now, the device-specific code is not really an issue, existing drivers
>> usually already have their ways of powering the chips on and off, based on
>> platform data. Everything needed here is to retrieve needed resources
>> (GPIOs, clocks, regulators) using DT, which should be trivial.
>>
>> The worse part is the interaction between MMC and power controller driver
>> (the platform driver part of WLAN driver, if you look at brcmfmac as an
>> example). I believe that we need following things:
>>
>> a) A way to tell the MMC controller that there is no card detection
>> mechanism available on given slot and it also should not be polling the slot
>> to check card presence. Something like a "manual card detect" that would be
>> triggered by another kernel entity that controls whether the MMC device is
>> present (i.e. WLAN driver). We already have "broken-cd" property, but it
>> only implies the former, wasting time on needless polling.
>
> There is already a host capability that I think we could use to handle
> this. MMC_CAP_NONREMOVABLE, the corresponding DT binding string is
> "non-removable", and it may be set per host device.
>
> Using this cap means the mmc_rescan process that runs to detect new
> cards, will only be executed once and during boot. So, we need to make
> sure all resources and powers are provided to the card at this point.
> Otherwise the card will not be detected.
I don't quite like this requirement, especially if you consider
multi-platform kernels where a lot of drivers is going to be provided as
modules. WLAN drivers are especially good candidates. This means that
even if the card is powered off at boot-up, if user (or init system)
loads appropriate module, which powers the chip on, MMC core must be
able to notice this.
> In the SDIO case, to save power, the SDIO func driver may use runtime
> PM to tell the mmc core power about whether the card needs to be
> powered. Typically from the WLAN driver's probe() and "interface
> up/down" the runtime PM reference for the SDIO func device, should be
> adjusted with pm_runtime_get|put.
I need to think a bit more about the power management control flow here.
In case of such chips I'd tend to look at MMC merely as a host
interface, which as I said, might be only one of available options. I'm
not sure if it should be the host interface core that decides whether
the whole device should be powered off. However there might be a
solution that leverages SDIO func runtime PM, which wouldn't imply such
control flow. Let me reconsider this.
>
>>
>> b) A mechanism to bind the power controller to used MMC slot. Something like
>> "mmc-bus = <&mmc2>;" property in device node of the power controller and a
>> function like of_find_mmc_controller_by_node(), which would be an MMC
>> counterpart of I2C's of_find_i2c_adapter_by_node(). To avoid races, it
>> should probably take a reference on MMC host that would have to be dropped
>> explicitly whenever it is not needed anymore.
>
> I suppose an "MMC slot" can be translated to "MMC host"?
Right.
> What I am trying to understand is how the mmc core (or if we push it
> to be handled from the mmc host's .set_ios callback) shall be able to
> tell the power controller driver to enable/disable it's resources.
> Somehow we need the struct device available to handle that. Then I
> guess operating on it using runtime PM would be a solution that would
> be quite nice!?
As I wrote above, I'm not quite sure about this yet.
>>
>> c) A method to notify the MMC subsystem that card presence has changed. We
>> already have something like this in drivers/mmc/core/slot-gpio.c, but used
>> for a simple GPIO-based card detection. If the main part of
>> mmc_gpio_cd_irqt() could be turned into an exported helper, e.g.
>> mmc_force_card_detect(host) then basically we would have everything needed.
>
> I am not sure I understand why this is needed. I think it would be
> more convenient to use MMC_CAP_NONREMOVABLE instead as stated earlier.
> But please elaborate, I might have missed something.
See above. I'm not quite convinced that state of MMC interface should
determine power state of the chip. I can easily imagine a situation
where the MMC link is powered down (link power management) but the WLAN
chip keeps operation. Keep in mind that those are usually complete SoCs
that can keep processing network traffic autonomously and wake-up the
application processor whenever anything interesting happens using extra
out of bounds signalling, which might trigger re-enabling the MMC link.
>>
>> Unfortunately, I don't have more time left for today to create patches and
>> test them, so for now, I'd like to hear opinion of MMC maintainers about
>> this approach. Do you find this acceptable?
>>
>> By the way, it seems like slot-gpio.c could replace a lot of custom GPIO
>> card detection code used in MMC host drivers, e.g. sdhci-s3c. Is there any
>> reason why it couldn't?
>
> I suppose most host driver's should convert to the slot-gpio API, it's
> is just a matter of someone to send the patches. :-)
OK, great. I'll add conversion of sdhci-s3c to my queue then.
Best regards,
Tomasz
^ permalink raw reply
* Freescale FEC packet loss
From: Marek Vasut @ 2014-01-28 1:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390772013.2735.47.camel@deadeye.wl.decadent.org.uk>
On Sunday, January 26, 2014 at 10:33:33 PM, Ben Hutchings wrote:
> On Sun, 2014-01-26 at 20:12 +0100, Marek Vasut wrote:
> > On Sunday, January 26, 2014 at 07:56:30 PM, Ben Hutchings wrote:
> > > On Wed, 2014-01-22 at 22:55 +0100, Marek Vasut wrote:
> > > > Hi guys,
> > > >
> > > > I am running stock Linux 3.13 on i.MX6Q SabreLite board. The CPU is
> > > > i.MX6Q TO 1.0 .
> > > >
> > > > I am hitting a WARNING when I use the FEC ethernet to transfer data,
> > > > thus I started investigating this problem. TL;DR I am not able to
> > > > figure this problem out, so I am not attaching a patch :-(
> > > >
> > > > Steps to reproduce:
> > > > -------------------
> > > > 1) Boot stock Linux 3.13 on i.MX6Q SabreLite board
> > > > 2) Plug in an SD card into one of the SD slots (I use the full-size
> > > > one) 3) Plug in an USB stick into one of the USB ports (I use the
> > > > upper one) 4) Plug in an ethernet cable into the board
> > > >
> > > > -> Connect the other side into a gigabit-capable PC
> > >
> > > [...]
> > >
> > > I think there are known problems with 1000BASE-T on the Sabre Lite
> > > board.
> >
> > This is MX6-wide thing, not sabrelite specific actually.
> >
> > > Two possible workarounds are to limit the PHY to 100BASE-TX
> > > (should be doable with ethtool) or force it to be clock master for
> > > 1000BASE-T (requires a driver patch).
> >
> > Can you please elaborate on the later ? I don't quite understand that.
>
> 1000BASE-T uses all 4 pairs in both directions at the same time, which
> requires that both ends transmit symbols synchronously. As part of the
> autonegotiation protocol, they decide which is the clock master (using a
> local clock generator) and which is the clock slave (generating a clock
> from the received signal). A PHY can be configured to support only one
> of these roles.
I checked the patch you pointed me to. The patch basically messes with the
CTL1000 (0x9) register of the PHY, right ? I did the adjustments to the PHY
register manually , but the result is still the same (backtrace).
I did two different kinds of adjustment:
1) reg 0x9 |= 0x1800;
2) reg 0x9 |= 0x1000;
In both cases, the crash did happen. I verified the PHY register was configured
as necessary. The KSZ9021 PHY bit 12 configures the master/slave override, same
as the patch does. The bit 11 forces either master or slave mode for the PHY. In
both cases the crash was there.
I think this patch won't help in this case, sorry.
Best regards,
Marek Vasut
^ permalink raw reply
* [PATCH] ARM: multi_v7: add mvebu and drivers to defconfig
From: Jason Cooper @ 2014-01-28 1:05 UTC (permalink / raw)
To: linux-arm-kernel
boot farms testing is highlighting some errors in mvebu. Let's get some
more coverage for multi_v7_defconfig kernels.
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
Kevin,
This is against tonight's master. Feel free to take it directly.
thx,
Jason.
arch/arm/configs/multi_v7_defconfig | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 687e4e811b2a..13e7d649230b 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -38,7 +38,6 @@ CONFIG_ARCH_TEGRA=y
CONFIG_ARCH_TEGRA_2x_SOC=y
CONFIG_ARCH_TEGRA_3x_SOC=y
CONFIG_ARCH_TEGRA_114_SOC=y
-CONFIG_TEGRA_PCI=y
CONFIG_TEGRA_EMC_SCALING_ENABLE=y
CONFIG_ARCH_U8500=y
CONFIG_MACH_HREFV60=y
@@ -49,7 +48,9 @@ CONFIG_ARCH_VEXPRESS_CA9X4=y
CONFIG_ARCH_VIRT=y
CONFIG_ARCH_WM8850=y
CONFIG_ARCH_ZYNQ=y
-CONFIG_SMP=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MVEBU=y
CONFIG_HIGHPTE=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
@@ -69,12 +70,14 @@ CONFIG_SATA_MV=y
CONFIG_NETDEVICES=y
CONFIG_SUN4I_EMAC=y
CONFIG_NET_CALXEDA_XGMAC=y
+CONFIG_MVNETA=y
CONFIG_KS8851=y
CONFIG_SMSC911X=y
CONFIG_STMMAC_ETH=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_MDIO_SUN4I=y
CONFIG_TI_CPSW=y
+CONFIG_MARVELL_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_SPEAR=y
CONFIG_SERIO_AMBAKMI=y
CONFIG_SERIAL_8250=y
@@ -99,25 +102,27 @@ CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
CONFIG_SERIAL_ST_ASC=y
CONFIG_SERIAL_ST_ASC_CONSOLE=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_I2C_MV64XXX=y
CONFIG_I2C_SIRF=y
CONFIG_I2C_TEGRA=y
CONFIG_SPI=y
CONFIG_SPI_OMAP24XX=y
+CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
CONFIG_SPI_SIRF=y
CONFIG_SPI_TEGRA114=y
CONFIG_SPI_TEGRA20_SLINK=y
-CONFIG_PINCTRL_SINGLE=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_TWL4030=y
-CONFIG_REGULATOR_GPIO=y
+CONFIG_THERMAL=y
+CONFIG_ARMADA_THERMAL=y
CONFIG_REGULATOR_AB8500=y
+CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_TPS51632=y
CONFIG_REGULATOR_TPS62360=y
CONFIG_REGULATOR_TWL4030=y
CONFIG_REGULATOR_VEXPRESS=y
CONFIG_DRM=y
-CONFIG_TEGRA_HOST1X=y
CONFIG_DRM_TEGRA=y
CONFIG_FB_ARMCLCD=y
CONFIG_FB_WM8505=y
@@ -132,8 +137,6 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_AB8500_USB=y
-CONFIG_NOP_USB_XCEIV=y
-CONFIG_OMAP_USB2=y
CONFIG_OMAP_USB3=y
CONFIG_SAMSUNG_USB2PHY=y
CONFIG_SAMSUNG_USB3PHY=y
@@ -144,13 +147,13 @@ CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=16
CONFIG_MMC_ARMMMCI=y
CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_ESDHC_IMX=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_MMC_SDHCI_SPEAR=y
CONFIG_MMC_SDHCI_BCM_KONA=y
CONFIG_MMC_OMAP=y
CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_MVSDIO=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_HIGHBANK_MC=y
@@ -159,20 +162,23 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_TWL4030=y
CONFIG_RTC_DRV_PL031=y
CONFIG_RTC_DRV_VT8500=y
+CONFIG_RTC_DRV_MV=y
CONFIG_RTC_DRV_TEGRA=y
CONFIG_DMADEVICES=y
CONFIG_DW_DMAC=y
+CONFIG_MV_XOR=y
CONFIG_TEGRA20_APB_DMA=y
CONFIG_STE_DMA40=y
CONFIG_SIRF_DMA=y
-CONFIG_TI_EDMA=y
CONFIG_PL330_DMA=y
CONFIG_IMX_SDMA=y
CONFIG_IMX_DMA=y
CONFIG_MXS_DMA=y
CONFIG_DMA_OMAP=y
+CONFIG_MEMORY=y
CONFIG_PWM=y
CONFIG_PWM_VT8500=y
+CONFIG_OMAP_USB2=y
CONFIG_EXT4_FS=y
CONFIG_TMPFS=y
CONFIG_NFS_FS=y
--
1.8.5.3
^ permalink raw reply related
* [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Chris Ball @ 2014-01-28 1:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52E700F0.7040708@gmail.com>
Hi,
On Tue, Jan 28 2014, Tomasz Figa wrote:
>> I am not sure I understand why this is needed. I think it would be
>> more convenient to use MMC_CAP_NONREMOVABLE instead as stated earlier.
>> But please elaborate, I might have missed something.
>
> See above. I'm not quite convinced that state of MMC interface should
> determine power state of the chip. I can easily imagine a situation
> where the MMC link is powered down (link power management) but the
> WLAN chip keeps operation. Keep in mind that those are usually
> complete SoCs that can keep processing network traffic autonomously
> and wake-up the application processor whenever anything interesting
> happens using extra out of bounds signalling, which might trigger
> re-enabling the MMC link.
For what it's worth, we did this using upstream code (libertas-sd8686
WLAN with sdhci-pxav3) at OLPC. We set the SDIO device to 1-bit mode
on system suspend, using MMC_CAP_NONREMOVABLE, MMC_PM_KEEP_POWER and
MMC_PM_WAKE_SDIO_IRQ, and tell the PMU to wake on the 1-bit data line.
When it wakes the system, the system sees the SDIO interrupt and
processes the waiting network traffic.
So this use case is already supported using the current interfaces.
If this interface doesn't work for your use case, could you talk a
little more about what you're trying to achieve?
Thanks,
- Chris.
--
Chris Ball <chris@printf.net> <http://printf.net/>
^ permalink raw reply
* [PATCH] arm64: setup: report non-optional CPU features
From: Alex Van Brunt @ 2014-01-28 1:23 UTC (permalink / raw)
To: linux-arm-kernel
There are a large number of popular applications compiled for ARMv7-A that read
/proc/cpuinfo to find out what features the CPU has. But, when they are run
on an arm64 kernel, they fail to run. This is because features that were
optional on ARMv7 or earlier but are not optional on ARMv8-A like Thumb are not
listed as a CPU feature using the arm64 kernel. To make those applications run,
the kernel still needs to print the features in the list.
This patch changes "cat /proc/cpuinfo" from printing:
Features : fp asimd
To printing:
Features : fp asimd wp half thumb fastmult vfp edsp neon vfpv3d16 tlsi vfpv4 idiva idivt
Subject: [PATCH] arm64: setup: report non-optional CPU features
Many ARM applications read the CPU features list provided by the
kernel in /proc/cpuinfo to determine which features to use. If a
feature is not listed, the application with either run slower or will
not run at all.
CPU features that are no longer optional in ARMv8-A, but were
optional in previous architectures still need to be printed. To
achieve this, always report these features.
Change-Id: I0a8092ee07926ae5410d7863a270a76fa224297d
Signed-off-by: Alex Van Brunt <avanbrunt@nvidia.com>
---
arch/arm64/kernel/setup.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index bd9bbd0..7f8e9bd 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -302,6 +302,8 @@ static int c_show(struct seq_file *m, void *v)
for (i = 0; hwcap_str[i]; i++)
if (elf_hwcap & (1 << i))
seq_printf(m, "%s ", hwcap_str[i]);
+ /* Print non-optional features in ARMv8 */
+ seq_printf(m, "half thumb fastmult vfp neon vfpv3 vfpv4 idiva");
seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
seq_printf(m, "CPU architecture: AArch64\n");
--
1.8.1.5
^ permalink raw reply related
* [PATCH 1/2] arm64: use num_possible_cpus() instead of NR_CPUS
From: Jingoo Han @ 2014-01-28 1:35 UTC (permalink / raw)
To: linux-arm-kernel
Use num_possible_cpus() instead of direct use of NR_CPUS. Also,
it fixes the following checkpatch warning.
WARNING: usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm64/kernel/smp.c | 10 +++++-----
arch/arm64/mm/context.c | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 1b7617a..09ff7d4 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -320,7 +320,7 @@ void __init smp_init_cpus(void)
* cpu_logical_map was initialized to INVALID_HWID to
* avoid matching valid MPIDR values.
*/
- for (i = 1; (i < cpu) && (i < NR_CPUS); i++) {
+ for (i = 1; (i < cpu) && (i < num_possible_cpus()); i++) {
if (cpu_logical_map(i) == hwid) {
pr_err("%s: duplicate cpu reg properties in the DT\n",
dn->full_name);
@@ -352,7 +352,7 @@ void __init smp_init_cpus(void)
continue;
}
- if (cpu >= NR_CPUS)
+ if (cpu >= num_possible_cpus())
goto next;
if (cpu_read_ops(dn, cpu) != 0)
@@ -368,9 +368,9 @@ next:
}
/* sanity check */
- if (cpu > NR_CPUS)
+ if (cpu > num_possible_cpus())
pr_warning("no. of cores (%d) greater than configured maximum of %d - clipping\n",
- cpu, NR_CPUS);
+ cpu, num_possible_cpus());
if (!bootcpu_valid) {
pr_err("DT missing boot CPU MPIDR, not enabling secondaries\n");
@@ -381,7 +381,7 @@ next:
* All the cpus that made it to the cpu_logical_map have been
* validated so set them as possible cpus.
*/
- for (i = 0; i < NR_CPUS; i++)
+ for (i = 0; i < num_possible_cpus(); i++)
if (cpu_logical_map(i) != INVALID_HWID)
set_cpu_possible(i, true);
}
diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
index baa758d..3ef960a 100644
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -151,7 +151,7 @@ void __new_context(struct mm_struct *mm)
smp_wmb();
smp_call_function(reset_context, NULL, 1);
#endif
- cpu_last_asid += NR_CPUS - 1;
+ cpu_last_asid += num_possible_cpus() - 1;
}
set_mm_context(mm, asid);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/2] arm64: kernel: use seq_puts() instead of seq_printf()
From: Jingoo Han @ 2014-01-28 1:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <001d01cf1bc9$452569d0$cf703d70$%han@samsung.com>
For a constant format without additional arguments, use seq_puts()
instead of seq_printf(). Also, it fixes the following checkpatch
warning.
WARNING: Prefer seq_puts to seq_printf
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm64/kernel/setup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index c8e9eff..4507691 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -416,7 +416,7 @@ static int c_show(struct seq_file *m, void *v)
seq_printf(m, "%s ", hwcap_str[i]);
seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
- seq_printf(m, "CPU architecture: AArch64\n");
+ seq_puts(m, "CPU architecture: AArch64\n");
seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15);
seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff);
seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
--
1.7.10.4
^ permalink raw reply related
* [PATCH] arm64: Add pdev_archdata for dmamask
From: Laura Abbott @ 2014-01-28 1:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140127193149.GV15937@n2100.arm.linux.org.uk>
On 1/27/2014 11:31 AM, Russell King - ARM Linux wrote:
> On Mon, Jan 27, 2014 at 09:52:57AM -0800, Laura Abbott wrote:
>> The dma_mask for a device structure is a pointer. This pointer
>> needs to be set up before the dma mask can actually be set. Most
>> frameworks in the kernel take care of setting this up properly but
>> platform devices that don't follow a regular bus structure may not
>> ever have this set. As a result, checks such as dma_capable will
>> always return false on a raw platform device and dma_set_mask will
>> always return -EIO. Fix this by adding a dma_mask in the
>> platform_device archdata and setting it to be the dma_mask. Devices
>> used in other frameworks can change this as needed.
>
> You shouldn't need to do this. I went through a lot of the drivers we
> currently have, fixing them up in various manners. The basic rules
> for this stuff are:
>
> - It is the responsibility of the code creating the device to set a
> reasonable default for the dma mask according to the bus and whether
> DMA is supportable.
>
> - It is the responsibility of the driver _always_ to make a call to
> dma_set_mask() and/or dma_set_coherent_mask() according to the
> driver's needs if the driver is going to be using DMA.
>
> As a work-around for the buggy situation we have in the kernel with DT,
> various buggy workarounds have been incorporated into drivers which
> involve writing directly to the DMA masks, and other such games. None
> of that is necessary when the dma_coerce_*() functions are used - but
> these are a stop-gap until the DT code gets fixed.
>
> The real answer here is to make DT conform to the first point above
> and not add yet another different hack to the kernel.
>
powerpc ran into this exact problem before and fixed it using this
method (a77ce8167cc1d0370fcb1d79b367d62e050cb2b0
"driver core: Add ability for arch code to setup pdev_archdata" and
314b02f503c2c219fde0fcf6f086fda415f8a847 "powerpc: implement
arch_setup_pdev_archdata") so there is at least some precedent for this
method.
Are there patches/discussion somewhere else on what a proper solution
would be in the DT?
Thanks,
Laura
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* [RFC PATCH V2 1/4] pci: APM X-Gene PCIe controller driver
From: Tanmay Inamdar @ 2014-01-28 2:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAErSpo5zMd_k407tvzPS85Nub9p2KMQnHJLTqd3eyvjdgfVtLg@mail.gmail.com>
On Mon, Jan 27, 2014 at 4:55 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> We're only seeing Arnd's side of the conversation on linux-pci.
> Tanmay, are your messages being rejected because they're too "fancy",
> per the definition here: http://vger.kernel.org/majordomo-info.html ?
>
Thanks for pointing out. I am not sure though what's being detected as
fancy. I checked that my emails are received as plaintext on
majordomo. They are also displayed fine on LKML.
In this email, I have tried to keep the format of to: and cc: same as
first email in the thread. Not sure if this fixes the problem.
Again.. sorry for spamming.
> On Sat, Jan 25, 2014 at 1:11 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Friday 24 January 2014 13:28:22 Tanmay Inamdar wrote:
>>> On Thu, Jan 16, 2014 at 5:10 PM, Tanmay Inamdar <tinamdar@apm.com> wrote:
>>> > On Wed, Jan 15, 2014 at 4:39 AM, Arnd Bergmann <arnd@arndb.de> wrote:
>>> >> On Wednesday 15 January 2014, Tanmay Inamdar wrote:
>>
>>> >>
>>> >>> +static void xgene_pcie_poll_linkup(struct xgene_pcie_port *port, u32 *lanes)
>>> >>> +{
>>> >>> + void *csr_base = port->csr_base;
>>> >>> + u32 val32;
>>> >>> + u64 start_time, time;
>>> >>> +
>>> >>> + /*
>>> >>> + * A component enters the LTSSM Detect state within
>>> >>> + * 20ms of the end of fundamental core reset.
>>> >>> + */
>>> >>> + msleep(XGENE_LTSSM_DETECT_WAIT);
>>> >>> + port->link_up = 0;
>>> >>> + start_time = jiffies;
>>> >>> + do {
>>> >>> + val32 = readl(csr_base + PCIECORE_CTLANDSTATUS);
>>> >>> + if (val32 & LINK_UP_MASK) {
>>> >>> + port->link_up = 1;
>>> >>> + port->link_speed = PIPE_PHY_RATE_RD(val32);
>>> >>> + val32 = readl(csr_base + BRIDGE_STATUS_0);
>>> >>> + *lanes = val32 >> 26;
>>> >>> + }
>>> >>> + time = jiffies_to_msecs(jiffies - start_time);
>>> >>> + } while ((!port->link_up) || (time <= XGENE_LTSSM_L0_WAIT));
>>> >>> +}
>>> >>
>>> >> Maybe another msleep() in the loop? It seems weird to first do an
>>> >> unconditional sleep but then busy-wait for the result.
>>> >
>>> > ok.
>>>
>>> This loop can execute for maximum 4 msec. So putting msleep(1) won't
>>> get us much.
>>
>> 4 msec is still quite a long time for a busy loop that can be spent doing
>> useful work in another thread.
>>
>>> >>
>>> >> Another general note: Your "compatible" strings are rather unspecific.
>>> >> Do you have a version number for this IP block? I suppose that it's related
>>> >> to one that has been used in other chips before, or will be used in future
>>> >> chips, if it's not actually licensed from some other company.
>>> >
>>> > I will have to check this.
>>> >
>>>
>>> We have decided to stick with current compatible string for now.
>>
>> Can you elaborate on your reasoning? Does this mean X-Gene is a one-off
>> product and you won't be doing any new chips based on the same hardware
>> components?
>>
>> Arnd
^ permalink raw reply
* [PATCH v2] dma: Add Xilinx AXI Video Direct Memory Access Engine driver support
From: Vinod Koul @ 2014-01-28 3:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52E54849.2000208@metafoo.de>
On Sun, Jan 26, 2014 at 06:39:21PM +0100, Lars-Peter Clausen wrote:
> On 01/26/2014 02:59 PM, Vinod Koul wrote:
> > On Fri, Jan 24, 2014 at 02:24:27PM +0100, Lars-Peter Clausen wrote:
> >> On 01/24/2014 12:16 PM, Srikanth Thokala wrote:
> >>> Hi Lars,
> >>>
> >>> On Thu, Jan 23, 2014 at 4:55 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
> >>>> On 01/22/2014 05:52 PM, Srikanth Thokala wrote:
> >>>> [...]
> >>>>> +/**
> >>>>> + * xilinx_vdma_device_control - Configure DMA channel of the device
> >>>>> + * @dchan: DMA Channel pointer
> >>>>> + * @cmd: DMA control command
> >>>>> + * @arg: Channel configuration
> >>>>> + *
> >>>>> + * Return: '0' on success and failure value on error
> >>>>> + */
> >>>>> +static int xilinx_vdma_device_control(struct dma_chan *dchan,
> >>>>> + enum dma_ctrl_cmd cmd, unsigned long arg)
> >>>>> +{
> >>>>> + struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
> >>>>> +
> >>>>> + switch (cmd) {
> >>>>> + case DMA_TERMINATE_ALL:
> >>>>> + xilinx_vdma_terminate_all(chan);
> >>>>> + return 0;
> >>>>> + case DMA_SLAVE_CONFIG:
> >>>>> + return xilinx_vdma_slave_config(chan,
> >>>>> + (struct xilinx_vdma_config *)arg);
> >>>>
> >>>> You really shouldn't be overloading the generic API with your own semantics.
> >>>> DMA_SLAVE_CONFIG should take a dma_slave_config and nothing else.
> >>>
> >>> Ok. The driver needs few additional configuration from the slave
> >>> device like Vertical
> >>> Size, Horizontal Size, Stride etc., for the DMA transfers, in that case do you
> >>> suggest me to define a separate dma_ctrl_cmd like the one FSLDMA_EXTERNAL_START
> >>> defined for Freescale drivers?
> >>
> >> In my opinion it is not a good idea to have driver implement a generic API,
> >> but at the same time let the driver have custom semantics for those API
> >> calls. It's a bit like having a gpio driver that expects 23 and 42 as the
> >> values passed to gpio_set_value instead of 0 and 1. It completely defeats
> >> the purpose of a generic API, namely that you are able to write generic code
> >> that makes use of the API without having to know about which implementation
> >> API it is talking to. The dmaengine framework provides the
> >> dmaengine_prep_interleaved_dma() function to setup two dimensional
> >> transfers, e.g. take a look at sirf-dma.c or imx-dma.c.
> >
> > The question here i think would be waht this device supports? Is the hardware
> > capable of doing interleaved transfers, then would make sense.
>
> The hardware does 2D transfers. The parameters for a transfer are height,
> width and stride. That's only a subset of what interleaved transfers can be
> (xt->num_frames must be one for 2d transfers). But if I remember correctly
> there has been some discussion on this in the past and the result of that
> discussion was that using interleaved transfers for 2D transfers is
> preferred over adding a custom API for 2D transfers.
Yup that would be my recomendation. Moving this driver to interleaved API seems
right to me
--
~Vinod
^ permalink raw reply
* [PATCH RFC 00/73] tree-wide: clean up some no longer required #include <linux/init.h>
From: Benjamin Herrenschmidt @ 2014-01-28 3:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140123003838.GA10182@windriver.com>
On Wed, 2014-01-22 at 19:38 -0500, Paul Gortmaker wrote:
> Thanks, it was a great help as it uncovered a few issues in fringe arch
> that I didn't have toolchains for, and I've fixed all of those up.
>
> I've noticed that powerpc has been un-buildable for a while now; I have
> used this hack patch locally so I could run the ppc defconfigs to check
> that I didn't break anything. Maybe useful for linux-next in the
> interim? It is a hack patch -- Not-Signed-off-by: Paul Gortmaker. :)
Can you and/or Aneesh submit that as a proper patch (with S-O-B
etc...) ?
Thanks !
Cheers,
Ben.
> Paul.
> --
>
> diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
> index d27960c89a71..d0f070a2b395 100644
> --- a/arch/powerpc/include/asm/pgtable-ppc64.h
> +++ b/arch/powerpc/include/asm/pgtable-ppc64.h
> @@ -560,9 +560,9 @@ extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
> pmd_t *pmdp);
>
> #define pmd_move_must_withdraw pmd_move_must_withdraw
> -typedef struct spinlock spinlock_t;
> -static inline int pmd_move_must_withdraw(spinlock_t *new_pmd_ptl,
> - spinlock_t *old_pmd_ptl)
> +struct spinlock;
> +static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
> + struct spinlock *old_pmd_ptl)
> {
> /*
> * Archs like ppc64 use pgtable to store per pmd
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* [PATCH v2] dma: Add Xilinx AXI Video Direct Memory Access Engine driver support
From: Vinod Koul @ 2014-01-28 3:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+mB=1JvnTcyRnuvdnW1BCeiMLSTMrrAbKwVKgwFUmWrVuXzSw@mail.gmail.com>
On Mon, Jan 27, 2014 at 06:42:36PM +0530, Srikanth Thokala wrote:
> Hi Lars/Vinod,
> >> The question here i think would be waht this device supports? Is the hardware
> >> capable of doing interleaved transfers, then would make sense.
> >
> > The hardware does 2D transfers. The parameters for a transfer are height,
> > width and stride. That's only a subset of what interleaved transfers can be
> > (xt->num_frames must be one for 2d transfers). But if I remember correctly
> > there has been some discussion on this in the past and the result of that
> > discussion was that using interleaved transfers for 2D transfers is
> > preferred over adding a custom API for 2D transfers.
>
> I went through the prep_interleaved_dma API and I see only one descriptor
> is prepared per API call (i.e. per frame). As our IP supports upto 16 frame
> buffers (can be more in future), isn't it less efficient compared to the
> prep_slave_sg where we get a single sg list and can prepare all the descriptors
> (of non-contiguous buffers) in one go? Correct me, if am wrong and let me
> know your opinions.
Well the descriptor maybe one, but that can represent multiple frames, for
example 16 as in your case. Can you read up the documentation of how multiple
frames are passed. Pls see include/linux/dmaengine.h
/**
* Interleaved Transfer Request
* ----------------------------
* A chunk is collection of contiguous bytes to be transfered.
* The gap(in bytes) between two chunks is called inter-chunk-gap(ICG).
* ICGs may or maynot change between chunks.
* A FRAME is the smallest series of contiguous {chunk,icg} pairs,
* that when repeated an integral number of times, specifies the transfer.
* A transfer template is specification of a Frame, the number of times
* it is to be repeated and other per-transfer attributes.
*
* Practically, a client driver would have ready a template for each
* type of transfer it is going to need during its lifetime and
* set only 'src_start' and 'dst_start' before submitting the requests.
*
*
* | Frame-1 | Frame-2 | ~ | Frame-'numf' |
* |====....==.===...=...|====....==.===...=...| ~ |====....==.===...=...|
*
* == Chunk size
* ... ICG
*/
--
~Vinod
^ permalink raw reply
* [PATCH] ARM: dts: imx28-m28cu3: Remove 'reset-active-high'
From: Marek Vasut @ 2014-01-28 3:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390596324-20904-1-git-send-email-festevam@gmail.com>
On Friday, January 24, 2014 at 09:45:24 PM, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
>
> The 'reset-active-high' property is not defined anywhere, so just remove
> it.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Acked-by: Marek Vasut <marex@denx.de>
Best regards,
Marek Vasut
^ permalink raw reply
* [RFC PATCH 0/3] In-kernel PSCI v0.2 emulation for KVM ARM/ARM64
From: Anup Patel @ 2014-01-28 4:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390309301-28424-1-git-send-email-anup.patel@linaro.org>
On Tue, Jan 21, 2014 at 6:31 PM, Anup Patel <anup.patel@linaro.org> wrote:
> Currently, KVM ARM/ARM64 only provides in-kernel emulation of Power State
> and Coordination Interface (PSCI) v0.1.
>
> This patchset aims at providing newer PSCI v0.2 for KVM ARM/ARM64 VCPUs
> such that it does not break current KVM ARM/ARM64 ABI. Also, the patchset
> provides emulation of only few PSCI v0.2 functions such as PSCI_VERSION,
> CPU_ON, and CPU_OFF. Emulation of other PSCI v0.2 functions will be added
> later.
>
> The user space tools (i.e. QEMU or KVMTOOL) will have to explicitly enable
> KVM_ARM_VCPU_PSCI_0_2 feature using KVM_ARM_VCPU_INIT ioctl for providing
> PSCI v0.2 to VCPUs.
>
> Anup Patel (3):
> KVM: Add capability to advertise PSCI v0.2 support
> ARM/ARM64: KVM: Add support for PSCI v0.2 emulation
> KVM: Documentation: Add info regarding KVM_ARM_VCPU_PSCI_0_2 feature
>
> Documentation/virtual/kvm/api.txt | 2 +
> arch/arm/include/asm/kvm_host.h | 2 +-
> arch/arm/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
> arch/arm/kvm/arm.c | 6 ++-
> arch/arm/kvm/psci.c | 79 ++++++++++++++++++++++++++++++-------
> arch/arm64/include/asm/kvm_host.h | 2 +-
> arch/arm64/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
> include/uapi/linux/kvm.h | 1 +
> 8 files changed, 146 insertions(+), 24 deletions(-)
>
> --
> 1.7.9.5
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
Hi All,
Please provide feedback and comments on this patchset.
Regards,
Anup
^ permalink raw reply
* [PATCH v2 1/7] cpufreq: cpufreq-cpu0: allow optional safe voltage during frequency transitions
From: Thomas Abraham @ 2014-01-28 4:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140127071656.GB3135@S2101-09.ap.freescale.net>
Hi Shawn,
On Mon, Jan 27, 2014 at 12:46 PM, Shawn Guo <shawn.guo@linaro.org> wrote:
> On Sat, Jan 18, 2014 at 05:40:51PM +0530, Thomas Abraham wrote:
>> From: Thomas Abraham <thomas.ab@samsung.com>
>>
>> On some platforms such as the Samsung Exynos, changing the frequency
>> of the CPU clock requires changing the frequency of the PLL that is
>> supplying the CPU clock. To change the frequency of the PLL, the CPU
>> clock is temporarily reparented to another parent clock.
>>
>> The clock frequency of this temporary parent clock could be much higher
>> than the clock frequency of the PLL at the time of reparenting. Due
>> to the temporary increase in the CPU clock speed, the CPU (and any other
>> components in the CPU clock domain such as dividers, mux, etc.) have to
>> to be operated at a higher voltage level, called the safe voltage level.
>> This patch adds optional support to temporarily switch to a safe voltage
>> level during CPU frequency transitions.
>>
>> Cc: Shawn Guo <shawn.guo@linaro.org>
>> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
>> ---
>> .../devicetree/bindings/cpufreq/cpufreq-cpu0.txt | 7 ++++
>
> The devicetree list should be copied for this change.
Okay, will do in the next version.
>
>> drivers/cpufreq/cpufreq-cpu0.c | 37 +++++++++++++++++--
>> 2 files changed, 40 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> index f055515..37453ab 100644
>> --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> @@ -19,6 +19,12 @@ Optional properties:
>> - cooling-min-level:
>> - cooling-max-level:
>> Please refer to Documentation/devicetree/bindings/thermal/thermal.txt.
>> +- safe-opp: Certain platforms require that during a opp transition,
>> + a system should not go below a particular opp level. For such systems,
>> + this property specifies the minimum opp to be maintained during the
>> + opp transitions. The safe-opp value is a tuple with first element
>> + representing the safe frequency and the second element representing the
>> + safe voltage.
>>
>> Examples:
>>
>> @@ -36,6 +42,7 @@ cpus {
>> 396000 950000
>> 198000 850000
>> >;
>> + safe-opp = <396000 950000>
>> clock-latency = <61036>; /* two CLK32 periods */
>> #cooling-cells = <2>;
>> cooling-min-level = <0>;
>> diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
>> index 0c12ffc..075d3d1 100644
>> --- a/drivers/cpufreq/cpufreq-cpu0.c
>> +++ b/drivers/cpufreq/cpufreq-cpu0.c
>> @@ -27,6 +27,8 @@
>>
>> static unsigned int transition_latency;
>> static unsigned int voltage_tolerance; /* in percentage */
>> +static unsigned long safe_frequency;
>> +static unsigned long safe_voltage;
>>
>> static struct device *cpu_dev;
>> static struct clk *cpu_clk;
>> @@ -64,17 +66,30 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
>> volt_old = regulator_get_voltage(cpu_reg);
>> }
>>
>> - pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n",
>> + pr_debug("\n\n%u MHz, %ld mV --> %u MHz, %ld mV\n",
>
> This is an unnecessary change?
Yes, sorry missed that.
>
> Otherwise,
>
> Acked-by: Shawn Guo <shawn.guo@linaro.org>
Thanks for your review.
Regards,
Thomas.
>
> Shawn
>
>> old_freq / 1000, volt_old ? volt_old / 1000 : -1,
>> new_freq / 1000, volt ? volt / 1000 : -1);
>>
>> /* scaling up? scale voltage before frequency */
>> - if (!IS_ERR(cpu_reg) && new_freq > old_freq) {
>> + if (!IS_ERR(cpu_reg) && new_freq > old_freq &&
>> + new_freq >= safe_frequency) {
>> ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
>> if (ret) {
>> pr_err("failed to scale voltage up: %d\n", ret);
>> return ret;
>> }
>> + } else if (!IS_ERR(cpu_reg) && old_freq < safe_frequency) {
>> + /*
>> + * the scaled up voltage level for the new_freq is lower
>> + * than the safe voltage level. so set safe_voltage
>> + * as the intermediate voltage level and revert it
>> + * back after the frequency has been changed.
>> + */
>> + ret = regulator_set_voltage_tol(cpu_reg, safe_voltage, tol);
>> + if (ret) {
>> + pr_err("failed to set safe voltage: %d\n", ret);
>> + return ret;
>> + }
>> }
>>
>> ret = clk_set_rate(cpu_clk, freq_exact);
>> @@ -86,7 +101,8 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
>> }
>>
>> /* scaling down? scale voltage after frequency */
>> - if (!IS_ERR(cpu_reg) && new_freq < old_freq) {
>> + if (!IS_ERR(cpu_reg) &&
>> + (new_freq < old_freq || new_freq < safe_frequency)) {
>> ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
>> if (ret) {
>> pr_err("failed to scale voltage down: %d\n", ret);
>> @@ -116,6 +132,8 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {
>>
>> static int cpu0_cpufreq_probe(struct platform_device *pdev)
>> {
>> + const struct property *prop;
>> + struct dev_pm_opp *opp;
>> struct device_node *np;
>> int ret;
>>
>> @@ -165,13 +183,24 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
>> goto out_put_node;
>> }
>>
>> + prop = of_find_property(np, "safe-opp", NULL);
>> + if (prop) {
>> + if (prop->value && (prop->length / sizeof(u32)) == 2) {
>> + const __be32 *val;
>> + val = prop->value;
>> + safe_frequency = be32_to_cpup(val++);
>> + safe_voltage = be32_to_cpup(val);
>> + } else {
>> + pr_err("invalid safe-opp level specified\n");
>> + }
>> + }
>> +
>> of_property_read_u32(np, "voltage-tolerance", &voltage_tolerance);
>>
>> if (of_property_read_u32(np, "clock-latency", &transition_latency))
>> transition_latency = CPUFREQ_ETERNAL;
>>
>> if (!IS_ERR(cpu_reg)) {
>> - struct dev_pm_opp *opp;
>> unsigned long min_uV, max_uV;
>> int i;
>>
>> --
>> 1.6.6.rc2
>>
>
^ permalink raw reply
* [RFC] drivers: irq-chip: Enable SGI's for Secure-to-NonSecure communication use-cases
From: Hiremath, Vaibhav @ 2014-01-28 5:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87wqhl15wi.fsf@nbsps.com>
> -----Original Message-----
> From: Bill Pringlemeir [mailto:bpringlemeir at nbsps.com]
> Sent: Tuesday, January 28, 2014 2:47 AM
> To: Hiremath, Vaibhav
> Cc: linux-arm-kernel at lists.infradead.org
> Subject: Re: [RFC] drivers: irq-chip: Enable SGI's for Secure-to-NonSecure
> communication use-cases
>
>
> > From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
>
> >> So it seems that your intention is to use the existing infrastructure
> >> for this by directing SGIs through the normal IRQ processing.
> >> To that idea, I say no way.
>
> On 6 Jan 2014, hvaibhav at ti.com wrote:
>
> > You have any other alternative?
>
> I think you need to put Bhupesh Sharma's comment with this. The typical sane
> mode for GIC with TZ is to have the monitor mode toggle the IRQ/FIQ routing
> bits in the SCR (cp15) bits 1,2. That is, the IRQ goes direct to core and FIQ goes
> to monitor from the 'Normal' world. In the 'Secure' world, the FIQ goes direct
> to core and IRQ traps to monitor.
> The monitor mode vector table has a gateway from secure to normal for IRQ
> and gateway from normal to secure for FIQ.
>
> Now, consider the 'SMC' instruction and what is present in stuff like this,
>
> http://lwn.net/Articles/513756/
> mach-omap2/{omap-smc.S,omap-secure.c,omap-secure.h}
>
> Instead of messing around with the GIC, why not use something even more
> generic like the 'SMC' instruction. It has the same sort of 'end game'
> which is a trap to monitor mode. The monitor has to be a little smarter to
> determine which world called but this should always be the case; really you want
> to check this.
>
> Btw, the situation is the same no matter which world Linux is in. I don't think
> Linux can be the recipient of an 'SMC' call. But I think most use cases would put
> it in the 'normal world' and the SMC is fine.
>
May be I am missing something here,
I find your above two statements contradictory,
If we want to use SMC as you mentioned, and assuming Secure Monitor mode is intelligent
enough to determine the calling world (whether secure or non-secure),
then without Linux being recipient (in any world) of an 'SMC' call how can realtime switch possible
from secure world to non-secure world??
Just to clarify,
The need here is, to switch from secure world to non-secure world on any realtime (multiple) hardware events,
which in turn gets processed/handled in non-secure world.
In certain cases even we do not want non-secure world know about the hardware event. In this case, the
Processing of hardware event completely happens in secure world, and different event/trigger/info/message
goes to non-secure world. So just manipulating IRQ/FIQ routing will not solve the need here. :)
Thanks,
Vaibhav
^ permalink raw reply
* [PATCH v2 1/7] cpufreq: cpufreq-cpu0: allow optional safe voltage during frequency transitions
From: Thomas Abraham @ 2014-01-28 5:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140127202543.4167.83362@quantum>
Hi Mike,
On Tue, Jan 28, 2014 at 1:55 AM, Mike Turquette <mturquette@linaro.org> wrote:
> Quoting Thomas Abraham (2014-01-18 04:10:51)
>> From: Thomas Abraham <thomas.ab@samsung.com>
>>
>> On some platforms such as the Samsung Exynos, changing the frequency
>> of the CPU clock requires changing the frequency of the PLL that is
>> supplying the CPU clock. To change the frequency of the PLL, the CPU
>> clock is temporarily reparented to another parent clock.
>>
>> The clock frequency of this temporary parent clock could be much higher
>> than the clock frequency of the PLL at the time of reparenting. Due
>> to the temporary increase in the CPU clock speed, the CPU (and any other
>> components in the CPU clock domain such as dividers, mux, etc.) have to
>> to be operated at a higher voltage level, called the safe voltage level.
>> This patch adds optional support to temporarily switch to a safe voltage
>> level during CPU frequency transitions.
>>
>> Cc: Shawn Guo <shawn.guo@linaro.org>
>> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
>
> I'm not a fan of this change. This corner case should be abstracted away
> somehow. I had talked to Chander Kayshap previously about handling
> voltage changes in clock notifier callbacks, which then renders any
> voltage change as a trivial part of the clock rate transition. That
> means that this "safe voltage" thing could be handled automagically
> without any additional code in the CPUfreq driver.
>
> There are two nice ways to do this with the clock framework. First is
> explicit re-parenting with voltage scaling done in the clock rate-change
> notifiers:
>
> clk_set_parent(cpu_clk, temp_parent);
> /* implicit voltage scaling to "safe voltage" happens above */
> clk_set_rate(pll, some_rate);
> clk_set_parent(cpu_clk, pll);
> /* implicit voltage scaling to nominal OPP voltage happens above */
>
> The above sequence would require a separate exnyos CPUfreq driver, due
> to the added clk_set_parent logic.
>
> The second way to do this is to abstract the clk re-muxing logic out
> into the clk driver, which would allow cpufreq-cpu0 to be used for the
> exynos chips.
This is the approach this patch series takes (patch 2/7). The clock
re-muxing logic is handled by a clock driver code. The difference from
what you suggested is that the safe voltage (that may be optionally)
required before doing the re-muxing is handled here in cpufreq-cpu0
driver.
The safe voltage setup can be done in the notifier as you suggested.
But, doing that in cpufreq-cpu0 driver will help other platforms reuse
this feature if required. Also, if done here, the regulator handling
is localized in this driver which otherwise would need to be handled
in two places, cpufreq-cpu0 driver and the clock notifier.
So I tend to prefer the approach in this patch but I am willing to
consider any suggestions. Shawn, it would be helpful if you could let
us know your thoughts on this. I am almost done with testing the v3 of
this series and want to post it so if there are any objections to the
changes in this patch, please let me know.
Thanks,
Thomas.
>
> I'm more a fan of explicitly listing the Exact Steps for the cpu opp
> transition in a separate exynos-specific CPUfreq driver, but that's
> probably an unpopular view.
>
> Regards,
> Mike
>
>> ---
>> .../devicetree/bindings/cpufreq/cpufreq-cpu0.txt | 7 ++++
>> drivers/cpufreq/cpufreq-cpu0.c | 37 +++++++++++++++++--
>> 2 files changed, 40 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> index f055515..37453ab 100644
>> --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> @@ -19,6 +19,12 @@ Optional properties:
>> - cooling-min-level:
>> - cooling-max-level:
>> Please refer to Documentation/devicetree/bindings/thermal/thermal.txt.
>> +- safe-opp: Certain platforms require that during a opp transition,
>> + a system should not go below a particular opp level. For such systems,
>> + this property specifies the minimum opp to be maintained during the
>> + opp transitions. The safe-opp value is a tuple with first element
>> + representing the safe frequency and the second element representing the
>> + safe voltage.
>>
>> Examples:
>>
>> @@ -36,6 +42,7 @@ cpus {
>> 396000 950000
>> 198000 850000
>> >;
>> + safe-opp = <396000 950000>
>> clock-latency = <61036>; /* two CLK32 periods */
>> #cooling-cells = <2>;
>> cooling-min-level = <0>;
>> diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
>> index 0c12ffc..075d3d1 100644
>> --- a/drivers/cpufreq/cpufreq-cpu0.c
>> +++ b/drivers/cpufreq/cpufreq-cpu0.c
>> @@ -27,6 +27,8 @@
>>
>> static unsigned int transition_latency;
>> static unsigned int voltage_tolerance; /* in percentage */
>> +static unsigned long safe_frequency;
>> +static unsigned long safe_voltage;
>>
>> static struct device *cpu_dev;
>> static struct clk *cpu_clk;
>> @@ -64,17 +66,30 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
>> volt_old = regulator_get_voltage(cpu_reg);
>> }
>>
>> - pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n",
>> + pr_debug("\n\n%u MHz, %ld mV --> %u MHz, %ld mV\n",
>> old_freq / 1000, volt_old ? volt_old / 1000 : -1,
>> new_freq / 1000, volt ? volt / 1000 : -1);
>>
>> /* scaling up? scale voltage before frequency */
>> - if (!IS_ERR(cpu_reg) && new_freq > old_freq) {
>> + if (!IS_ERR(cpu_reg) && new_freq > old_freq &&
>> + new_freq >= safe_frequency) {
>> ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
>> if (ret) {
>> pr_err("failed to scale voltage up: %d\n", ret);
>> return ret;
>> }
>> + } else if (!IS_ERR(cpu_reg) && old_freq < safe_frequency) {
>> + /*
>> + * the scaled up voltage level for the new_freq is lower
>> + * than the safe voltage level. so set safe_voltage
>> + * as the intermediate voltage level and revert it
>> + * back after the frequency has been changed.
>> + */
>> + ret = regulator_set_voltage_tol(cpu_reg, safe_voltage, tol);
>> + if (ret) {
>> + pr_err("failed to set safe voltage: %d\n", ret);
>> + return ret;
>> + }
>> }
>>
>> ret = clk_set_rate(cpu_clk, freq_exact);
>> @@ -86,7 +101,8 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
>> }
>>
>> /* scaling down? scale voltage after frequency */
>> - if (!IS_ERR(cpu_reg) && new_freq < old_freq) {
>> + if (!IS_ERR(cpu_reg) &&
>> + (new_freq < old_freq || new_freq < safe_frequency)) {
>> ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
>> if (ret) {
>> pr_err("failed to scale voltage down: %d\n", ret);
>> @@ -116,6 +132,8 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {
>>
>> static int cpu0_cpufreq_probe(struct platform_device *pdev)
>> {
>> + const struct property *prop;
>> + struct dev_pm_opp *opp;
>> struct device_node *np;
>> int ret;
>>
>> @@ -165,13 +183,24 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
>> goto out_put_node;
>> }
>>
>> + prop = of_find_property(np, "safe-opp", NULL);
>> + if (prop) {
>> + if (prop->value && (prop->length / sizeof(u32)) == 2) {
>> + const __be32 *val;
>> + val = prop->value;
>> + safe_frequency = be32_to_cpup(val++);
>> + safe_voltage = be32_to_cpup(val);
>> + } else {
>> + pr_err("invalid safe-opp level specified\n");
>> + }
>> + }
>> +
>> of_property_read_u32(np, "voltage-tolerance", &voltage_tolerance);
>>
>> if (of_property_read_u32(np, "clock-latency", &transition_latency))
>> transition_latency = CPUFREQ_ETERNAL;
>>
>> if (!IS_ERR(cpu_reg)) {
>> - struct dev_pm_opp *opp;
>> unsigned long min_uV, max_uV;
>> int i;
>>
>> --
>> 1.6.6.rc2
>>
^ permalink raw reply
* [PATCH] arm64: add DSB after icache flush in __flush_icache_all()
From: Vinayak Kale @ 2014-01-28 5:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140127121613.GB6547@mudshark.cambridge.arm.com>
On Mon, Jan 27, 2014 at 5:46 PM, Will Deacon <will.deacon@arm.com> wrote:
> Hi Vinayak,
>
> On Mon, Jan 27, 2014 at 11:59:44AM +0000, Vinayak Kale wrote:
>> Add DSB after icache flush operation.
>
> Please elaborate a bit on what this achieves (i.e. completion of the
> maintenance operation).
Okay.
>
>> Signed-off-by: Vinayak Kale <vkale@apm.com>
>> ---
>> arch/arm64/include/asm/cacheflush.h | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
>> index fea9ee3..88932498 100644
>> --- a/arch/arm64/include/asm/cacheflush.h
>> +++ b/arch/arm64/include/asm/cacheflush.h
>> @@ -116,6 +116,7 @@ extern void flush_dcache_page(struct page *);
>> static inline void __flush_icache_all(void)
>> {
>> asm("ic ialluis");
>
> This needs a "memory" clobber to prevent re-ordering by GCC. We should
> probably check the rest of the code for other occurrences of this too.
Okay.
>
>> + dsb();
>
> Can you make a corresponding change for arch/arm/ too, please? I think we're
> missing the barrier there as well.
I could have, but I don't have hardware to test it on.
>
> Will
^ permalink raw reply
* [PATCH] arm64: add DSB after icache flush in __flush_icache_all()
From: Vinayak Kale @ 2014-01-28 5:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140127122536.GE32608@arm.com>
On Mon, Jan 27, 2014 at 5:55 PM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Mon, Jan 27, 2014 at 11:59:44AM +0000, Vinayak Kale wrote:
>> Add DSB after icache flush operation.
>>
>> Signed-off-by: Vinayak Kale <vkale@apm.com>
>
> I think we should also mention that this function is used for user
> addresses and an ISB is not required because of an exception return
> before executing user instructions.
Okay, will mention this. Thanks.
>
> --
> Catalin
^ permalink raw reply
* [PATCH] clk: remove unnecessary substitution
From: Masahiro Yamada @ 2014-01-28 6:09 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
---
drivers/clk/clk.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 2b38dc9..d97b313 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1637,7 +1637,7 @@ static struct clk *__clk_init_parent(struct clk *clk)
if (clk->num_parents == 1) {
if (IS_ERR_OR_NULL(clk->parent))
- ret = clk->parent = __clk_lookup(clk->parent_names[0]);
+ clk->parent = __clk_lookup(clk->parent_names[0]);
ret = clk->parent;
goto out;
}
--
1.8.3.2
^ 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