* [PATCH 1/2] soc: ti: knav_dma: fix typos in trace message
From: Santosh Shilimkar @ 2016-12-21 1:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482272663-29829-1-git-send-email-m-karicheri2@ti.com>
On 12/20/2016 2:24 PM, Murali Karicheri wrote:
> This patch fixes some typos in the trace message
>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
> ---
Patch 1 and 2 looks fine. Will pick them for next
merge window. Thanks !!
Regards,
Santosh
^ permalink raw reply
* [PATCH v2] rtc: armada38x: Followed the new recommendation for errata implementation
From: Alexandre Belloni @ 2016-12-21 0:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161213112510.25692-1-gregory.clement@free-electrons.com>
Hi,
On 13/12/2016 at 12:25:10 +0100, Gregory CLEMENT wrote :
> According to RES-3124064:
>
> The device supports CPU write and read access to the RTC time register.
> However, due to this restriction, read and write from/to internal RTC
> register may fail.
>
> Workaround:
> General setup:
> 1. Configure the RTC Mbus Bridge Timing Control register (offset 0x184A0)
> to value 0xFD4D4FFF
> Write RTC WRCLK Period to its maximum value (0x3FF)
> Write RTC WRCLK setup to 0x29
> Write RTC WRCLK High Time to 0x53 (default value)
> Write RTC Read Output Delay to its maximum value (0x1F)
> Mbus - Read All Byte Enable to 0x1 (default value)
> 2. Configure the RTC Test Configuration Register (offset 0xA381C) bit3
> to '1' (Reserved, Marvell internal)
>
> For any RTC register read operation:
> 1. Read the requested register 100 times.
> 2. Find the result that appears most frequently and use this result
> as the correct value.
>
> For any RTC register write operation:
> 1. Issue two dummy writes of 0x0 to the RTC Status register (offset
> 0xA3800).
> 2. Write the time to the RTC Time register (offset 0xA380C).
>
> This patch is based on the work of Shaker Daibes
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> Hi,
>
> this patch followed the patch series sent here:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-December/473232.html
>
> For now I kept the patch 2 converting to time64_t apart after Russell
> King feedback.
>
> I merged the patch 1 and 3 and I also substantially modified the 1st
> patch with I think a better implementation.
>
> - First I do not put anymore more a big array onto the stack as
> suggested by Andrew Lunn.
> - Then I optimize the way to find the correct value.
>
> Gregory
>
>
> drivers/rtc/rtc-armada38x.c | 121 +++++++++++++++++++++++++++++++++++---------
> 1 file changed, 97 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
> index 9a3f2a6f512e..458ef8da0484 100644
> --- a/drivers/rtc/rtc-armada38x.c
> +++ b/drivers/rtc/rtc-armada38x.c
> @@ -29,50 +29,119 @@
> #define RTC_TIME 0xC
> #define RTC_ALARM1 0x10
>
> +#define SOC_RTC_BRIDGE_TIMING_CTL 0x0
> +#define SOC_RTC_PERIOD_OFFS 0
> +#define SOC_RTC_PERIOD_MASK (0x3FF << SOC_RTC_PERIOD_OFFS)
> +#define SOC_RTC_READ_DELAY_OFFS 26
> +#define SOC_RTC_READ_DELAY_MASK (0x1F << SOC_RTC_READ_DELAY_OFFS)
> +
> #define SOC_RTC_INTERRUPT 0x8
> #define SOC_RTC_ALARM1 BIT(0)
> #define SOC_RTC_ALARM2 BIT(1)
> #define SOC_RTC_ALARM1_MASK BIT(2)
> #define SOC_RTC_ALARM2_MASK BIT(3)
>
> +
Unnecessary blank line ;)
> +#define SAMPLE_NR 100
> +
> +struct value_to_freq {
> + u32 value;
> + u8 freq;
> +};
> +
> struct armada38x_rtc {
> struct rtc_device *rtc_dev;
> void __iomem *regs;
> void __iomem *regs_soc;
> spinlock_t lock;
> int irq;
> + struct value_to_freq *val_to_freq;
> };
>
> /*
> * According to the datasheet, the OS should wait 5us after every
> * register write to the RTC hard macro so that the required update
> * can occur without holding off the system bus
> + * According to errata FE-3124064, Write to any RTC register
> + * may fail. As a workaround, before writing to RTC
> + * register, issue a dummy write of 0x0 twice to RTC Status
> + * register.
> */
> +
> static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
> {
> + writel(0, rtc->regs + RTC_STATUS);
> + writel(0, rtc->regs + RTC_STATUS);
> writel(val, rtc->regs + offset);
> udelay(5);
> }
>
> +/* Update RTC-MBUS bridge timing parameters */
> +static void rtc_update_mbus_timing_params(struct armada38x_rtc *rtc)
> +{
> + uint32_t reg;
> +
u32 is preferable.
[...]
> @@ -182,7 +244,7 @@ static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data)
> val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
>
> writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT);
> - val = readl(rtc->regs + RTC_IRQ1_CONF);
> + val = read_rtc_register_wa(rtc, RTC_IRQ1_CONF);
> /* disable all the interrupts for alarm 1 */
> rtc_delayed_write(0, rtc, RTC_IRQ1_CONF);
> /* Ack the event */
> @@ -196,7 +258,6 @@ static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data)
> else
> event |= RTC_PF;
> }
> -
Unrelated change.
> rtc_update_irq(rtc->rtc_dev, 1, event);
>
> return IRQ_HANDLED;
> @@ -221,6 +282,11 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
> if (!rtc)
> return -ENOMEM;
>
> + rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR,
> + sizeof(struct value_to_freq), GFP_KERNEL);
> + if (!rtc->val_to_freq)
> + return -ENOMEM;
> +
The whole struct armada38x_rtc is already allocated just before. Maybe
you can put the whole array inside the structure instead of doing a new
allocation.
> spin_lock_init(&rtc->lock);
>
> res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
> @@ -253,6 +319,9 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
> if (rtc->irq != -1)
> device_init_wakeup(&pdev->dev, 1);
>
> + /* Update RTC-MBUS bridge timing parameters */
> + rtc_update_mbus_timing_params(rtc);
> +
> rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
> &armada38x_rtc_ops, THIS_MODULE);
> if (IS_ERR(rtc->rtc_dev)) {
> @@ -260,6 +329,7 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
> dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
> return ret;
> }
> +
Unrelated change.
> return 0;
> }
>
> @@ -280,6 +350,9 @@ static int armada38x_rtc_resume(struct device *dev)
> if (device_may_wakeup(dev)) {
> struct armada38x_rtc *rtc = dev_get_drvdata(dev);
>
> + /* Update RTC-MBUS bridge timing parameters */
> + rtc_update_mbus_timing_params(rtc);
> +
> return disable_irq_wake(rtc->irq);
> }
>
> --
> 2.10.2
>
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
From: Tony Lindgren @ 2016-12-20 23:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161220225627.GF5423@codeaurora.org>
* Stephen Boyd <sboyd@codeaurora.org> [161220 14:56]:
> On 12/19, Tero Kristo wrote:
> > First thing to do here would be to implement the hwmod genpds, rest
> > can follow later, but we need an agreement if this is the way we
> > want to go.
>
> Ok. I guess we're just waiting on Tony then?
Sounds right to me except for the hwmod genpd part.. We don't want to
pile up any new code to mach-omap2 but instead we want to make the
hwmod code into proper interconnect driver. As long as we do it that
way, sounds good to me.
Regards,
Tony
^ permalink raw reply
* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
From: Stephen Boyd @ 2016-12-20 22:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <88baee5e-48c3-f0d3-de5e-8e578fab0aa4@ti.com>
On 12/19, Tero Kristo wrote:
> On 17/12/16 03:46, Stephen Boyd wrote:
> >On 12/13, Tero Kristo wrote:
> >>On 13/12/16 06:40, Michael Turquette wrote:
> >>>>>On 12/12, Michael Turquette wrote:
> >>>
> >>>Is the goal to describe this hardware topology in DT? Is that right
> >>>thing to do? I think it's cool to have this modeled *somehow* in Linux,
> >>>but I'm not sure DT is the right place to model the interconnect and
> >>>every device hanging off of it.
> >>>
> >>>I don't want to put words in Stephen's mouth, but I think the issue over
> >>>whether clockdomains are CCF clock providers or some genpd thing is
> >>>probably less important to him than the fact that the DT bindings are
> >>>super detailed to inner workings of the SoC.
> >>
> >>Ok, so your preference would be to reduce the data under DT, and the
> >>ideal approach would be a single prcm node. I think we still need to
> >>keep the prm / cm1 / cm2 as separate nodes, as they are pretty
> >>individual from hardware point of view, provide quite different
> >>features, and they reside in some cases in quite different address
> >>spaces also. Anyway, here's what I gather we should probably have in
> >>DT:
> >>
> >>- reset provider
> >> * example: resets = <&prm OMAP4_IVA2_RESET>;
> >> * only from 'prm' node
> >>
> >>- genpd provider (for the hwmods, clockdomains, powerdomains,
> >>voltage domains)
> >> * examples: power-domains = <&cm2 OMAP4_DSS_CORE_MOD>;
> >> power-domains = <&cm2 OMAP4_DSS_CLKDM>;
> >> power-domains = <&prm OMAP4_DSS_PWRDM>;
> >> power-domains = <&prm OMAP4_CORE_VOLTDM>;
> >> * from all 'prm', 'cm1' and 'cm2' nodes, though 'prm' would be the
> >>only one providing _CLKDM, _PWRDM, _VOLTDM genpds.
> >>
> >>- clock provider (for anything that requires clocks)
> >> * example: clocks = <&cm1 OMAP4_DPLL_MPU_CK>;
> >> * from all 'prm', 'cm1' and 'cm2' nodes
> >>
> >>This would eventually cause an ABI breakage for the clock handles,
> >>if we transfer the existing clocks to this format, and remove the
> >>existing clock handles from DT. Otherwise, I think we could just
> >>transition the existing hwmod data to this new format only, and add
> >>the clockdomain / powerdomain / voltagedomain support a bit later.
> >>
> >
> >This sounds about right. Is the ABI break because we get rid of
> >clock nodes and just have a few big nodes?
>
> In the above plan, the ABI breakage is because we get rid of the
> existing clock nodes and replace everything with a single (or few)
> clock provider nodes.
Thanks for confirming.
>
> >I thought we had
> >already broken DT ABI here but if we didn't then that isn't
> >great. Perhaps to make things keep working we can detect the old
> >style one node per clock design and register a bunch of providers
> >individually from the single driver probe? It would have to match
> >up the registers with a clk_hw pointer somewhere, but it should
> >be possible. Alternatively, we keep both designs around for some
> >time and have different compatibles and different driver entry
> >points.
>
> Keeping both around for a while should be okay, the design for this
> series was done with that in mind. I didn't address the scrapping of
> old clock data yet though, but that would be a step taken in the
> future.
>
> First thing to do here would be to implement the hwmod genpds, rest
> can follow later, but we need an agreement if this is the way we
> want to go.
Ok. I guess we're just waiting on Tony then?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH v4 2/2] cpufreq: brcmstb-cpufreq: CPUfreq driver for older Broadcom STB SoCs
From: Markus Mayer @ 2016-12-20 22:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161220225530.96699-1-code@mmayer.net>
From: Markus Mayer <mmayer@broadcom.com>
This CPUfreq driver provides basic frequency scaling for older Broadcom
STB SoCs that do not use AVS firmware with DVFS support. There is no
support for voltage scaling.
Signed-off-by: Markus Mayer <mmayer@broadcom.com>
---
drivers/cpufreq/Kconfig.arm | 12 ++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/brcmstb-cpufreq.c | 377 ++++++++++++++++++++++++++++++++++++++
3 files changed, 390 insertions(+)
create mode 100644 drivers/cpufreq/brcmstb-cpufreq.c
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 920c469..36422af 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -33,6 +33,18 @@ config ARM_BRCMSTB_AVS_CPUFREQ_DEBUG
If in doubt, say N.
+config ARM_BRCMSTB_CPUFREQ
+ tristate "Broadcom STB CPUfreq driver"
+ depends on ARCH_BRCMSTB || COMPILE_TEST
+ default y
+ help
+ Some Broadcom SoCs offer multiple operating frequencies that CPUfreq
+ can take advantage of to improve energy efficiency.
+
+ Say Y, if you have a supported Broadcom SoC. If your Broadcom SoC
+ has AVS firmware with support for frequency and voltage scaling,
+ say N here and enable ARM_BRCMSTB_AVS_CPUFREQ instead.
+
config ARM_DT_BL_CPUFREQ
tristate "Generic probing via DT for ARM big LITTLE CPUfreq driver"
depends on ARM_BIG_LITTLE_CPUFREQ && OF
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 1e46c39..23700aa 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ) += arm_big_little.o
obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o
obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ) += brcmstb-avs-cpufreq.o
+obj-$(CONFIG_ARM_BRCMSTB_CPUFREQ) += brcmstb-cpufreq.o
obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o
obj-$(CONFIG_UX500_SOC_DB8500) += dbx500-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
diff --git a/drivers/cpufreq/brcmstb-cpufreq.c b/drivers/cpufreq/brcmstb-cpufreq.c
new file mode 100644
index 0000000..80ac1ae
--- /dev/null
+++ b/drivers/cpufreq/brcmstb-cpufreq.c
@@ -0,0 +1,377 @@
+/*
+ * CPU frequency scaling for Broadcom set top box SoCs
+ *
+ * Copyright (c) 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/cpufreq.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#define BRCMSTB_CPUFREQ_PREFIX "brcmstb"
+#define BRCMSTB_CPUFREQ_NAME BRCMSTB_CPUFREQ_PREFIX "-cpufreq"
+
+/* We search for these compatible strings. */
+#define BRCMSTB_DT_CPU_CLK_CTRL "brcm,brcmstb-cpu-clk-div"
+#define BRCMSTB_DT_MEMC_DDR "brcm,brcmstb-memc-ddr"
+#define BRCM_AVS_CPU_DATA "brcm,avs-cpu-data-mem"
+
+/*
+ * We also need a few clocks in device tree. They are referenced in the
+ * brcm,brcmstb-cpu-clk-div node in device tree, so we can look them up.
+ */
+#define BRCMSTB_CLK_MDIV_CH0 "cpu_mdiv_ch0"
+#define BRCMSTB_CLK_NDIV_INT "cpu_ndiv_int"
+#define BRCMSTB_CLK_SW_SCB "sw_scb"
+
+#define BRCMSTB_TBL_SAFE_MODE BIT(0)
+#define BRCMSTB_REG_SAFE_MODE BIT(4)
+
+#define TRANSITION_LATENCY (25 * 1000) /* 25 us */
+
+/* This is as low as we'll go in the frequency table. */
+#define MIN_CPU_FREQ (100 * 1000) /* in kHz */
+
+struct private_data {
+ void __iomem *cpu_clk_ctrl_reg;
+ struct clk *mdiv_clk;
+ struct clk *ndiv_clk;
+ struct clk *sw_scb_clk;
+ struct device *dev;
+};
+
+/* Count the active memory controllers in the system. */
+static int count_memory_controllers(void)
+{
+ struct device_node *np = NULL;
+ int i = 0;
+
+ do {
+ np = of_find_compatible_node(np, NULL, BRCMSTB_DT_MEMC_DDR);
+ if (of_device_is_available(np))
+ i++;
+ of_node_put(np);
+ } while (np);
+
+ return i;
+}
+
+static void get_frequencies(const struct cpufreq_policy *policy,
+ unsigned int *vco_freq, unsigned int *cpu_freq,
+ unsigned int *scb_freq)
+{
+ struct private_data *priv = policy->driver_data;
+
+ /* return frequencies in kHz */
+ *vco_freq = clk_get_rate(priv->ndiv_clk) / 1000;
+ *cpu_freq = clk_get_rate(priv->mdiv_clk) / 1000;
+ *scb_freq = clk_get_rate(priv->sw_scb_clk) / 1000;
+}
+
+/*
+ * Safe mode: When set, the CPU's bus unit is being throttled. This is done to
+ * avoid buffer overflows when the CPU-to-bus-clock ratio is low.
+ *
+ * The formula as to what constitutes a low CPU-to-bus-clock ratio takes into
+ * account the number of memory controllers active in the system and the SCB
+ * frequency. More memory controllers means safe mode is required starting at
+ * higher frequencies.
+ *
+ * For 1 memory controller, cpu_freq/scb_freq must be greater than or equal to
+ * 2 to not require safe mode.
+ *
+ * For 2 or 3 memory controllers, cpu_freq/scb_freq must be greater than or
+ * equal 3 to not require safe mode.
+ */
+
+static int freq_requires_safe_mode(unsigned int cpu_freq, unsigned int scb_freq,
+ int num_memc)
+{
+ unsigned int safe_ratio;
+
+ switch (num_memc) {
+ case 1:
+ safe_ratio = 2;
+ break;
+ case 2:
+ case 3:
+ safe_ratio = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ((cpu_freq / scb_freq) < safe_ratio);
+}
+
+static struct cpufreq_frequency_table *
+brcmstb_get_freq_table(const struct cpufreq_policy *policy)
+{
+ unsigned int cpu_freq, vco_freq, scb_freq, mdiv, init_mdiv, f;
+ struct cpufreq_frequency_table *table;
+ struct private_data *priv;
+ int num_memc, ret;
+ unsigned int i = 0;
+
+ priv = policy->driver_data;
+ num_memc = count_memory_controllers();
+ get_frequencies(policy, &vco_freq, &cpu_freq, &scb_freq);
+
+ /* Calculate the initial mdiv value. We'll increment mdiv from here. */
+ init_mdiv = vco_freq / cpu_freq;
+
+ /* Count how many frequencies we'll offer. */
+ f = cpu_freq;
+ for (mdiv = init_mdiv; f >= MIN_CPU_FREQ; mdiv++, f = vco_freq / mdiv) {
+ /* We only want to use "whole" MHz. */
+ if ((f % 1000) == 0)
+ i++;
+ }
+
+ table = devm_kzalloc(priv->dev, (i + 1) * sizeof(*table), GFP_KERNEL);
+ if (!table)
+ return ERR_PTR(-ENOMEM);
+
+ /* Now, fill the table. */
+ f = cpu_freq;
+ i = 0;
+ for (mdiv = init_mdiv; f >= MIN_CPU_FREQ; mdiv++, f = vco_freq / mdiv) {
+ if ((f % 1000) == 0) {
+ table[i].frequency = f;
+ ret = freq_requires_safe_mode(f, scb_freq, num_memc);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ if (ret > 0)
+ table[i].driver_data |= BRCMSTB_TBL_SAFE_MODE;
+ i++;
+ }
+ }
+ table[i].frequency = CPUFREQ_TABLE_END;
+
+ return table;
+}
+
+static int brcmstb_target_index(struct cpufreq_policy *policy,
+ unsigned int index)
+{
+ struct cpufreq_frequency_table *entry;
+ struct private_data *priv;
+ int ret, safe_mode_needed;
+ u32 reg;
+
+ priv = policy->driver_data;
+ entry = &policy->freq_table[index];
+ safe_mode_needed = entry->driver_data & BRCMSTB_TBL_SAFE_MODE;
+
+ reg = readl(priv->cpu_clk_ctrl_reg);
+ if (safe_mode_needed && !(reg & BRCMSTB_REG_SAFE_MODE)) {
+ reg |= BRCMSTB_REG_SAFE_MODE;
+ writel(reg, priv->cpu_clk_ctrl_reg);
+ }
+ ret = clk_set_rate(policy->clk, entry->frequency * 1000);
+ if (!ret && !safe_mode_needed && (reg & BRCMSTB_REG_SAFE_MODE)) {
+ reg &= ~BRCMSTB_REG_SAFE_MODE;
+ writel(reg, priv->cpu_clk_ctrl_reg);
+ }
+
+ return ret;
+}
+
+/*
+ * All initialization code that we only want to execute once goes here. Setup
+ * code that can be re-tried on every core (if it failed before) can go into
+ * brcmstb_cpufreq_init().
+ */
+static int brcmstb_prepare_init(struct platform_device *pdev)
+{
+ struct private_data *priv;
+ struct resource *res;
+ struct device *dev;
+
+ /*
+ * If the BRCM STB AVS CPUfreq driver is supported, we bail, so that
+ * the more modern approach implementing DVFS in firmware can be used.
+ */
+ if (IS_ENABLED(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)) {
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, BRCM_AVS_CPU_DATA);
+ if (np) {
+ of_node_put(np);
+ return -ENXIO;
+ }
+ }
+
+ dev = &pdev->dev;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->cpu_clk_ctrl_reg = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->cpu_clk_ctrl_reg)) {
+ dev_err(dev, "couldn't map DT entry %s\n",
+ BRCMSTB_DT_CPU_CLK_CTRL);
+ return -ENODEV;
+ }
+
+ priv->mdiv_clk = devm_clk_get(dev, BRCMSTB_CLK_MDIV_CH0);
+ priv->ndiv_clk = devm_clk_get(dev, BRCMSTB_CLK_NDIV_INT);
+ priv->sw_scb_clk = devm_clk_get(dev, BRCMSTB_CLK_SW_SCB);
+
+ if (IS_ERR(priv->mdiv_clk))
+ return PTR_ERR(priv->mdiv_clk);
+ if (IS_ERR(priv->ndiv_clk))
+ return PTR_ERR(priv->ndiv_clk);
+ if (IS_ERR(priv->sw_scb_clk))
+ return PTR_ERR(priv->sw_scb_clk);
+
+ priv->dev = dev;
+ platform_set_drvdata(pdev, priv);
+
+ return 0;
+}
+
+static int brcmstb_cpufreq_init(struct cpufreq_policy *policy)
+{
+ struct cpufreq_frequency_table *freq_table;
+ struct platform_device *pdev;
+ struct private_data *priv;
+ struct device *dev;
+ int ret;
+
+ pdev = cpufreq_get_driver_data();
+ priv = platform_get_drvdata(pdev);
+ dev = &pdev->dev;
+
+ policy->clk = priv->mdiv_clk;
+ policy->driver_data = priv;
+
+ freq_table = brcmstb_get_freq_table(policy);
+ if (IS_ERR(freq_table)) {
+ ret = PTR_ERR(freq_table);
+ dev_err(dev, "Couldn't determine frequency table (%d).\n", ret);
+ if (ret == -EINVAL)
+ dev_emerg(dev,
+ "Invalid number of memory controllers -- %d!\n",
+ count_memory_controllers());
+ return ret;
+ }
+
+ ret = cpufreq_generic_init(policy, freq_table, TRANSITION_LATENCY);
+ if (!ret)
+ dev_info(dev, "registered\n");
+
+ return ret;
+}
+
+/* Shows the number of memory controllers. */
+static ssize_t show_brcmstb_num_memc(struct cpufreq_policy *policy, char *buf)
+{
+ return sprintf(buf, "%u\n", count_memory_controllers());
+}
+
+/* Shows vco_freq, cpu_freq, and scb_freq in kHz. */
+static ssize_t show_brcmstb_freqs(struct cpufreq_policy *policy, char *buf)
+{
+ unsigned int vco_freq, cpu_freq, scb_freq;
+
+ get_frequencies(policy, &vco_freq, &cpu_freq, &scb_freq);
+
+ return sprintf(buf, "%u %u %u\n", vco_freq, cpu_freq, scb_freq);
+}
+
+/* Shows the lowest frequency (in kHz) that can be used without "safe mode". */
+static ssize_t show_brcmstb_safe_freq(struct cpufreq_policy *policy, char *buf)
+{
+ struct cpufreq_frequency_table *entry;
+ unsigned int safe_freq = 0;
+
+ cpufreq_for_each_valid_entry(entry, policy->freq_table) {
+ if (!(entry->driver_data & BRCMSTB_TBL_SAFE_MODE))
+ safe_freq = entry->frequency;
+ }
+
+ return sprintf(buf, "%u\n", safe_freq);
+}
+
+cpufreq_freq_attr_ro(brcmstb_num_memc);
+cpufreq_freq_attr_ro(brcmstb_freqs);
+cpufreq_freq_attr_ro(brcmstb_safe_freq);
+
+static struct freq_attr *brcmstb_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ &brcmstb_num_memc,
+ &brcmstb_freqs,
+ &brcmstb_safe_freq,
+ NULL
+};
+
+static struct cpufreq_driver brcmstb_driver = {
+ .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+ .verify = cpufreq_generic_frequency_table_verify,
+ .target_index = brcmstb_target_index,
+ .get = cpufreq_generic_get,
+ .init = brcmstb_cpufreq_init,
+ .attr = brcmstb_cpufreq_attr,
+ .name = BRCMSTB_CPUFREQ_PREFIX,
+};
+
+static int brcmstb_cpufreq_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = brcmstb_prepare_init(pdev);
+ if (ret)
+ return ret;
+
+ brcmstb_driver.driver_data = pdev;
+
+ return cpufreq_register_driver(&brcmstb_driver);
+}
+
+static int brcmstb_cpufreq_remove(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = cpufreq_unregister_driver(&brcmstb_driver);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id brcmstb_cpufreq_match[] = {
+ { .compatible = BRCMSTB_DT_CPU_CLK_CTRL },
+ { }
+};
+MODULE_DEVICE_TABLE(of, brcmstb_cpufreq_match);
+
+static struct platform_driver brcmstb_cpufreq_platdrv = {
+ .driver = {
+ .name = BRCMSTB_CPUFREQ_NAME,
+ .of_match_table = brcmstb_cpufreq_match,
+ },
+ .probe = brcmstb_cpufreq_probe,
+ .remove = brcmstb_cpufreq_remove,
+};
+module_platform_driver(brcmstb_cpufreq_platdrv);
+
+MODULE_AUTHOR("Markus Mayer <mmayer@broadcom.com>");
+MODULE_DESCRIPTION("CPUfreq driver for Broadcom STB SoCs");
+MODULE_LICENSE("GPL");
--
2.7.4
^ permalink raw reply related
* [PATCH v4 1/2] dt-bindings: brcm: clocks: add binding for brcmstb-cpu-clk-div
From: Markus Mayer @ 2016-12-20 22:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161220225530.96699-1-code@mmayer.net>
From: Markus Mayer <mmayer@broadcom.com>
Add binding document for brcm,brcmstb-cpu-clk-div.
Signed-off-by: Markus Mayer <mmayer@broadcom.com>
---
.../bindings/clock/brcm,brcmstb-cpu-clk-div.txt | 83 ++++++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 84 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/brcm,brcmstb-cpu-clk-div.txt
diff --git a/Documentation/devicetree/bindings/clock/brcm,brcmstb-cpu-clk-div.txt b/Documentation/devicetree/bindings/clock/brcm,brcmstb-cpu-clk-div.txt
new file mode 100644
index 0000000..3bc99c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/brcm,brcmstb-cpu-clk-div.txt
@@ -0,0 +1,83 @@
+The CPU divider node serves as the sole clock for the CPU complex. It supports
+power-of-2 clock division, with a divider of "1" as the default highest-speed
+setting.
+
+Required properties:
+- compatible: shall be "brcm,brcmstb-cpu-clk-div"
+- reg: address and width of the divider configuration register
+- #clock-cells: shall be set to 0
+- clocks: phandle of clock provider which provides the source clock
+ (this would typically be a "fixed-clock" type PLL)
+- div-table: list of (raw_value,divider) ordered pairs that correspond to the
+ allowed clock divider settings
+- div-shift-width: least-significant bit position and width of divider value
+
+Optional properties:
+- clocks: additional clocks can be specified if needed
+- clock-names: clocks can be named, so they can be looked up
+
+Example:
+ sw_scb: sw_scb {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <432000000>;
+ };
+
+ fixed0: fixed0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <54000000>;
+ };
+
+ cpu_pdiv: cpu_pdiv at f04e0008 {
+ compatible = "divider-clock";
+ #clock-cells = <0>;
+ reg = <0xf04e0008 0x4>;
+ bit-shift = <10>;
+ bit-mask = <0xf>;
+ index-starts-at-one;
+ clocks = <&fixed0>;
+ clock-names = "fixed0";
+ };
+
+ cpu_ndiv_int: cpu_ndiv_int {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <167>;
+ clocks = <&cpu_pdiv>;
+ clock-names = "cpu_pdiv";
+ };
+
+ cpu_mdiv_ch0: cpu_mdiv_ch0 at f04e0000 {
+ compatible = "divider-clock";
+ #clock-cells = <0>;
+ reg = <0xf04e0000 0x4>;
+ bit-shift = <1>;
+ bit-mask = <0xff>;
+ index-starts-at-one;
+ clocks = <&cpu_ndiv_int>;
+ clock-names = "cpu_ndiv_int";
+ };
+
+ cpupll: cpupll at 0 {
+ #clock-cells = <0>;
+ clock-frequency = <1503000000>;
+ compatible = "fixed-clock";
+ };
+
+ cpuclkdiv: cpu-clk-div at 0 {
+ #clock-cells = <0>;
+ clock-names = "cpupll",
+ "cpu_mdiv_ch0",
+ "cpu_ndiv_int",
+ "sw_scb";
+ clocks = <&cpupll,
+ &cpu_mdiv_ch0,
+ &cpu_ndiv_int,
+ &sw_scb>;
+ compatible = "brcm,brcmstb-cpu-clk-div";
+ reg = <0xf03e257c 0x4>;
+ div-table = <0x00 1>;
+ div-shift-width = <0 5>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index f6eb97b..5473b31 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2786,6 +2786,7 @@ M: bcm-kernel-feedback-list at broadcom.com
L: linux-pm at vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt
+F: Documentation/devicetree/bindings/clock/brcm,brcmstb-cpu-clk-div.txt
F: drivers/cpufreq/brcmstb*
BROADCOM SPECIFIC AMBA DRIVER (BCMA)
--
2.7.4
^ permalink raw reply related
* [PATCH v4 0/2] cpufreq: brcmstb-cpufreq: CPUfreq driver for older Broadcom STB SoCs
From: Markus Mayer @ 2016-12-20 22:55 UTC (permalink / raw)
To: linux-arm-kernel
From: Markus Mayer <mmayer@broadcom.com>
This CPUfreq driver provides basic frequency scaling for older Broadcom
STB SoCs that do not use AVS firmware with DVFS support. There is no
support for voltage scaling.
v3 of this patch can be found here: https://lkml.org/lkml/2016/11/22/747
Changes since v3:
- added binding document
- got rid of calls to __clk_lookup(), using devm_clk_get() instead
- re-worked clock lookup code a bit, along with switching to devm_clk_get()
- get_frequencies() became a void function, removing the need for some
error checking
- fixed CONFIG_ARM_BRCM_AVS_CPUFREQ typo
- fixed MODULE_DEVICE_TABLE declaration
Markus Mayer (2):
dt-bindings: brcm: clocks: add binding for brcmstb-cpu-clk-div
cpufreq: brcmstb-cpufreq: CPUfreq driver for older Broadcom STB SoCs
.../bindings/clock/brcm,brcmstb-cpu-clk-div.txt | 83 +++++
MAINTAINERS | 1 +
drivers/cpufreq/Kconfig.arm | 12 +
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/brcmstb-cpufreq.c | 377 +++++++++++++++++++++
5 files changed, 474 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/brcm,brcmstb-cpu-clk-div.txt
create mode 100644 drivers/cpufreq/brcmstb-cpufreq.c
--
2.7.4
^ permalink raw reply
* [PATCH v2] ARM64: dts: marvell: Correct license text
From: Alexandre Belloni @ 2016-12-20 22:40 UTC (permalink / raw)
To: linux-arm-kernel
The license text has been mangled at some point then copy pasted across
multiple files. Restore it to what it should be.
Note that this is not intended as a license change.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
Changes in v2:
- squashed all the patches
- fix commit message
arch/arm64/boot/dts/marvell/armada-371x.dtsi | 10 +++++-----
arch/arm64/boot/dts/marvell/armada-3720-db.dts | 10 +++++-----
arch/arm64/boot/dts/marvell/armada-372x.dtsi | 10 +++++-----
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 10 +++++-----
4 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-371x.dtsi b/arch/arm64/boot/dts/marvell/armada-371x.dtsi
index c9e5325b8ac3..11226f7b9ed9 100644
--- a/arch/arm64/boot/dts/marvell/armada-371x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-371x.dtsi
@@ -16,17 +16,17 @@
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
- * This file is distributed in the hope that it will be useful
+ * This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * Or, alternatively
+ * Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
+ * restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
@@ -35,11 +35,11 @@
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
index 1372e9a6aaa4..2e707875039a 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -15,17 +15,17 @@
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
- * This file is distributed in the hope that it will be useful
+ * This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * Or, alternatively
+ * Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
+ * restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
@@ -34,11 +34,11 @@
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
diff --git a/arch/arm64/boot/dts/marvell/armada-372x.dtsi b/arch/arm64/boot/dts/marvell/armada-372x.dtsi
index 5120296596c2..59d7557d3b1b 100644
--- a/arch/arm64/boot/dts/marvell/armada-372x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-372x.dtsi
@@ -16,17 +16,17 @@
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
- * This file is distributed in the hope that it will be useful
+ * This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * Or, alternatively
+ * Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
+ * restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
@@ -35,11 +35,11 @@
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index e9bd58793464..3c6f5d9d15c4 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -15,17 +15,17 @@
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
- * This file is distributed in the hope that it will be useful
+ * This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * Or, alternatively
+ * Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
+ * restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
@@ -34,11 +34,11 @@
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
--
2.11.0
^ permalink raw reply related
* [PATCH v2] efi/libstub: arm*: Pass latest memory map to the kernel
From: Ard Biesheuvel @ 2016-12-20 22:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu8_8+GdaV86_ctf=PzKxPvT3tbUOcuz5OkyBya5OC+ekw@mail.gmail.com>
On 20 December 2016 at 22:32, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 19 December 2016 at 21:38, Matt Fleming <matt@codeblueprint.co.uk> wrote:
>> On Mon, 19 Dec, at 02:24:19PM, James Morse wrote:
>>> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>>
>>> As reported by James, the current libstub code involving the annotated
>>> memory map only works somewhat correctly by accident, due to the fact
>>> that a pool allocation happens to be reused immediately, retaining its
>>> former contents.
>>>
>>> Instead of juggling memory maps, which makes the code more complex than
>>> it needs to be, simply put a placholder value into the FDT, and only
>>> write the actual value after ExitBootServices() has been called.
>>>
>>> Reported-by: James Morse <james.morse@arm.com>
>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>> [Update mmap-size too, remove updated_fdt()s unused params and header entry]
>>> Signed-off-by: James Morse <james.morse@arm.com>
>>> ---
>>> Hi Ard,
>>>
>>> This is a v2 of your patch that updates the mmap-size too. This solves the
>>> truncated memmap problem I saw with v1 on Seattle.
>>>
>>> The original patch was CC-stable, so I think this should also have:
>>> Cc: <stable@vger.kernel.org>
>>> Fixes: ed9cc156c42f ("efi/libstub: Use efi_exit_boot_services() in FDT")
>>>
>>>
>>> Thanks,
>>>
>>> James
>>>
>>> drivers/firmware/efi/libstub/efistub.h | 8 ----
>>> drivers/firmware/efi/libstub/fdt.c | 75 +++++++++++++++++++++-------------
>>> 2 files changed, 47 insertions(+), 36 deletions(-)
>>
>> Thanks James. I've queued this one up in the 'urgent' queue and tagged
>> it for stable. I'll send it to tip before the end of the week.
>
> Could we fold the hunk below, please?
>
> diff --git a/drivers/firmware/efi/libstub/fdt.c
> b/drivers/firmware/efi/libstub/fdt.c
> index 9b11b0559a23..90ab96845937 100644
> --- a/drivers/firmware/efi/libstub/fdt.c
> +++ b/drivers/firmware/efi/libstub/fdt.c
> @@ -149,26 +149,25 @@ static efi_status_t
> update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
> static efi_status_t update_fdt_memmap(void *fdt, u64 memmap, u32 map_size)
> {
> int node = fdt_path_offset(fdt, "/chosen");
> - efi_status_t status;
> + int err;
>
> if (node < 0)
> return EFI_LOAD_ERROR;
>
> memmap = cpu_to_fdt64(memmap);
> - status = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-start",
> - &memmap, sizeof(memmap));
> + err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-start",
> + &memmap, sizeof(memmap));
>
> if (status)
> return EFI_LOAD_ERROR;
>
> map_size = cpu_to_fdt32(map_size);
> - status = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-size",
> - &map_size, sizeof(map_size));
> + err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-size",
> + &map_size, sizeof(map_size));
>
> if (status)
> return EFI_LOAD_ERROR;
>
> -
> return EFI_SUCCESS;
> }
>
> My mistake, and harmless in practice, but sloppy nonetheless
... but with the 'if (status)' replaced as well, of course (2x)
^ permalink raw reply
* [PATCH v2] efi/libstub: arm*: Pass latest memory map to the kernel
From: Ard Biesheuvel @ 2016-12-20 22:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161219213859.GA2225@codeblueprint.co.uk>
On 19 December 2016 at 21:38, Matt Fleming <matt@codeblueprint.co.uk> wrote:
> On Mon, 19 Dec, at 02:24:19PM, James Morse wrote:
>> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>
>> As reported by James, the current libstub code involving the annotated
>> memory map only works somewhat correctly by accident, due to the fact
>> that a pool allocation happens to be reused immediately, retaining its
>> former contents.
>>
>> Instead of juggling memory maps, which makes the code more complex than
>> it needs to be, simply put a placholder value into the FDT, and only
>> write the actual value after ExitBootServices() has been called.
>>
>> Reported-by: James Morse <james.morse@arm.com>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> [Update mmap-size too, remove updated_fdt()s unused params and header entry]
>> Signed-off-by: James Morse <james.morse@arm.com>
>> ---
>> Hi Ard,
>>
>> This is a v2 of your patch that updates the mmap-size too. This solves the
>> truncated memmap problem I saw with v1 on Seattle.
>>
>> The original patch was CC-stable, so I think this should also have:
>> Cc: <stable@vger.kernel.org>
>> Fixes: ed9cc156c42f ("efi/libstub: Use efi_exit_boot_services() in FDT")
>>
>>
>> Thanks,
>>
>> James
>>
>> drivers/firmware/efi/libstub/efistub.h | 8 ----
>> drivers/firmware/efi/libstub/fdt.c | 75 +++++++++++++++++++++-------------
>> 2 files changed, 47 insertions(+), 36 deletions(-)
>
> Thanks James. I've queued this one up in the 'urgent' queue and tagged
> it for stable. I'll send it to tip before the end of the week.
Could we fold the hunk below, please?
diff --git a/drivers/firmware/efi/libstub/fdt.c
b/drivers/firmware/efi/libstub/fdt.c
index 9b11b0559a23..90ab96845937 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -149,26 +149,25 @@ static efi_status_t
update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
static efi_status_t update_fdt_memmap(void *fdt, u64 memmap, u32 map_size)
{
int node = fdt_path_offset(fdt, "/chosen");
- efi_status_t status;
+ int err;
if (node < 0)
return EFI_LOAD_ERROR;
memmap = cpu_to_fdt64(memmap);
- status = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-start",
- &memmap, sizeof(memmap));
+ err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-start",
+ &memmap, sizeof(memmap));
if (status)
return EFI_LOAD_ERROR;
map_size = cpu_to_fdt32(map_size);
- status = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-size",
- &map_size, sizeof(map_size));
+ err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-size",
+ &map_size, sizeof(map_size));
if (status)
return EFI_LOAD_ERROR;
-
return EFI_SUCCESS;
}
My mistake, and harmless in practice, but sloppy nonetheless
^ permalink raw reply related
* [PATCH 2/2] soc: ti: knav: cleanup includes and sort header files
From: Murali Karicheri @ 2016-12-20 22:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482272663-29829-1-git-send-email-m-karicheri2@ti.com>
This patch cleanup the code to remove unnecessary header files and
also sort the header files.
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
drivers/soc/ti/knav_qmss_acc.c | 15 +++------------
drivers/soc/ti/knav_qmss_queue.c | 25 ++++++++-----------------
2 files changed, 11 insertions(+), 29 deletions(-)
diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c
index 0612eba..3d7225f 100644
--- a/drivers/soc/ti/knav_qmss_acc.c
+++ b/drivers/soc/ti/knav_qmss_acc.c
@@ -16,21 +16,12 @@
* General Public License for more details.
*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
+#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/soc/ti/knav_qmss.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/module.h>
#include <linux/of_address.h>
-#include <linux/firmware.h>
+#include <linux/soc/ti/knav_qmss.h>
#include "knav_qmss.h"
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index eacad57..279e7c5 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -16,26 +16,17 @@
* General Public License for more details.
*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
+#include <linux/debugfs.h>
#include <linux/dma-mapping.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <linux/of_device.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
#include <linux/pm_runtime.h>
-#include <linux/firmware.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/soc/ti/knav_qmss.h>
#include "knav_qmss.h"
--
1.9.1
^ permalink raw reply related
* [PATCH 1/2] soc: ti: knav_dma: fix typos in trace message
From: Murali Karicheri @ 2016-12-20 22:24 UTC (permalink / raw)
To: linux-arm-kernel
This patch fixes some typos in the trace message
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
drivers/soc/ti/knav_dma.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c
index 1a7b5ca..ecebe2e 100644
--- a/drivers/soc/ti/knav_dma.c
+++ b/drivers/soc/ti/knav_dma.c
@@ -395,7 +395,7 @@ static int of_channel_match_helper(struct device_node *np, const char *name,
if (of_parse_phandle_with_fixed_args(np, "ti,navigator-dmas",
1, index, &args)) {
- dev_err(kdev->dev, "Missing the pahndle args name %s\n", name);
+ dev_err(kdev->dev, "Missing the phandle args name %s\n", name);
return -ENODEV;
}
@@ -436,7 +436,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name,
}
dev_dbg(kdev->dev, "initializing %s channel %d from DMA %s\n",
- config->direction == DMA_MEM_TO_DEV ? "transmit" :
+ config->direction == DMA_MEM_TO_DEV ? "transmit" :
config->direction == DMA_DEV_TO_MEM ? "receive" :
"unknown", chan_num, instance);
--
1.9.1
^ permalink raw reply related
* [PATCH] devicetree: bindings: clk: mvebu: fix description for sata1 on Armada XP
From: Uwe Kleine-König @ 2016-12-20 21:20 UTC (permalink / raw)
To: linux-arm-kernel
SATA Host 0 clock is (as correctly documented) id 15/sata0.
Signed-off-by: Uwe Kleine-K?nig <uwe@kleine-koenig.org>
---
Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
index cb8542d910b3..5142efc8099d 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
@@ -117,7 +117,7 @@ ID Clock Peripheral
25 tdm Time Division Mplx
28 xor1 XOR DMA 1
29 sata1lnk
-30 sata1 SATA Host 0
+30 sata1 SATA Host 1
The following is a list of provided IDs for Dove:
ID Clock Peripheral
--
2.10.2
^ permalink raw reply related
* [PATCH v6 4/5] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs
From: Uwe Kleine-König @ 2016-12-20 20:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ba899a9f-3a31-85c5-9da4-dd64a2661e60@gmail.com>
Hello Joshua,
On Tue, Dec 20, 2016 at 11:47:37AM -0800, Joshua Clayton wrote:
> >> + * Copyright (c) 2017 United Western Technologies, Corporation
> > In which timezone it's already 2017? s/ / /
> >
> LOL. It will be 2017 long before 4.11 was my thinking.
> I guess I've never spent much time on time stamp etiquette for copyright.
> It said "2015" in v5, despite still being revised.
Well, you have to put the date when you worked on the driver.
> >> + *
> >> + * Joshua Clayton <stillcompiling@gmail.com>
> >> + *
> >> + * Manage Altera FPGA firmware that is loaded over spi using the passive
> >> + * serial configuration method.
> >> + * Firmware must be in binary "rbf" format.
> >> + * Works on Cyclone V. Should work on cyclone series.
> >> + * May work on other Altera FPGAs.
> > I can test this later on an Arria 10. I'm not sure what the connection
> > between "Cyclone" and "Arria" is, but the protocol looks similar.
> My guess was it would be.
> Would be wonderful to have someone to test.
I didn't come around yet.
> >> + *
> >> + */
> >> +
> >> +#include <linux/bitrev.h>
> >> +#include <linux/delay.h>
> >> +#include <linux/fpga/fpga-mgr.h>
> >> +#include <linux/gpio/consumer.h>
> >> +#include <linux/module.h>
> >> +#include <linux/of_gpio.h>
> >> +#include <linux/spi/spi.h>
> >> +#include <linux/sizes.h>
> >> +
> >> +#define FPGA_RESET_TIME 50 /* time in usecs to trigger FPGA config */
> >> +#define FPGA_MIN_DELAY 50 /* min usecs to wait for config status */
> >> +#define FPGA_MAX_DELAY 1000 /* max usecs to wait for config status */
> >> +
> >> +struct cyclonespi_conf {
> >> + struct gpio_desc *config;
> >> + struct gpio_desc *status;
> >> + struct spi_device *spi;
> >> +};
> >> +
> >> +static const struct of_device_id of_ef_match[] = {
> >> + { .compatible = "altr,cyclone-ps-spi-fpga-mgr", },
> >> + {}
> >> +};
> >> +MODULE_DEVICE_TABLE(of, of_ef_match);
> > barebox already has such a driver, the binding is available at
> >
> > https://git.pengutronix.de/cgit/barebox/tree/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
> >
> > (This isn't completely accurate because nstat is optional in the driver.)
> Interesting.
> The binding looks ... like we should synchronize those bindings.
ack.
> >> + gpiod_set_value(conf->config, 1);
> >> + usleep_range(FPGA_RESET_TIME, FPGA_RESET_TIME + 20);
> >> + if (!gpiod_get_value(conf->status)) {
> >> + dev_err(&mgr->dev, "Status pin should be low.\n");
> > You write this when get_value returns 0. There is something fishy.
> I'll take a look. These gpios are "active low", so a logical 1 is a
> physical low, IIRC. Maybe I should change the wording:
> Something like dev_err(&mgr->dev, "Status pin should be in reset.\n");
maybe "inactive"? Then then you should better use nconfig as dts name
(as done in the barebox binding) and put the active low information into
the flag.
> >> + return -EIO;
> >> + }
> >> +
> >> + gpiod_set_value(conf->config, 0);
> >> + for (i = 0; i < (FPGA_MAX_DELAY / FPGA_MIN_DELAY); i++) {
> >> + usleep_range(FPGA_MIN_DELAY, FPGA_MIN_DELAY + 20);
> >> + if (!gpiod_get_value(conf->status))
> >> + return 0;
> >> + }
> >> +
> >> + dev_err(&mgr->dev, "Status pin not ready.\n");
> >> + return -EIO;
> > For Arria 10 the documentation has:
> >
> > To ensure a successful configuration, send the entire
> > configuration data to the device. CONF_DONE is released high
> > when the device receives all the configuration data
> > successfully. After CONF_DONE goes high, send two additional
> > falling edges on DCLK to begin initialization and enter user
> > mode.
> >
> > ISTR this is necessary for Arria V, too.
> DCLK is the spi clock, yes?
> Would sending an extra byte after CONF_DONE is released suffice?
The barebox driver sends two bytes.
> >> +}
> >> +
> >> +static int cyclonespi_write(struct fpga_manager *mgr, const char *buf,
> >> + size_t count)
> >> +{
> >> + struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
> >> + const char *fw_data = buf;
> >> + const char *fw_data_end = fw_data + count;
> >> +
> >> + while (fw_data < fw_data_end) {
> >> + int ret;
> >> + size_t stride = min(fw_data_end - fw_data, SZ_4K);
> >> +
> >> + rev_buf((void *)fw_data, stride);
> > This isn't necessary if the spi controller supports SPI_LSB_FIRST. At
> > least the mvebu spi core can do this for you. (The driver doesn't
> > support it yet, though.)
> This is true, but many of them do not.
And I think it's hard to detect if the adapter driver supports this or
simply ignores it.
> Moritz Fischer had proposal to add things like this with a flag.
> It could then be part of the library, rather than part of the driver
>
> Speaking of which,
> I made an unsuccessful attempt to hack generic lsb first SPI
> with an extra bounce buffer.
> Sending was fine, but I ran into trouble with LSB first rx
> (I think) because of dma.
Link?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH 3/3] ARM: da850: Add ti, da830-uart compatible for serial ports
From: David Lechner @ 2016-12-20 20:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482265384-715-1-git-send-email-david@lechnology.com>
TI DA8xx/OMAPL13x/AM17xx/AM18xx SoCs have extra UART registers beyond
the standard 8250 registers, so we need a new compatible string to
indicate this. Also, at least one of these registers uses the full 32
bits, so we need to specify reg-io-width in addition to reg-shift.
"ns16550a" is left in the compatible specification since it does work
as long as the bootloader configures the SoC UART power management
registers.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/boot/dts/da850.dtsi | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 104155d..f6cd212 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -266,22 +266,25 @@
interrupt-names = "edm3_tcerrint";
};
serial0: serial at 42000 {
- compatible = "ns16550a";
+ compatible = "ti,da830-uart", "ns16550a";
reg = <0x42000 0x100>;
+ reg-io-width = <4>;
reg-shift = <2>;
interrupts = <25>;
status = "disabled";
};
serial1: serial at 10c000 {
- compatible = "ns16550a";
+ compatible = "ti,da830-uart", "ns16550a";
reg = <0x10c000 0x100>;
+ reg-io-width = <4>;
reg-shift = <2>;
interrupts = <53>;
status = "disabled";
};
serial2: serial at 10d000 {
- compatible = "ns16550a";
+ compatible = "ti,da830-uart", "ns16550a";
reg = <0x10d000 0x100>;
+ reg-io-width = <4>;
reg-shift = <2>;
interrupts = <61>;
status = "disabled";
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3] serial: 8250: Add new port type for TI DA8xx/OMAPL13x/AM17xx/AM18xx
From: David Lechner @ 2016-12-20 20:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482265384-715-1-git-send-email-david@lechnology.com>
This adds a new UART port type for TI DA8xx/OMAPL13x/AM17xx/AM18xx. These
SoCs have standard 8250 registers plus some extra non-standard registers.
The UART will not function unless the non-standard Power and Emulation
Management Register (PWREMU_MGMT) is configured correctly. This is
currently handled in arch/arm/mach-davinci/serial.c for non-device-tree
boards. Making this part of the UART driver will allow UART to work on
device-tree boards as well and the mach code can eventually be removed.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/tty/serial/8250/8250_of.c | 1 +
drivers/tty/serial/8250/8250_port.c | 22 ++++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 ++-
include/uapi/linux/serial_reg.h | 8 ++++++++
4 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
index d25ab1c..5281252 100644
--- a/drivers/tty/serial/8250/8250_of.c
+++ b/drivers/tty/serial/8250/8250_of.c
@@ -332,6 +332,7 @@ static const struct of_device_id of_platform_serial_table[] = {
.data = (void *)PORT_ALTR_16550_F128, },
{ .compatible = "mrvl,mmp-uart",
.data = (void *)PORT_XSCALE, },
+ { .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, },
{ /* end of list */ },
};
MODULE_DEVICE_TABLE(of, of_platform_serial_table);
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index fe4399b..ea854054 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -273,6 +273,15 @@ static const struct serial8250_config uart_config[] = {
.rxtrig_bytes = {1, 4, 8, 14},
.flags = UART_CAP_FIFO,
},
+ [PORT_DA830] = {
+ .name = "TI DA8xx/OMAPL13x/AM17xx/AM18xx",
+ .fifo_size = 16,
+ .tx_loadsz = 16,
+ .fcr = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO |
+ UART_FCR_R_TRIG_10,
+ .rxtrig_bytes = {1, 4, 8, 14},
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
};
/* Uart divisor latch read */
@@ -2118,6 +2127,19 @@ int serial8250_do_startup(struct uart_port *port)
serial_port_out(port, UART_LCR, 0);
}
+ if (port->type == PORT_DA830) {
+ /* Reset the port */
+ serial_port_out(port, UART_IER, 0);
+ serial_port_out(port, UART_DA830_PWREMU_MGMT, 0);
+ mdelay(10);
+
+ /* Enable Tx, Rx and free run mode */
+ serial_port_out(port, UART_DA830_PWREMU_MGMT,
+ UART_DA830_PWREMU_MGMT_UTRST |
+ UART_DA830_PWREMU_MGMT_URRST |
+ UART_DA830_PWREMU_MGMT_FREE);
+ }
+
#ifdef CONFIG_SERIAL_8250_RSA
/*
* If this is an RSA port, see if we can kick it up to the
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 99dbed8..a126d05 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -56,7 +56,8 @@
#define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */
#define PORT_RT2880 29 /* Ralink RT2880 internal UART */
#define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */
-#define PORT_MAX_8250 30 /* max port ID */
+#define PORT_DA830 31 /* TI DA8xx/OMAP13x/AM17xx/AM18xx */
+#define PORT_MAX_8250 31 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed
diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h
index b4c0484..0e72eeb 100644
--- a/include/uapi/linux/serial_reg.h
+++ b/include/uapi/linux/serial_reg.h
@@ -327,6 +327,14 @@
#define SERIAL_RSA_BAUD_BASE (921600)
#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8)
+/* Extra registers for TI DA8xx/OMAP13x/AM17xx/AM18xx */
+#define UART_DA830_PWREMU_MGMT 12
+
+/* PWREMU_MGMT register bits */
+#define UART_DA830_PWREMU_MGMT_FREE (1 << 0) /* Free-running mode */
+#define UART_DA830_PWREMU_MGMT_URRST (1 << 13) /* Receiver reset/enable */
+#define UART_DA830_PWREMU_MGMT_UTRST (1 << 14) /* Transmitter reset/enable */
+
/*
* Extra serial register definitions for the internal UARTs
* in TI OMAP processors.
--
2.7.4
^ permalink raw reply related
* [PATCH 1/3] doc: DT: Add ti,da830-uart to serial/8250 bindings
From: David Lechner @ 2016-12-20 20:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482265384-715-1-git-send-email-david@lechnology.com>
This adds the ti,da830-uart compatible string to serial 8250 UART bindings.
Signed-off-by: David Lechner <david@lechnology.com>
---
Documentation/devicetree/bindings/serial/8250.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt
index f86bb06..10276a4 100644
--- a/Documentation/devicetree/bindings/serial/8250.txt
+++ b/Documentation/devicetree/bindings/serial/8250.txt
@@ -19,6 +19,7 @@ Required properties:
- "altr,16550-FIFO128"
- "fsl,16550-FIFO64"
- "fsl,ns16550"
+ - "ti,da830-uart"
- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
--
2.7.4
^ permalink raw reply related
* [PATCH 0/3] TI DA8xx/OMAPL13x/AM17xx/AM18xx UART
From: David Lechner @ 2016-12-20 20:23 UTC (permalink / raw)
To: linux-arm-kernel
This series adds a new UART port type for TI DA8xx/OMAPL13x/AM17xx/AM18xx UART.
This SoCs have a non-standard register for UART power management that needs
special handling in the UART driver.
David Lechner (3):
doc: DT: Add ti,da830-uart to serial/8250 bindings
serial: 8250: Add new port type for TI DA8xx/OMAPL13x/AM17xx/AM18xx
ARM: da850: Add ti,da830-uart compatible for serial ports
Documentation/devicetree/bindings/serial/8250.txt | 1 +
arch/arm/boot/dts/da850.dtsi | 9 ++++++---
drivers/tty/serial/8250/8250_of.c | 1 +
drivers/tty/serial/8250/8250_port.c | 22 ++++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 ++-
include/uapi/linux/serial_reg.h | 8 ++++++++
6 files changed, 40 insertions(+), 4 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH v6 4/5] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs
From: Joshua Clayton @ 2016-12-20 19:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161219072326.fael3uughtghexl4@pengutronix.de>
Uwe,
Thanks so much for your review.
On 12/18/2016 11:23 PM, Uwe Kleine-K?nig wrote:
> On Fri, Dec 16, 2016 at 03:17:53PM -0800, Joshua Clayton wrote:
>> cyclone-ps-spi loads FPGA firmware over spi, using the "passive serial"
>> interface on Altera Cyclone FPGAS.
>>
>> This is one of the simpler ways to set up an FPGA at runtime.
>> The signal interface is close to unidirectional spi with lsb first.
>>
>> Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>
>> ---
>> drivers/fpga/Kconfig | 7 ++
>> drivers/fpga/Makefile | 1 +
>> drivers/fpga/cyclone-ps-spi.c | 186 ++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 194 insertions(+)
>> create mode 100644 drivers/fpga/cyclone-ps-spi.c
>>
>> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
>> index ce861a2..e6c032d 100644
>> --- a/drivers/fpga/Kconfig
>> +++ b/drivers/fpga/Kconfig
>> @@ -20,6 +20,13 @@ config FPGA_REGION
>> FPGA Regions allow loading FPGA images under control of
>> the Device Tree.
>>
>> +config FPGA_MGR_CYCLONE_PS_SPI
>> + tristate "Altera Cyclone FPGA Passive Serial over SPI"
>> + depends on SPI
>> + help
>> + FPGA manager driver support for Altera Cyclone using the
>> + passive serial interface over SPI
>> +
>> config FPGA_MGR_SOCFPGA
>> tristate "Altera SOCFPGA FPGA Manager"
>> depends on ARCH_SOCFPGA || COMPILE_TEST
>> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
>> index 8df07bc..a112bef 100644
>> --- a/drivers/fpga/Makefile
>> +++ b/drivers/fpga/Makefile
>> @@ -6,6 +6,7 @@
>> obj-$(CONFIG_FPGA) += fpga-mgr.o
>>
>> # FPGA Manager Drivers
>> +obj-$(CONFIG_FPGA_MGR_CYCLONE_PS_SPI) += cyclone-ps-spi.o
>> obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
>> obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
>> obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o
>> diff --git a/drivers/fpga/cyclone-ps-spi.c b/drivers/fpga/cyclone-ps-spi.c
>> new file mode 100644
>> index 0000000..f9126f9
>> --- /dev/null
>> +++ b/drivers/fpga/cyclone-ps-spi.c
>> @@ -0,0 +1,186 @@
>> +/**
>> + * Altera Cyclone Passive Serial SPI Driver
>> + *
>> + * Copyright (c) 2017 United Western Technologies, Corporation
> In which timezone it's already 2017? s/ / /
>
LOL. It will be 2017 long before 4.11 was my thinking.
I guess I've never spent much time on time stamp etiquette for copyright.
It said "2015" in v5, despite still being revised.
>> + *
>> + * Joshua Clayton <stillcompiling@gmail.com>
>> + *
>> + * Manage Altera FPGA firmware that is loaded over spi using the passive
>> + * serial configuration method.
>> + * Firmware must be in binary "rbf" format.
>> + * Works on Cyclone V. Should work on cyclone series.
>> + * May work on other Altera FPGAs.
> I can test this later on an Arria 10. I'm not sure what the connection
> between "Cyclone" and "Arria" is, but the protocol looks similar.
My guess was it would be.
Would be wonderful to have someone to test.
>> + *
>> + */
>> +
>> +#include <linux/bitrev.h>
>> +#include <linux/delay.h>
>> +#include <linux/fpga/fpga-mgr.h>
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/module.h>
>> +#include <linux/of_gpio.h>
>> +#include <linux/spi/spi.h>
>> +#include <linux/sizes.h>
>> +
>> +#define FPGA_RESET_TIME 50 /* time in usecs to trigger FPGA config */
>> +#define FPGA_MIN_DELAY 50 /* min usecs to wait for config status */
>> +#define FPGA_MAX_DELAY 1000 /* max usecs to wait for config status */
>> +
>> +struct cyclonespi_conf {
>> + struct gpio_desc *config;
>> + struct gpio_desc *status;
>> + struct spi_device *spi;
>> +};
>> +
>> +static const struct of_device_id of_ef_match[] = {
>> + { .compatible = "altr,cyclone-ps-spi-fpga-mgr", },
>> + {}
>> +};
>> +MODULE_DEVICE_TABLE(of, of_ef_match);
> barebox already has such a driver, the binding is available at
>
> https://git.pengutronix.de/cgit/barebox/tree/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
>
> (This isn't completely accurate because nstat is optional in the driver.)
Interesting.
The binding looks ... like we should synchronize those bindings.
In the case of my hardware, I don't have access to the confd, but do
have access to nstat. I was thinking that using confd to signal done
would be a nice but optional... Ideally you'd have both.
>> +static enum fpga_mgr_states cyclonespi_state(struct fpga_manager *mgr)
>> +{
>> + struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
>> +
>> + if (gpiod_get_value(conf->status))
>> + return FPGA_MGR_STATE_RESET;
>> +
>> + return FPGA_MGR_STATE_UNKNOWN;
>> +}
>> +
>> +static int cyclonespi_write_init(struct fpga_manager *mgr,
>> + struct fpga_image_info *info,
>> + const char *buf, size_t count)
>> +{
>> + struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
>> + int i;
>> +
>> + if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
>> + dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
>> + return -EINVAL;
>> + }
>> +
>> + gpiod_set_value(conf->config, 1);
>> + usleep_range(FPGA_RESET_TIME, FPGA_RESET_TIME + 20);
>> + if (!gpiod_get_value(conf->status)) {
>> + dev_err(&mgr->dev, "Status pin should be low.\n");
> You write this when get_value returns 0. There is something fishy.
I'll take a look. These gpios are "active low", so a logical 1 is a
physical low, IIRC. Maybe I should change the wording:
Something like dev_err(&mgr->dev, "Status pin should be in reset.\n");
Perhaps?
>> + return -EIO;
>> + }
>> +
>> + gpiod_set_value(conf->config, 0);
>> + for (i = 0; i < (FPGA_MAX_DELAY / FPGA_MIN_DELAY); i++) {
>> + usleep_range(FPGA_MIN_DELAY, FPGA_MIN_DELAY + 20);
>> + if (!gpiod_get_value(conf->status))
>> + return 0;
>> + }
>> +
>> + dev_err(&mgr->dev, "Status pin not ready.\n");
>> + return -EIO;
> For Arria 10 the documentation has:
>
> To ensure a successful configuration, send the entire
> configuration data to the device. CONF_DONE is released high
> when the device receives all the configuration data
> successfully. After CONF_DONE goes high, send two additional
> falling edges on DCLK to begin initialization and enter user
> mode.
>
> ISTR this is necessary for Arria V, too.
DCLK is the spi clock, yes?
Would sending an extra byte after CONF_DONE is released suffice?
>> +}
>> +
>> +static void rev_buf(void *buf, size_t len)
>> +{
>> + u32 *fw32 = (u32 *)buf;
>> + const u32 *fw_end = (u32 *)(buf + len);
>> +
>> + /* set buffer to lsb first */
>> + while (fw32 < fw_end) {
>> + *fw32 = bitrev8x4(*fw32);
>> + fw32++;
>> + }
> Is the size of the firmware always a multiple of 32 bit? If len isn't a
> multiple of 4 you access data after the end of buf.
The rbf cyclone V bitstream is padded out with extra bytes of FFFFFFFF
and always a multiple of 4 bytes.
I could not find anywhere this is documented.
I guess we should not assume this will always be the case.
I'll add something to handle the tail.
>> +}
>> +
>> +static int cyclonespi_write(struct fpga_manager *mgr, const char *buf,
>> + size_t count)
>> +{
>> + struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
>> + const char *fw_data = buf;
>> + const char *fw_data_end = fw_data + count;
>> +
>> + while (fw_data < fw_data_end) {
>> + int ret;
>> + size_t stride = min(fw_data_end - fw_data, SZ_4K);
>> +
>> + rev_buf((void *)fw_data, stride);
> This isn't necessary if the spi controller supports SPI_LSB_FIRST. At
> least the mvebu spi core can do this for you. (The driver doesn't
> support it yet, though.)
This is true, but many of them do not.
Moritz Fischer had proposal to add things like this with a flag.
It could then be part of the library, rather than part of the driver
Speaking of which,
I made an unsuccessful attempt to hack generic lsb first SPI
with an extra bounce buffer.
Sending was fine, but I ran into trouble with LSB first rx
(I think) because of dma.
>> + ret = spi_write(conf->spi, fw_data, stride);
>> + if (ret) {
>> + dev_err(&mgr->dev, "spi error in firmware write: %d\n",
>> + ret);
>> + return ret;
>> + }
>> + fw_data += stride;
>> + }
>> +
>> + return 0;
>> +}
>> [...]
>> +static int cyclonespi_probe(struct spi_device *spi)
>> +{
>> + struct cyclonespi_conf *conf = devm_kzalloc(&spi->dev, sizeof(*conf),
>> + GFP_KERNEL);
> please indent to the opening (.
Will fix.
>> +
>> + if (!conf)
>> + return -ENOMEM;
>> +
>> + conf->spi = spi;
>> + conf->config = devm_gpiod_get(&spi->dev, "config", GPIOD_OUT_HIGH);
>> + if (IS_ERR(conf->config)) {
>> + dev_err(&spi->dev, "Failed to get config gpio: %ld\n",
>> + PTR_ERR(conf->config));
>> + return PTR_ERR(conf->config);
>> + }
>> +
>> + conf->status = devm_gpiod_get(&spi->dev, "status", GPIOD_IN);
>> + if (IS_ERR(conf->status)) {
>> + dev_err(&spi->dev, "Failed to get status gpio: %ld\n",
>> + PTR_ERR(conf->status));
>> + return PTR_ERR(conf->status);
>> + }
>> +
>> + return fpga_mgr_register(&spi->dev,
>> + "Altera Cyclone PS SPI FPGA Manager",
>> + &cyclonespi_ops, conf);
>> +}
>> +
>> +static int cyclonespi_remove(struct spi_device *spi)
>> +{
>> + fpga_mgr_unregister(&spi->dev);
>> +
>> + return 0;
>> +}
>> +
>> +static struct spi_driver cyclonespi_driver = {
>> + .driver = {
>> + .name = "cyclone-ps-spi",
>> + .owner = THIS_MODULE,
>> + .of_match_table = of_match_ptr(of_ef_match),
>> + },
>> + .probe = cyclonespi_probe,
>> + .remove = cyclonespi_remove,
>> +};
> I'm not a big fan of aligning the assignment operators. This tends to
> get out of sync or results in bigger than necessary changes in follow up
> patches. Note that it's out of sync already now, so I suggest to use a
> single space before =.
Yes, I can see it your way. Will change.
>> +
>> +module_spi_driver(cyclonespi_driver)
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR("Joshua Clayton <stillcompiling@gmail.com>");
>> +MODULE_DESCRIPTION("Module to load Altera FPGA firmware over spi");
>> --
> Best regards
> Uwe
>
Even bester regards,
Joshua
^ permalink raw reply
* [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
From: Code Kipper @ 2016-12-20 19:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161220191656.xrmovtlslwcofsts@lukather>
On 20 December 2016 at 20:16, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Tue, Dec 20, 2016 at 03:55:24PM +0100, codekipper at gmail.com wrote:
>> From: Marcus Cooper <codekipper@gmail.com>
>>
>> Newer SoCs have additional functionality so a quirks structure
>> has been added to handle them. So far we've seen the use of a
>> reset controller, a different address for the TXFIFO and varying
>> register changes.
>>
>> This patch prepares the driver for these changes and adds the
>> reset specifier.
>>
>> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
>> ---
>> .../devicetree/bindings/sound/sun4i-i2s.txt | 2 +
>> sound/soc/sunxi/sun4i-i2s.c | 47 ++++++++++++++++++++--
>> 2 files changed, 45 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> index 7a2c0945fd22..494a881ccd21 100644
>> --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> @@ -18,6 +18,8 @@ Required properties:
>> - "apb" : clock for the I2S bus interface
>> - "mod" : module clock for the I2S controller
>> - #sound-dai-cells : Must be equal to 0
>> +- resets: reset specifier for the ahb reset (A31 and newer only)
>> +
>>
>> Example:
>>
>> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
>> index f24d19526603..80fe4f1d6e3b 100644
>> --- a/sound/soc/sunxi/sun4i-i2s.c
>> +++ b/sound/soc/sunxi/sun4i-i2s.c
>> @@ -14,9 +14,11 @@
>> #include <linux/clk.h>
>> #include <linux/dmaengine.h>
>> #include <linux/module.h>
>> +#include <linux/of_device.h>
>> #include <linux/platform_device.h>
>> #include <linux/pm_runtime.h>
>> #include <linux/regmap.h>
>> +#include <linux/reset.h>
>>
>> #include <sound/dmaengine_pcm.h>
>> #include <sound/pcm_params.h>
>> @@ -92,6 +94,7 @@ struct sun4i_i2s {
>> struct clk *bus_clk;
>> struct clk *mod_clk;
>> struct regmap *regmap;
>> + struct reset_control *rst;
>>
>> unsigned int mclk_freq;
>>
>> @@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
>> u8 val;
>> };
>>
>> +struct sun4i_i2s_quirks {
>> + unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */
>> + bool has_reset;
>> + const struct regmap_config *sun4i_i2s_regmap;
>> + const struct snd_soc_dai_ops *ops;
>> +};
>> +
>
> This is quite hard to review without actual example of what you'll put
> in there.
Fair enough...I have a patch for the A31 but haven't got any hardware
that I can verify it on. I've confirmed on the H3 but I feel like that
patch needs some tidying up. That being said...I'll push it as a patch
set and we can talk about the setup.
>
>> static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
>> { .div = 2, .val = 0 },
>> { .div = 4, .val = 1 },
>> @@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
>> .rates = SNDRV_PCM_RATE_8000_192000,
>> .formats = SNDRV_PCM_FMTBIT_S16_LE,
>> },
>> - .ops = &sun4i_i2s_dai_ops,
>> .symmetric_rates = 1,
>> };
>>
>> @@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>> {
>> struct sun4i_i2s *i2s;
>> struct resource *res;
>> + const struct sun4i_i2s_quirks *quirks;
>> void __iomem *regs;
>> int irq, ret;
>>
>> @@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>> return PTR_ERR(i2s->bus_clk);
>> }
>>
>> + quirks = of_device_get_match_data(&pdev->dev);
>> + if (quirks == NULL) {
>> + dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
>> + return -ENODEV;
>> + }
>> +
>> i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
>> - &sun4i_i2s_regmap_config);
>> + quirks->sun4i_i2s_regmap);
>> if (IS_ERR(i2s->regmap)) {
>> dev_err(&pdev->dev, "Regmap initialisation failed\n");
>> return PTR_ERR(i2s->regmap);
>> @@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>> dev_err(&pdev->dev, "Can't get our mod clock\n");
>> return PTR_ERR(i2s->mod_clk);
>> }
>> +
>
> Spurious change?
ACK
>
>>
>> - i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
>> + i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
>> i2s->playback_dma_data.maxburst = 4;
>>
>> i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
>> i2s->capture_dma_data.maxburst = 4;
>>
>> + if (quirks->has_reset) {
>> + i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
>> + if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
>> + ret = -EPROBE_DEFER;
>> + dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
>> + goto err_pm_disable;
>> + }
>> + if (!IS_ERR(i2s->rst))
>> + reset_control_deassert(i2s->rst);
>> + }
>> +
>
> That reset line is not optional. The <A31 SoCs don't need it, and you
> cover that case already, but it is definitely mandatory for the A31.
OK..I'll search for a better function call. Thanks for this and the
other reviews.
CK
>
> Thanks,
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
^ permalink raw reply
* [PATCH 2/2] mfd: mc13xxx: Pass the IRQF_TRIGGER_HIGH flag.
From: Magnus Lilja @ 2016-12-20 19:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1482211233.10253607@f408.i.mail.ru>
On 20 December 2016 at 06:20, Alexander Shiyan <shc_work@mail.ru> wrote:
>>???????, 20 ??????? 2016, 0:28 +03:00 ?? Magnus Lilja <lilja.magnus@gmail.com>:
>>
>>All supported mc13xxx devices have active high interrupt outputs. Make sure
>>to configure the interrupt as active high by passing the IRQF_TRIGGER_HIGH
>>flag. This is required at least on the i.MX31 PDK board.
>>
>>Signed-off-by: Magnus Lilja < lilja.magnus@gmail.com >
>>---
>>
>> drivers/mfd/mc13xxx-core.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>>diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
>>index d7f54e4..4cbe6b7 100644
>>--- a/drivers/mfd/mc13xxx-core.c
>>+++ b/drivers/mfd/mc13xxx-core.c
>>@@ -440,7 +440,7 @@ int mc13xxx_common_init(struct device *dev)
>> mc13xxx->irq_chip.irqs = mc13xxx->irqs;
>> mc13xxx->irq_chip.num_irqs = ARRAY_SIZE(mc13xxx->irqs);
>>
>>-ret = regmap_add_irq_chip(mc13xxx->regmap, mc13xxx->irq, IRQF_ONESHOT,
>>+ret = regmap_add_irq_chip(mc13xxx->regmap, mc13xxx->irq, IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
>> 0, &mc13xxx->irq_chip, &mc13xxx->irq_data);
>> if (ret)
>> return ret;
>
> IRQ line can be passed through inverter to IC.
> On my opinion the best way to handle all possible situations is parse
> devicetree IRQ flags and pass to the driver.
My guess is that most boards follow the evaluation boards/kits and
don't have an inverter so I think the default should be TRIG_HIGH
since that will make most boards work automatically. But I can have a
look at making it configurable (with and without the use of device
tree), but for the device tree stuff I would need pointers to similar
code since my experience with that is none.
Any pointers to similar code?
Regards. Magnus
^ permalink raw reply
* [PATCH v2] ARM: dts: sun4i: A1000: add axp209 regulator nodes
From: Maxime Ripard @ 2016-12-20 19:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161220155542.22047-1-codekipper@gmail.com>
On Tue, Dec 20, 2016 at 04:55:42PM +0100, codekipper at gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
>
> This patch adds the regulator nodes for the axp209 by including
> the axp209 dtsi.
>
> DCDC2 is used as the cpu power supply. This patch also references
> it from the cpu node.
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
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/20161220/88378e27/attachment.sig>
^ permalink raw reply
* [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
From: Maxime Ripard @ 2016-12-20 19:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161220145524.31047-1-codekipper@gmail.com>
Hi,
On Tue, Dec 20, 2016 at 03:55:24PM +0100, codekipper at gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
>
> Newer SoCs have additional functionality so a quirks structure
> has been added to handle them. So far we've seen the use of a
> reset controller, a different address for the TXFIFO and varying
> register changes.
>
> This patch prepares the driver for these changes and adds the
> reset specifier.
>
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
> .../devicetree/bindings/sound/sun4i-i2s.txt | 2 +
> sound/soc/sunxi/sun4i-i2s.c | 47 ++++++++++++++++++++--
> 2 files changed, 45 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> index 7a2c0945fd22..494a881ccd21 100644
> --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> @@ -18,6 +18,8 @@ Required properties:
> - "apb" : clock for the I2S bus interface
> - "mod" : module clock for the I2S controller
> - #sound-dai-cells : Must be equal to 0
> +- resets: reset specifier for the ahb reset (A31 and newer only)
> +
>
> Example:
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index f24d19526603..80fe4f1d6e3b 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -14,9 +14,11 @@
> #include <linux/clk.h>
> #include <linux/dmaengine.h>
> #include <linux/module.h>
> +#include <linux/of_device.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> #include <linux/regmap.h>
> +#include <linux/reset.h>
>
> #include <sound/dmaengine_pcm.h>
> #include <sound/pcm_params.h>
> @@ -92,6 +94,7 @@ struct sun4i_i2s {
> struct clk *bus_clk;
> struct clk *mod_clk;
> struct regmap *regmap;
> + struct reset_control *rst;
>
> unsigned int mclk_freq;
>
> @@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
> u8 val;
> };
>
> +struct sun4i_i2s_quirks {
> + unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */
> + bool has_reset;
> + const struct regmap_config *sun4i_i2s_regmap;
> + const struct snd_soc_dai_ops *ops;
> +};
> +
This is quite hard to review without actual example of what you'll put
in there.
> static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
> { .div = 2, .val = 0 },
> { .div = 4, .val = 1 },
> @@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
> .rates = SNDRV_PCM_RATE_8000_192000,
> .formats = SNDRV_PCM_FMTBIT_S16_LE,
> },
> - .ops = &sun4i_i2s_dai_ops,
> .symmetric_rates = 1,
> };
>
> @@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
> {
> struct sun4i_i2s *i2s;
> struct resource *res;
> + const struct sun4i_i2s_quirks *quirks;
> void __iomem *regs;
> int irq, ret;
>
> @@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
> return PTR_ERR(i2s->bus_clk);
> }
>
> + quirks = of_device_get_match_data(&pdev->dev);
> + if (quirks == NULL) {
> + dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
> + return -ENODEV;
> + }
> +
> i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
> - &sun4i_i2s_regmap_config);
> + quirks->sun4i_i2s_regmap);
> if (IS_ERR(i2s->regmap)) {
> dev_err(&pdev->dev, "Regmap initialisation failed\n");
> return PTR_ERR(i2s->regmap);
> @@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
> dev_err(&pdev->dev, "Can't get our mod clock\n");
> return PTR_ERR(i2s->mod_clk);
> }
> +
Spurious change?
>
> - i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
> + i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
> i2s->playback_dma_data.maxburst = 4;
>
> i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
> i2s->capture_dma_data.maxburst = 4;
>
> + if (quirks->has_reset) {
> + i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
> + if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
> + ret = -EPROBE_DEFER;
> + dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
> + goto err_pm_disable;
> + }
> + if (!IS_ERR(i2s->rst))
> + reset_control_deassert(i2s->rst);
> + }
> +
That reset line is not optional. The <A31 SoCs don't need it, and you
cover that case already, but it is definitely mandatory for the A31.
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/20161220/368fceb7/attachment-0001.sig>
^ permalink raw reply
* [PATCH 2/2] ASoC: sun4i-spdif: Add quirks to the spdif driver
From: Maxime Ripard @ 2016-12-20 19:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161220144914.30945-3-codekipper@gmail.com>
On Tue, Dec 20, 2016 at 03:49:14PM +0100, codekipper at gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
>
> It has been seen that some newer SoCs have a different TX FIFO
> address and we already have the difference with the A31 requiring
> a reset. Add a quirks structure so that these can be managed
> easily.
>
> Signed-off-by: Marcus Cooper <codekipper@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/20161220/f7369346/attachment.sig>
^ permalink raw reply
* [RFC PATCH] Memory hotplug support for arm64 platform
From: Scott Branden @ 2016-12-20 19:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481717765-31186-1-git-send-email-m.bielski@virtualopensystems.com>
Hi Maciej,
I have applied that patch ontop of the patches I previously sent out
and tested.
It does recognized the memory in /proc/iomem but I get memory corruption
of the original system RAM soon after. It appears the page allocation
gets corrupted. I will try to dig into it further but if somebody else
could try it out in their system to see what results they get it would help.
Regards,
Scott
On 16-12-14 04:16 AM, Maciej Bielski wrote:
> This patch relates to the work previously announced in [1]. This builds on the
> work by Scott Branden [2] and, henceforth, it needs to be applied on top of
> Scott's patches [2]. Comments are very welcome.
>
> Changes from the original patchset and known issues:
>
> - Compared to Scott's original patchset, this work adds the mapping of
> the new hotplugged pages into the kernel page tables. This is done by
> copying the old swapper_pg_dir over a new page, adding the new mappings,
> and then switching to the newly built pg_dir (see `hotplug_paging` in
> arch/arm64/mmu.c). There might be better ways to to this: suggestions
> are more than welcome.
>
> - The stub function for `arch_remove_memory` has been removed for now; we
> are working in parallel on memory hot remove, and we plan to contribute
> it as a separate patch.
>
> - Corresponding Kconfig flags have been added;
>
> - Note that this patch does not work when NUMA is enabled; in fact,
> the function `memory_add_physaddr_to_nid` does not have an
> implementation when the NUMA flag is on: this function is supposed to
> return the nid the hotplugged memory should be associated with. However
> it is not really clear to us yet what the semantics of this function
> in the context of a NUMA system should be. A quick and dirty fix would
> be to always attach to the first available NUMA node.
>
> - In arch/arm64/mm/init.c `arch_add_memory`, we are doing a hack with the
> nomap memory block flags to satisfy preconditions and postconditions of
> `__add_pages` and postconditions of `arch_add_memory`. Compared to
> memory hotplug implementation for other architectures, the "issue"
> seems to be in the implemenation of `pfn_valid`. Suggestions on how
> to cleanly avoid this hack are welcome.
>
> This patchset can be tested by starting the kernel with the `mem=X` flag, where
> X is less than the total available physical memory and has to be multiple of
> MIN_MEMORY_BLOCK_SIZE. We also tested it on a customised version of QEMU
> capable to emulate physical hotplug on arm64 platform.
>
> To enable the feature the CONFIG_MEMORY_HOTPLUG compilation flag
> needs to be set to true. Then, after memory is physically hotplugged,
> the standard two steps to make it available (as also documented in
> Documentation/memory-hotplug.txt) are:
>
> (1) Notify memory hot-add
> echo '0xYY000000' > /sys/devices/system/memory/probe
>
> where 0xYY000000 is the first physical address of the new memory section.
>
> (2) Online new memory block(s)
> echo online > /sys/devices/system/memory/memoryXXX/state
>
> where XXX corresponds to the ids of newly added blocks.
>
> Onlining can optionally be automatic at hot-add notification by enabling
> the global flag:
> echo online > /sys/devices/system/memory/auto_online_blocks
> or by setting the corresponding config flag in the kernel build.
>
> Again, any comment is highly appreciated.
>
> [1] https://lkml.org/lkml/2016/11/17/49
> [2] https://lkml.org/lkml/2016/12/1/811
>
> Signed-off-by: Maciej Bielski <m.bielski@virtualopensystems.com>
> Signed-off-by: Andrea Reale <ar@linux.vnet.ibm.com>
> ---
> arch/arm64/Kconfig | 4 +--
> arch/arm64/include/asm/mmu.h | 3 +++
> arch/arm64/mm/init.c | 58 +++++++++++++++++++++++++++++++-------------
> arch/arm64/mm/mmu.c | 24 ++++++++++++++++++
> include/linux/memblock.h | 1 +
> mm/memblock.c | 10 ++++++++
> 6 files changed, 80 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 2482fdd..bd8ddf2 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -577,9 +577,7 @@ config HOTPLUG_CPU
> can be controlled through /sys/devices/system/cpu.
>
> config ARCH_ENABLE_MEMORY_HOTPLUG
> - def_bool y
> -
> -config ARCH_ENABLE_MEMORY_HOTREMOVE
> + depends on !NUMA
> def_bool y
>
> # Common NUMA Features
> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
> index 8d9fce0..2499745 100644
> --- a/arch/arm64/include/asm/mmu.h
> +++ b/arch/arm64/include/asm/mmu.h
> @@ -36,5 +36,8 @@ extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
> unsigned long virt, phys_addr_t size,
> pgprot_t prot, bool allow_block_mappings);
> extern void *fixmap_remap_fdt(phys_addr_t dt_phys);
> +#ifdef CONFIG_MEMORY_HOTPLUG
> +extern void hotplug_paging(phys_addr_t start, phys_addr_t size);
> +#endif
>
> #endif
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 687d087..a7c740e 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -544,37 +544,61 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
> struct zone *zone;
> unsigned long start_pfn = start >> PAGE_SHIFT;
> unsigned long nr_pages = size >> PAGE_SHIFT;
> + unsigned long end_pfn = start_pfn + nr_pages;
> + unsigned long max_sparsemem_pfn = 1UL << (MAX_PHYSMEM_BITS-PAGE_SHIFT);
> + unsigned long pfn;
> int ret;
>
> + if (end_pfn > max_sparsemem_pfn) {
> + pr_err("end_pfn too big");
> + return -1;
> + }
> + hotplug_paging(start, size);
> +
> + /*
> + * Mark all the page range as unsuable.
> + * This is needed because __add_section (within __add_pages)
> + * wants pfn_valid to be false, and in arm64 pfn falid is implemented
> + * by just checking at the nomap flag for existing blocks
> + */
> + memblock_mark_nomap(start, size);
> +
> pgdat = NODE_DATA(nid);
>
> zone = pgdat->node_zones +
> zone_for_memory(nid, start, size, ZONE_NORMAL, for_device);
> ret = __add_pages(nid, zone, start_pfn, nr_pages);
>
> - if (ret)
> - pr_warn("%s: Problem encountered in __add_pages() ret=%d\n",
> - __func__, ret);
> + /*
> + * Make the pages usable after they have been added.
> + * This will make pfn_valid return true
> + */
> + memblock_clear_nomap(start, size);
>
> - return ret;
> -}
> + /*
> + * This is a hack to avoid having to mix arch specific code into arch
> + * independent code. SetPageReserved is supposed to be called by __add_zone
> + * (within __add_section, within __add_pages). However, when it is called
> + * there, it assumes that pfn_valid returns true. For the way pfn_valid is
> + * implemented in arm64 (a check on the nomap flag), the only way to make
> + * this evaluate true inside __add_zone is to clear the nomap flags of
> + * blocks in architecture independent code.
> + *
> + * To avoid this, we set the Reserved flag here after we cleared the nomap
> + * flag in the line above.
> + */
> + for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
> + if (!pfn_valid(pfn))
> + continue;
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> -int arch_remove_memory(u64 start, u64 size)
> -{
> - unsigned long start_pfn = start >> PAGE_SHIFT;
> - unsigned long nr_pages = size >> PAGE_SHIFT;
> - struct zone *zone;
> - int ret;
> + SetPageReserved(pfn_to_page(pfn));
> + }
>
> - zone = page_zone(pfn_to_page(start_pfn));
> - ret = __remove_pages(zone, start_pfn, nr_pages);
> if (ret)
> - pr_warn("%s: Problem encountered in __remove_pages() ret=%d\n",
> + pr_warn("%s: Problem encountered in __add_pages() ret=%d\n",
> __func__, ret);
>
> return ret;
> }
> #endif
> -#endif
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 05615a3..9efa7d1 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -493,6 +493,30 @@ void __init paging_init(void)
> SWAPPER_DIR_SIZE - PAGE_SIZE);
> }
>
> +#ifdef CONFIG_MEMORY_HOTPLUG
> +/*
> + * hotplug_paging() is used by memory hotplug to build new page tables
> + * for hot added memory.
> + */
> +void hotplug_paging(phys_addr_t start, phys_addr_t size)
> +{
> + phys_addr_t pgd_phys = pgd_pgtable_alloc();
> + pgd_t *pgd = pgd_set_fixmap(pgd_phys);
> +
> + memcpy(pgd, swapper_pg_dir, PAGE_SIZE);
> +
> + __create_pgd_mapping(pgd, start, __phys_to_virt(start), size,
> + PAGE_KERNEL, pgd_pgtable_alloc, false);
> +
> + cpu_replace_ttbr1(__va(pgd_phys));
> + memcpy(swapper_pg_dir, pgd, PAGE_SIZE);
> + cpu_replace_ttbr1(swapper_pg_dir);
> +
> + pgd_clear_fixmap();
> + memblock_free(pgd_phys, PAGE_SIZE);
> +}
> +#endif
> +
> /*
> * Check whether a kernel address is valid (derived from arch/x86/).
> */
> diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> index 5b759c9..5f78257 100644
> --- a/include/linux/memblock.h
> +++ b/include/linux/memblock.h
> @@ -92,6 +92,7 @@ int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
> int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
> int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);
> int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
> +int memblock_clear_nomap(phys_addr_t base, phys_addr_t size);
> ulong choose_memblock_flags(void);
>
> /* Low level functions */
> diff --git a/mm/memblock.c b/mm/memblock.c
> index 7608bc3..05e7676 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -814,6 +814,16 @@ int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)
> }
>
> /**
> + * memblock_clear_nomap - Clear a flag of MEMBLOCK_NOMAP memory region
> + * @base: the base phys addr of the region
> + * @size: the size of the region
> + */
> +int __init_memblock memblock_clear_nomap(phys_addr_t base, phys_addr_t size)
> +{
> + return memblock_setclr_flag(base, size, 0, MEMBLOCK_NOMAP);
> +}
> +
> +/**
> * __next_reserved_mem_region - next function for for_each_reserved_region()
> * @idx: pointer to u64 loop variable
> * @out_start: ptr to phys_addr_t for start address of the region, can be %NULL
>
^ permalink raw reply
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