* [kernel-hardening][PATCH] arm: hw_breakpoint: Mark variables as __ro_after_init
From: Kees Cook @ 2017-12-11 19:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211125043.GA17299@pjb1027-Latitude-E5410>
On Mon, Dec 11, 2017 at 4:50 AM, Jinbum Park <jinb.park7@gmail.com> wrote:
> core_num_brps, core_num_wrps, debug_arch, has_ossr,
> max_watchpoint_len are setup once while init stage,
> and never changed after that.
> so it is good candidate for __ro_after_init.
>
> Signed-off-by: Jinbum Park <jinb.park7@gmail.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
(Probably good to toss this into the ARM patch tracker.)
-Kees
> ---
> arch/arm/kernel/hw_breakpoint.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
> index af2a7f1..629e251 100644
> --- a/arch/arm/kernel/hw_breakpoint.c
> +++ b/arch/arm/kernel/hw_breakpoint.c
> @@ -44,17 +44,17 @@
> static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);
>
> /* Number of BRP/WRP registers on this CPU. */
> -static int core_num_brps;
> -static int core_num_wrps;
> +static int core_num_brps __ro_after_init;
> +static int core_num_wrps __ro_after_init;
>
> /* Debug architecture version. */
> -static u8 debug_arch;
> +static u8 debug_arch __ro_after_init;
>
> /* Does debug architecture support OS Save and Restore? */
> -static bool has_ossr;
> +static bool has_ossr __ro_after_init;
>
> /* Maximum supported watchpoint length. */
> -static u8 max_watchpoint_len;
> +static u8 max_watchpoint_len __ro_after_init;
>
> #define READ_WB_REG_CASE(OP2, M, VAL) \
> case ((OP2 << 4) + M): \
> --
> 1.9.1
>
--
Kees Cook
Pixel Security
^ permalink raw reply
* [PATCH v5 15/30] arm64/sve: Signal handling support
From: Kees Cook @ 2017-12-11 19:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211140720.GE2141@arm.com>
On Mon, Dec 11, 2017 at 6:07 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Thu, Dec 07, 2017 at 10:50:38AM -0800, Kees Cook wrote:
>> My question is mainly: why not just use copy_*() everywhere instead?
>> Having these things so spread out makes it fragile, and there's very
>> little performance benefit from using __copy_*() over copy_*().
>
> I think that's more of a general question. Why not just remove the __
> versions from the kernel entirely if they're not worth the perf?
That has been something Linus has strongly suggested in the past, so
I've kind of been looking for easy places to drop the __copy_*
versions. :)
-Kees
--
Kees Cook
Pixel Security
^ permalink raw reply
* [PATCH net-next 2/2 v8] net: ethernet: Add a driver for Gemini gigabit ethernet
From: David Miller @ 2017-12-11 19:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171210224558.27122-2-linus.walleij@linaro.org>
From: Linus Walleij <linus.walleij@linaro.org>
Date: Sun, 10 Dec 2017 23:45:58 +0100
> diff --git a/drivers/net/ethernet/cortina/Kconfig b/drivers/net/ethernet/cortina/Kconfig
> new file mode 100644
> index 000000000000..7d279ac4357d
> --- /dev/null
> +++ b/drivers/net/ethernet/cortina/Kconfig
> @@ -0,0 +1,24 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Cortina ethernet devices
> +
> +config NET_VENDOR_CORTINA
> + bool "Cortina Gemini devices"
> + depends on (ARM || COMPILE_TEST)
> + default ARCH_GEMINI
> + ---help---
> + If you have a network (Ethernet) card belonging to this class, say Y
> + and read the Ethernet-HOWTO, available from
> + <http://www.tldp.org/docs.html#howto>.
Vendor Kconfig guards should default to 'y'. Remove the depends guard.
> +
> +if NET_VENDOR_CORTINA
> +
> +config GEMINI_ETHERNET
> + tristate "Gemini Gigabit Ethernet support"
> + depends on ARCH_GEMINI
> + depends on OF
> + select PHYLIB
> + select CRC32
> + ---help---
> + This driver supports StorLink SL351x (Gemini) dual Gigabit Ethernet.
Make this driver buildable anywhere, you don't use any platform architecture
specific features.
Otherwise your driver will have bad build coverage and will likely
stop building when core APIs are changed.
^ permalink raw reply
* [RESEND PATCH] arm64: v8.4: Support for new floating point multiplication variant
From: Suzuki K Poulose @ 2017-12-11 18:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211132914.GJ22781@e103592.cambridge.arm.com>
Hi gengdongjiu
Sorry for the late response. I have a similar patch to add the support
for "FHM", which I was about to post it this week.
On 11/12/17 13:29, Dave Martin wrote:
> On Mon, Dec 11, 2017 at 08:47:00PM +0800, gengdongjiu wrote:
>>
>> On 2017/12/11 19:59, Dave P Martin wrote:
>>> On Sat, Dec 09, 2017 at 03:28:42PM +0000, Dongjiu Geng wrote:
>>>> ARM v8.4 extensions include support for new floating point
>>>> multiplication variant instructions to the AArch64 SIMD
>>>
>>> Do we have any human-readable description of what the new instructions
>>> do?
>>>
>>> Since the v8.4 spec itself only describes these as "New Floating
>>> Point Multiplication Variant", I wonder what "FHM" actually stands
>>> for.
>> Thanks for the point out.
>> In fact, this feature only adds two instructions:
>> FP16 * FP16 + FP32
>> FP16 * FP16 - FP32
>>
>> The spec call this bit to ID_AA64ISAR0_EL1.FHM, I do not know why it
>> will call "FHM", I think call it "FMLXL" may be better, which can
>> stand for FMLAL/FMLSL instructions.
>
> Although "FHM" is cryptic, I think it makes sense to keep this as "FHM"
> to match the ISAR0 field name -- we've tended to follow this policy
> for other extension names unless there's a much better or more obvious
> name available.
>
> For "FMLXL", new instructions might be added in the future that match
> the same pattern, and then "FMLXL" could become ambiguous. So maybe
> this is not the best choice.
I think the FHM stands for "FP Half precision Multiplication
instructions". I vote for keeping the feature bit in sync with the
register bit definition. i.e, FHM.
However, my version of the patch names the HWCAP bit "asimdfml",
following the compiler name for the feature option "fp16fml", which
is not perfect either. I think FHM is the safe option here.
>
>>> Maybe something like "widening half-precision floating-point multiply
>>> accumulate" is acceptable wording consistent with the existing
>>> architecture, but I just made that up, so it's not official ;)
>>
>> how about something like "performing a multiplication of each FP16
>> element of one vector with the corresponding FP16 element of a second
>> vector, and to add or subtract this without an intermediate rounding
>> to the corresponding FP32 element in a third vector."?
>
> We could have that, I guess.
>
I agree, and that matches the feature description.
^ permalink raw reply
* [PATCH] ARM: sa1100/neponset: add GPIO drivers for control and modem registers
From: Russell King @ 2017-12-11 18:56 UTC (permalink / raw)
To: linux-arm-kernel
The NCR, MDM_CTL* and AUD registers manipulate the state of external
signals (eg, the RTS, DTR signals and the ethernet oscillator enable
signal) or indicate the state of external signals (eg, CTS, DSR).
Where these registers can be written, the current value can be read
back, which relieves us from having to maintain a software copy of
the current state.
Model these registers as fixed-direction GPIO registers.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
arch/arm/mach-sa1100/neponset.c | 159 ++++++++++++++++++++++++----------------
1 file changed, 96 insertions(+), 63 deletions(-)
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index a61a2432766b..b1823f445358 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -3,6 +3,8 @@
* linux/arch/arm/mach-sa1100/neponset.c
*/
#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio/gpio-reg.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/irq.h>
@@ -45,10 +47,13 @@
#define IRR_USAR (1 << 1)
#define IRR_SA1111 (1 << 2)
+#define NCR_NGPIO 7
+
#define MDM_CTL0_RTS1 (1 << 0)
#define MDM_CTL0_DTR1 (1 << 1)
#define MDM_CTL0_RTS2 (1 << 2)
#define MDM_CTL0_DTR2 (1 << 3)
+#define MDM_CTL0_NGPIO 4
#define MDM_CTL1_CTS1 (1 << 0)
#define MDM_CTL1_DSR1 (1 << 1)
@@ -56,80 +61,87 @@
#define MDM_CTL1_CTS2 (1 << 3)
#define MDM_CTL1_DSR2 (1 << 4)
#define MDM_CTL1_DCD2 (1 << 5)
+#define MDM_CTL1_NGPIO 6
#define AUD_SEL_1341 (1 << 0)
#define AUD_MUTE_1341 (1 << 1)
+#define AUD_NGPIO 2
extern void sa1110_mb_disable(void);
+#define to_neponset_gpio_chip(x) container_of(x, struct neponset_gpio_chip, gc)
+
+static const char *neponset_ncr_names[] = {
+ "gp01_off", "tp_power", "ms_power", "enet_osc",
+ "spi_kb_wk_up", "a0vpp", "a1vpp"
+};
+
+static const char *neponset_mdmctl0_names[] = {
+ "rts3", "dtr3", "rts1", "dtr1",
+};
+
+static const char *neponset_mdmctl1_names[] = {
+ "cts3", "dsr3", "dcd3", "cts1", "dsr1", "dcd1"
+};
+
+static const char *neponset_aud_names[] = {
+ "sel_1341", "mute_1341",
+};
+
struct neponset_drvdata {
void __iomem *base;
struct platform_device *sa1111;
struct platform_device *smc91x;
unsigned irq_base;
-#ifdef CONFIG_PM_SLEEP
- u32 ncr0;
- u32 mdm_ctl_0;
-#endif
+ struct gpio_chip *gpio[4];
};
-static void __iomem *nep_base;
+static struct neponset_drvdata *nep;
void neponset_ncr_frob(unsigned int mask, unsigned int val)
{
- void __iomem *base = nep_base;
-
- if (base) {
- unsigned long flags;
- unsigned v;
-
- local_irq_save(flags);
- v = readb_relaxed(base + NCR_0);
- writeb_relaxed((v & ~mask) | val, base + NCR_0);
- local_irq_restore(flags);
- } else {
- WARN(1, "nep_base unset\n");
- }
+ struct neponset_drvdata *n = nep;
+ unsigned long m = mask, v = val;
+
+ if (nep)
+ n->gpio[0]->set_multiple(n->gpio[0], &m, &v);
+ else
+ WARN(1, "nep unset\n");
}
EXPORT_SYMBOL(neponset_ncr_frob);
static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
{
- void __iomem *base = nep_base;
- u_int mdm_ctl0;
+ struct neponset_drvdata *n = nep;
+ unsigned long mask, val = 0;
- if (!base)
+ if (!n)
return;
- mdm_ctl0 = readb_relaxed(base + MDM_CTL_0);
if (port->mapbase == _Ser1UTCR0) {
- if (mctrl & TIOCM_RTS)
- mdm_ctl0 &= ~MDM_CTL0_RTS2;
- else
- mdm_ctl0 |= MDM_CTL0_RTS2;
-
- if (mctrl & TIOCM_DTR)
- mdm_ctl0 &= ~MDM_CTL0_DTR2;
- else
- mdm_ctl0 |= MDM_CTL0_DTR2;
+ mask = MDM_CTL0_RTS2 | MDM_CTL0_DTR2;
+
+ if (!(mctrl & TIOCM_RTS))
+ val |= MDM_CTL0_RTS2;
+
+ if (!(mctrl & TIOCM_DTR))
+ val |= MDM_CTL0_DTR2;
} else if (port->mapbase == _Ser3UTCR0) {
- if (mctrl & TIOCM_RTS)
- mdm_ctl0 &= ~MDM_CTL0_RTS1;
- else
- mdm_ctl0 |= MDM_CTL0_RTS1;
-
- if (mctrl & TIOCM_DTR)
- mdm_ctl0 &= ~MDM_CTL0_DTR1;
- else
- mdm_ctl0 |= MDM_CTL0_DTR1;
+ mask = MDM_CTL0_RTS1 | MDM_CTL0_DTR1;
+
+ if (!(mctrl & TIOCM_RTS))
+ val |= MDM_CTL0_RTS1;
+
+ if (!(mctrl & TIOCM_DTR))
+ val |= MDM_CTL0_DTR1;
}
- writeb_relaxed(mdm_ctl0, base + MDM_CTL_0);
+ n->gpio[1]->set_multiple(n->gpio[1], &mask, &val);
}
static u_int neponset_get_mctrl(struct uart_port *port)
{
- void __iomem *base = nep_base;
+ void __iomem *base = nep->base;
u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
u_int mdm_ctl1;
@@ -231,6 +243,22 @@ static struct irq_chip nochip = {
.irq_unmask = nochip_noop,
};
+static int neponset_init_gpio(struct gpio_chip **gcp,
+ struct device *dev, const char *label, void __iomem *reg,
+ unsigned num, bool in, const char *const * names)
+{
+ struct gpio_chip *gc;
+
+ gc = gpio_reg_init(dev, reg, -1, num, label, in ? 0xffffffff : 0,
+ readl_relaxed(reg), names, NULL, NULL);
+ if (IS_ERR(gc))
+ return PTR_ERR(gc);
+
+ *gcp = gc;
+
+ return 0;
+}
+
static struct sa1111_platform_data sa1111_info = {
.disable_devs = SA1111_DEVID_PS2_MSE,
};
@@ -274,7 +302,7 @@ static int neponset_probe(struct platform_device *dev)
};
int ret, irq;
- if (nep_base)
+ if (nep)
return -EBUSY;
irq = ret = platform_get_irq(dev, 0);
@@ -330,6 +358,22 @@ static int neponset_probe(struct platform_device *dev)
irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
irq_set_chained_handler_and_data(irq, neponset_irq_handler, d);
+ /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
+ writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
+
+ neponset_init_gpio(&d->gpio[0], &dev->dev, "neponset-ncr",
+ d->base + NCR_0, NCR_NGPIO, false,
+ neponset_ncr_names);
+ neponset_init_gpio(&d->gpio[1], &dev->dev, "neponset-mdm-ctl0",
+ d->base + MDM_CTL_0, MDM_CTL0_NGPIO, false,
+ neponset_mdmctl0_names);
+ neponset_init_gpio(&d->gpio[2], &dev->dev, "neponset-mdm-ctl1",
+ d->base + MDM_CTL_1, MDM_CTL1_NGPIO, true,
+ neponset_mdmctl1_names);
+ neponset_init_gpio(&d->gpio[3], &dev->dev, "neponset-aud-ctl",
+ d->base + AUD_CTL, AUD_NGPIO, false,
+ neponset_aud_names);
+
/*
* We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
* something on the Neponset activates this IRQ on sleep (eth?)
@@ -340,16 +384,13 @@ static int neponset_probe(struct platform_device *dev)
dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
- nep_base = d->base;
+ nep = d;
sa1100_register_uart_fns(&neponset_port_fns);
/* Ensure that the memory bus request/grant signals are setup */
sa1110_mb_disable();
- /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
- writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
-
sa1111_resources[0].parent = sa1111_res;
sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111;
sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111;
@@ -385,7 +426,7 @@ static int neponset_remove(struct platform_device *dev)
platform_device_unregister(d->smc91x);
irq_set_chained_handler(irq, NULL);
irq_free_descs(d->irq_base, NEP_IRQ_NR);
- nep_base = NULL;
+ nep = NULL;
iounmap(d->base);
kfree(d);
@@ -393,30 +434,22 @@ static int neponset_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM_SLEEP
-static int neponset_suspend(struct device *dev)
-{
- struct neponset_drvdata *d = dev_get_drvdata(dev);
-
- d->ncr0 = readb_relaxed(d->base + NCR_0);
- d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0);
-
- return 0;
-}
-
static int neponset_resume(struct device *dev)
{
struct neponset_drvdata *d = dev_get_drvdata(dev);
+ int i, ret = 0;
- writeb_relaxed(d->ncr0, d->base + NCR_0);
- writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0);
+ for (i = 0; i < ARRAY_SIZE(d->gpio); i++) {
+ ret = gpio_reg_resume(d->gpio[i]);
+ if (ret)
+ break;
+ }
- return 0;
+ return ret;
}
static const struct dev_pm_ops neponset_pm_ops = {
- .suspend_noirq = neponset_suspend,
.resume_noirq = neponset_resume,
- .freeze_noirq = neponset_suspend,
.restore_noirq = neponset_resume,
};
#define PM_OPS &neponset_pm_ops
--
2.7.4
^ permalink raw reply related
* [PATCH] ARM: sa1100/assabet: add BCR/BSR GPIO driver
From: Russell King @ 2017-12-11 18:56 UTC (permalink / raw)
To: linux-arm-kernel
Add a GPIO driver for the board control register/board status register
for the sa1100/assabet platform. This allows us to transition a range
of drivers to use the gpiod APIs rather than the platform private
ASSABET_BCR_* interfaces.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
arch/arm/mach-sa1100/Kconfig | 1 +
arch/arm/mach-sa1100/assabet.c | 71 ++++++++++++++++++++++++++++++++----------
2 files changed, 55 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 36e3c79f4973..07df3a59b13f 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -5,6 +5,7 @@ menu "SA11x0 Implementations"
config SA1100_ASSABET
bool "Assabet"
select ARM_SA1110_CPUFREQ
+ select GPIO_REG
help
Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
Microprocessor Development Board (also known as the Assabet).
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index d28ecb9ef172..f68241d995f2 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/gpio/gpio-reg.h>
#include <linux/ioport.h>
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/serial_core.h>
@@ -61,20 +62,45 @@
unsigned long SCR_value = ASSABET_SCR_INIT;
EXPORT_SYMBOL(SCR_value);
-static unsigned long BCR_value = ASSABET_BCR_DB1110;
+static struct gpio_chip *assabet_bcr_gc;
+
+static const char *assabet_names[] = {
+ "cf_pwr", "cf_gfx_reset", "nsoft_reset", "irda_fsel",
+ "irda_md0", "irda_md1", "stereo_loopback", "ncf_bus_on",
+ "audio_pwr_on", "light_pwr_on", "lcd16data", "lcd_pwr_on",
+ "rs232_on", "nred_led", "ngreen_led", "vib_on",
+ "com_dtr", "com_rts", "radio_wake_mod", "i2c_enab",
+ "tvir_enab", "qmute", "radio_pwr_on", "spkr_off",
+ "rs232_valid", "com_dcd", "com_cts", "com_dsr",
+ "radio_cts", "radio_dsr", "radio_dcd", "radio_ri",
+};
+/* The old deprecated interface */
void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
{
- unsigned long flags;
+ unsigned long m = mask, v = val;
- local_irq_save(flags);
- BCR_value = (BCR_value & ~mask) | val;
- ASSABET_BCR = BCR_value;
- local_irq_restore(flags);
+ assabet_bcr_gc->set_multiple(assabet_bcr_gc, &m, &v);
}
-
EXPORT_SYMBOL(ASSABET_BCR_frob);
+static int __init assabet_init_gpio(void __iomem *reg, u32 def_val)
+{
+ struct gpio_chip *gc;
+
+ writel_relaxed(def_val, reg);
+
+ gc = gpio_reg_init(NULL, reg, -1, 32, "assabet", 0xff000000, def_val,
+ assabet_names, NULL, NULL);
+
+ if (IS_ERR(gc))
+ return PTR_ERR(gc);
+
+ assabet_bcr_gc = gc;
+
+ return gc->base;
+}
+
/*
* The codec reset goes to three devices, so we need to release
* the rest when any one of these requests it. However, that
@@ -146,7 +172,7 @@ static void adv7171_write(unsigned reg, unsigned val)
unsigned gpdr = GPDR;
unsigned gplr = GPLR;
- ASSABET_BCR = BCR_value | ASSABET_BCR_AUDIO_ON;
+ ASSABET_BCR_frob(ASSABET_BCR_AUDIO_ON, ASSABET_BCR_AUDIO_ON);
udelay(100);
GPCR = SDA | SCK | MOD; /* clear L3 mode to ensure UDA1341 doesn't respond */
@@ -457,14 +483,6 @@ static void __init assabet_init(void)
sa11x0_ppc_configure_mcp();
if (machine_has_neponset()) {
- /*
- * Angel sets this, but other bootloaders may not.
- *
- * This must precede any driver calls to BCR_set()
- * or BCR_clear().
- */
- ASSABET_BCR = BCR_value = ASSABET_BCR_DB1111;
-
#ifndef CONFIG_ASSABET_NEPONSET
printk( "Warning: Neponset detected but full support "
"hasn't been configured in the kernel\n" );
@@ -748,12 +766,31 @@ static int __init assabet_leds_init(void)
fs_initcall(assabet_leds_init);
#endif
+void __init assabet_init_irq(void)
+{
+ u32 def_val;
+
+ sa1100_init_irq();
+
+ if (machine_has_neponset())
+ def_val = ASSABET_BCR_DB1111;
+ else
+ def_val = ASSABET_BCR_DB1110;
+
+ /*
+ * Angel sets this, but other bootloaders may not.
+ *
+ * This must precede any driver calls to BCR_set() or BCR_clear().
+ */
+ assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+}
+
MACHINE_START(ASSABET, "Intel-Assabet")
.atag_offset = 0x100,
.fixup = fixup_assabet,
.map_io = assabet_map_io,
.nr_irqs = SA1100_NR_IRQS,
- .init_irq = sa1100_init_irq,
+ .init_irq = assabet_init_irq,
.init_time = sa1100_timer_init,
.init_machine = assabet_init,
.init_late = sa11x0_init_late,
--
2.7.4
^ permalink raw reply related
* [PATCH] ARM: pxa/lubbock: add GPIO driver for LUB_MISC_WR register
From: Russell King @ 2017-12-11 18:56 UTC (permalink / raw)
To: linux-arm-kernel
Add a gpio driver for the lubbock miscellaneous write IO register so we
can take advantage of subsystems modelled around gpiolib, rather than
having to provide platform specific callbacks.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
arch/arm/mach-pxa/Kconfig | 1 +
arch/arm/mach-pxa/lubbock.c | 24 ++++++++++++++++--------
2 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index ce7d97babb0f..a68b34183107 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -40,6 +40,7 @@ config MACH_PXA3XX_DT
config ARCH_LUBBOCK
bool "Intel DBPXA250 Development Platform (aka Lubbock)"
+ select GPIO_REG
select PXA25x
select SA1111
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index df45682e99a5..fe2ef9b78602 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -13,6 +13,7 @@
*/
#include <linux/clkdev.h>
#include <linux/gpio.h>
+#include <linux/gpio/gpio-reg.h>
#include <linux/gpio/machine.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -110,20 +111,18 @@ static unsigned long lubbock_pin_config[] __initdata = {
};
#define LUB_HEXLED __LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
-#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
void lubbock_set_hexled(uint32_t value)
{
LUB_HEXLED = value;
}
+static struct gpio_chip *lubbock_misc_wr_gc;
+
void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
{
- unsigned long flags;
-
- local_irq_save(flags);
- LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask);
- local_irq_restore(flags);
+ unsigned long m = mask, v = set;
+ lubbock_misc_wr_gc->set_multiple(lubbock_misc_wr_gc, &m, &v);
}
EXPORT_SYMBOL(lubbock_set_misc_wr);
@@ -452,9 +451,9 @@ static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
local_irq_save(flags);
if (mode & IR_SIRMODE) {
- LUB_MISC_WR &= ~(1 << 4);
+ lubbock_set_misc_wr(BIT(4), 0);
} else if (mode & IR_FIRMODE) {
- LUB_MISC_WR |= 1 << 4;
+ lubbock_set_misc_wr(BIT(4), BIT(4));
}
pxa2xx_transceiver_mode(dev, mode);
local_irq_restore(flags);
@@ -472,6 +471,15 @@ static void __init lubbock_init(void)
pxa2xx_mfp_config(ARRAY_AND_SIZE(lubbock_pin_config));
+ lubbock_misc_wr_gc = gpio_reg_init(NULL, (void *)&LUB_MISC_WR,
+ -1, 16, "lubbock", 0, LUB_MISC_WR,
+ NULL, NULL, NULL);
+ if (IS_ERR(lubbock_misc_wr_gc)) {
+ pr_err("Lubbock: unable to register lubbock GPIOs: %ld\n",
+ PTR_ERR(lubbock_misc_wr_gc));
+ lubbock_misc_wr_gc = NULL;
+ }
+
pxa_set_ffuart_info(NULL);
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
--
2.7.4
^ permalink raw reply related
* [PATCH 5/5] arm_pmu: acpi: request IRQs up-front
From: Will Deacon @ 2017-12-11 18:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211175539.jqjxyoa4vtwrakl3@lakrids.cambridge.arm.com>
On Mon, Dec 11, 2017 at 05:55:40PM +0000, Mark Rutland wrote:
> On Mon, Dec 11, 2017 at 05:36:47PM +0000, Will Deacon wrote:
> > On Wed, Nov 01, 2017 at 02:12:39PM +0000, Mark Rutland wrote:
> > > We can't request IRQs in atomic context, so for ACPI systems we'll have
> > > to request them up-front, and later associate them with CPUs.
> > >
> > > This patch reorganises the arm_pmu code to do so. As we no longer have
> > > the arm_pmu strucutre at probe time, a number of prototypes need to be
> > > adjusted, requiring changes to the common arm_pmu code and arm_pmu
> > > platform code.
>
> > > +void armpmu_bind_cpu(struct arm_pmu *armpmu, int cpu)
> > > {
> > > - struct arm_pmu_platdata *platdata = armpmu_get_platdata(armpmu);
> > > - unsigned long irq_flags;
> > > - struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
> > > - int irq = per_cpu(hw_events->irq, cpu);
> > > - if (!irq)
> > > - return 0;
> > > -
> > > - if (platdata && platdata->irq_flags) {
> > > - irq_flags = platdata->irq_flags;
> > > - } else {
> > > - irq_flags = ARM_PMU_IRQ_FLAGS;
> > > - }
> > > -
> > > per_cpu(cpu_armpmu, cpu) = armpmu;
> >
> > Can we not make the binding implicit in armpmu_{request,free}_irq?
>
> Unfortunately not.
>
> As mentioned in the commit message (typo and all), in the ACPI case, we
> need to request/free IRQs before we know the PMU.
Urgh. This is hideous! Just try reading the imnplementation of
armpmu_bind_cpu out loud.
Could we use {enable,disable}_irq in the hotplug notifier and request the
interrupts with NOAUTOEN instead? That would mean we have a similar flow
for SPI and PPIs and could potentially hide some of the book-keeping behind
armpmu_{enable,disable}_irq functions.
Will
^ permalink raw reply
* [PATCH 3/5] arm_pmu: acpi: check for mismatched PPIs
From: Will Deacon @ 2017-12-11 18:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211180830.firkcy3jptw3bou3@lakrids.cambridge.arm.com>
On Mon, Dec 11, 2017 at 06:08:31PM +0000, Mark Rutland wrote:
> On Mon, Dec 11, 2017 at 05:37:07PM +0000, Will Deacon wrote:
> > On Wed, Nov 01, 2017 at 02:12:37PM +0000, Mark Rutland wrote:
> > > The arm_pmu platform code explicitly checks for mismatched PPIs at probe
> > > time, while the ACPI code leaves this to the core code. Future
> > > refactoring will make this difficult for the core code to check, so
> > > let's have the ACPI code check this explicitly.
> > >
> > > As before, upon a failure we'll continue on without an interrupt. Ho
> > > hum.
> > >
> > > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > > Cc: Will Deacon <will.deacon@arm.com>
> > > ---
> > > drivers/perf/arm_pmu.c | 16 ++++------------
> > > drivers/perf/arm_pmu_acpi.c | 42 ++++++++++++++++++++++++++++++++++++++----
> > > 2 files changed, 42 insertions(+), 16 deletions(-)
> > >
> > > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > > index 3d6d4c5f2356..e0242103d904 100644
> > > --- a/drivers/perf/arm_pmu.c
> > > +++ b/drivers/perf/arm_pmu.c
> > > @@ -557,18 +557,10 @@ int armpmu_request_irq(struct arm_pmu *armpmu, int cpu)
> > > if (!irq)
> > > return 0;
> > >
> > > - if (irq_is_percpu_devid(irq) && cpumask_empty(&armpmu->active_irqs)) {
> > > - err = request_percpu_irq(irq, handler, "arm-pmu",
> > > - &hw_events->percpu_pmu);
> > > - } else if (irq_is_percpu_devid(irq)) {
> > > - int other_cpu = cpumask_first(&armpmu->active_irqs);
> > > - int other_irq = per_cpu(hw_events->irq, other_cpu);
> > > -
> > > - if (irq != other_irq) {
> > > - pr_warn("mismatched PPIs detected.\n");
> > > - err = -EINVAL;
> > > - goto err_out;
> > > - }
> > > + if (irq_is_percpu_devid(irq)) {
> > > + if (cpumask_empty(&armpmu->active_irqs))
> >
> > Why not leave this as before, with a '&&' operator?
>
> Because then we'd fall into the else case (for SPIs), were the
> active_irqs mask empty.
>
> Previously, that would have been caught by the irq_is_percpu_devid(irq)
> case that got removed.
>
> I can instead make this:
>
> if (irq_is_percpu_devid(irq) && cpumask_empty(&armpmu->active_irqs)) {
> err = request_percpu_irq(irq, handler, "arm-pmu",
> &hw_events->percpu_pmu);
> } else if (irq_is_percpu_devid(irq)) {
> /* nothing to do */
> } else {
> < SPI case >
> }
>
> ... but that seemed more painful to read.
Yeah, that's crazy :)
How about:
if (!irq_is_percpu_devid(irq)) {
/* SPI case */
} else if (cpumask_empty(&armpmu->active_irqs)) {
/* PPI case */
}
?
Will
^ permalink raw reply
* [PATCH 4/5] arm_pmu: note IRQs/PMUs per-cpu
From: Mark Rutland @ 2017-12-11 18:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211173657.GB3275@arm.com>
On Mon, Dec 11, 2017 at 05:36:58PM +0000, Will Deacon wrote:
> On Wed, Nov 01, 2017 at 02:12:38PM +0000, Mark Rutland wrote:
> > @@ -531,40 +530,56 @@ int perf_num_counters(void)
> > }
> > EXPORT_SYMBOL_GPL(perf_num_counters);
> >
> > -void armpmu_free_irq(struct arm_pmu *armpmu, int cpu)
> > +int armpmu_count_irq_users(const int irq)
> > {
> > - struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
> > - int irq = per_cpu(hw_events->irq, cpu);
> > + int cpu, count = 0;
> > +
> > + for_each_possible_cpu(cpu) {
> > + if (per_cpu(cpu_irq, cpu) == irq)
> > + count++;
> > + }
> > +
> > + return count;
> > +}
> >
> > - if (!cpumask_test_and_clear_cpu(cpu, &armpmu->active_irqs))
> > +void __armpmu_free_irq(int irq, int cpu)
> > +{
> > + if (per_cpu(cpu_irq, cpu) == 0)
> > + return;
> > + if (WARN_ON(irq != per_cpu(cpu_irq, cpu)))
> > return;
> >
> > if (irq_is_percpu_devid(irq)) {
> > - free_percpu_irq(irq, &hw_events->percpu_pmu);
> > - cpumask_clear(&armpmu->active_irqs);
> > - return;
> > + if (armpmu_count_irq_users(irq) == 1)
> > + free_percpu_irq(irq, &cpu_armpmu);
>
> Do you actually need the count, or could you just free the irq the first
> time this is called and set all of the cpu_irqs to 0?
It might be safe to blat all the matching cpu_irq entries. I'll take a
look.
Thanks,
Mark.
^ permalink raw reply
* [PATCH 3/5] arm_pmu: acpi: check for mismatched PPIs
From: Mark Rutland @ 2017-12-11 18:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211173707.GD3275@arm.com>
On Mon, Dec 11, 2017 at 05:37:07PM +0000, Will Deacon wrote:
> On Wed, Nov 01, 2017 at 02:12:37PM +0000, Mark Rutland wrote:
> > The arm_pmu platform code explicitly checks for mismatched PPIs at probe
> > time, while the ACPI code leaves this to the core code. Future
> > refactoring will make this difficult for the core code to check, so
> > let's have the ACPI code check this explicitly.
> >
> > As before, upon a failure we'll continue on without an interrupt. Ho
> > hum.
> >
> > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > Cc: Will Deacon <will.deacon@arm.com>
> > ---
> > drivers/perf/arm_pmu.c | 16 ++++------------
> > drivers/perf/arm_pmu_acpi.c | 42 ++++++++++++++++++++++++++++++++++++++----
> > 2 files changed, 42 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > index 3d6d4c5f2356..e0242103d904 100644
> > --- a/drivers/perf/arm_pmu.c
> > +++ b/drivers/perf/arm_pmu.c
> > @@ -557,18 +557,10 @@ int armpmu_request_irq(struct arm_pmu *armpmu, int cpu)
> > if (!irq)
> > return 0;
> >
> > - if (irq_is_percpu_devid(irq) && cpumask_empty(&armpmu->active_irqs)) {
> > - err = request_percpu_irq(irq, handler, "arm-pmu",
> > - &hw_events->percpu_pmu);
> > - } else if (irq_is_percpu_devid(irq)) {
> > - int other_cpu = cpumask_first(&armpmu->active_irqs);
> > - int other_irq = per_cpu(hw_events->irq, other_cpu);
> > -
> > - if (irq != other_irq) {
> > - pr_warn("mismatched PPIs detected.\n");
> > - err = -EINVAL;
> > - goto err_out;
> > - }
> > + if (irq_is_percpu_devid(irq)) {
> > + if (cpumask_empty(&armpmu->active_irqs))
>
> Why not leave this as before, with a '&&' operator?
Because then we'd fall into the else case (for SPIs), were the
active_irqs mask empty.
Previously, that would have been caught by the irq_is_percpu_devid(irq)
case that got removed.
I can instead make this:
if (irq_is_percpu_devid(irq) && cpumask_empty(&armpmu->active_irqs)) {
err = request_percpu_irq(irq, handler, "arm-pmu",
&hw_events->percpu_pmu);
} else if (irq_is_percpu_devid(irq)) {
/* nothing to do */
} else {
< SPI case >
}
... but that seemed more painful to read.
Mark.
^ permalink raw reply
* [PATCH 2/5] arm_pmu: have armpmu_alloc() take GFP flags
From: Mark Rutland @ 2017-12-11 18:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211173702.GC3275@arm.com>
On Mon, Dec 11, 2017 at 05:37:02PM +0000, Will Deacon wrote:
> On Wed, Nov 01, 2017 at 02:12:36PM +0000, Mark Rutland wrote:
> > diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c
> > index 705f1a390e31..a52f5b673a15 100644
> > --- a/drivers/perf/arm_pmu_acpi.c
> > +++ b/drivers/perf/arm_pmu_acpi.c
> > @@ -127,7 +127,7 @@ static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void)
> > return pmu;
> > }
> >
> > - pmu = armpmu_alloc();
> > + pmu = armpmu_alloc(GFP_ATOMIC);
>
> I think I'd rather have armpmu_alloc_atomic as a wrapper around
> __armpmu_alloc(GFP_ATOMIC) and then leave the armpmu_alloc to pass
> GFP_KERNEL.
Sure; done.
Mark.
^ permalink raw reply
* [PATCH v3 00/20] arm64: Unmap the kernel whilst running in userspace (KPTI)
From: Catalin Marinas @ 2017-12-11 17:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512563739-25239-1-git-send-email-will.deacon@arm.com>
On Wed, Dec 06, 2017 at 12:35:19PM +0000, Will Deacon wrote:
> Patches are also pushed here:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git kpti
>
> Feedback and testing welcome. At this point, I'd like to start thinking
> about getting this merged for 4.16.
For the record, the fixed up version was pushed by Will here:
git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git kpti
and I queued it for 4.16 in the arm64 for-next/core branch (same tree as
above).
--
Catalin
^ permalink raw reply
* [PATCH 5/5] arm_pmu: acpi: request IRQs up-front
From: Mark Rutland @ 2017-12-11 17:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211173647.GA3275@arm.com>
On Mon, Dec 11, 2017 at 05:36:47PM +0000, Will Deacon wrote:
> On Wed, Nov 01, 2017 at 02:12:39PM +0000, Mark Rutland wrote:
> > We can't request IRQs in atomic context, so for ACPI systems we'll have
> > to request them up-front, and later associate them with CPUs.
> >
> > This patch reorganises the arm_pmu code to do so. As we no longer have
> > the arm_pmu strucutre at probe time, a number of prototypes need to be
> > adjusted, requiring changes to the common arm_pmu code and arm_pmu
> > platform code.
> > +void armpmu_bind_cpu(struct arm_pmu *armpmu, int cpu)
> > {
> > - struct arm_pmu_platdata *platdata = armpmu_get_platdata(armpmu);
> > - unsigned long irq_flags;
> > - struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
> > - int irq = per_cpu(hw_events->irq, cpu);
> > - if (!irq)
> > - return 0;
> > -
> > - if (platdata && platdata->irq_flags) {
> > - irq_flags = platdata->irq_flags;
> > - } else {
> > - irq_flags = ARM_PMU_IRQ_FLAGS;
> > - }
> > -
> > per_cpu(cpu_armpmu, cpu) = armpmu;
>
> Can we not make the binding implicit in armpmu_{request,free}_irq?
Unfortunately not.
As mentioned in the commit message (typo and all), in the ACPI case, we
need to request/free IRQs before we know the PMU.
Mark.
^ permalink raw reply
* [alsa-devel] [PATCH 5/8] ASoC: uniphier: add support for UniPhier AIO driver
From: Vinod Koul @ 2017-12-11 17:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211151629.GD9854@sirena.org.uk>
On Mon, Dec 11, 2017 at 03:16:29PM +0000, Mark Brown wrote:
> On Mon, Dec 11, 2017 at 06:21:58PM +0900, Katsuhiro Suzuki wrote:
>
> > But I can't find how to use/map this DAI in machine driver or Device-Tree or
> > something. I think that it's same as PCM DAI, am I correct?
>
> Yes, that probably makes sense from a binding point of view.
>
> > I read compress-offload.rst, but I can't find how do I test it. It seems aplay
> > of
> > alsa-util doesn't know compress audio formats. Should I use PulseAudio or
> > Android HAL to test compress audio APIs?
>
> IIRC tinyalsa has a compressed API test application - Vinod?
I guess it was sheer luck that i saw this :) email in CC reads
vinod.koul at linaro.org! I don't work for Linaro, not yet :D
And to the answer the question, Yes we have compressed API test application
in tinycompress which is located at git.alsa-project.org:tinycompress.git
We have both compressed audio playback as well as record test app, cplay and
crecord.
HTH
--
~Vinod
^ permalink raw reply
* [PATCH 08/13] x86: do not use print_symbol()
From: Borislav Petkov @ 2017-12-11 17:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211125025.2270-9-sergey.senozhatsky@gmail.com>
On Mon, Dec 11, 2017 at 09:50:20PM +0900, Sergey Senozhatsky wrote:
> print_symbol() uses extra stack space to sprintf() symbol
> information and then to feed that buffer to printk()
>
> char buffer[KSYM_SYMBOL_LEN];
>
> sprint_symbol(buffer, address);
> printk(fmt, buffer);
>
> Replace print_symbol() with a direct printk("%pS") call.
>
> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> Cc: Tony Luck <tony.luck@intel.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> ---
> arch/x86/kernel/cpu/mcheck/mce.c | 3 +--
> arch/x86/mm/mmio-mod.c | 5 ++---
> 2 files changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
> index b1d616d08eee..8ca8f6eb32db 100644
> --- a/arch/x86/kernel/cpu/mcheck/mce.c
> +++ b/arch/x86/kernel/cpu/mcheck/mce.c
> @@ -14,7 +14,6 @@
> #include <linux/capability.h>
> #include <linux/miscdevice.h>
> #include <linux/ratelimit.h>
> -#include <linux/kallsyms.h>
> #include <linux/rcupdate.h>
> #include <linux/kobject.h>
> #include <linux/uaccess.h>
> @@ -235,7 +234,7 @@ static void __print_mce(struct mce *m)
> m->cs, m->ip);
>
> if (m->cs == __KERNEL_CS)
> - print_symbol("{%s}", m->ip);
> + pr_cont("{%pS}", (void *)m->ip);
> pr_cont("\n");
> }
>
For the mce.c bit above:
Acked-by: Borislav Petkov <bp@suse.de>
Thx.
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
^ permalink raw reply
* [PATCH 0/5] arm_pmu: fix lockdep issues with ACPI systems
From: Will Deacon @ 2017-12-11 17:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171101141239.45340-1-mark.rutland@arm.com>
On Wed, Nov 01, 2017 at 02:12:34PM +0000, Mark Rutland wrote:
> Currently the arm_pmu ACPI code is somewhat dubious. It attempts ot
> allocate memory any manpiulate IRQs in a hotplug callback, which is an
> atomic context.
>
> These patches (based on the arm64 for-next/core branch [1]) attempt to
> address this by moving work out of hotplug callback, requiring a
> reorganisation of the common arm_pmu code.
>
> I've given these a boot-test on a Juno R1 system, both with DT and ACPI.
> In either case the PMU works as expected, and lockdep seems happy.
>
> I've pushed the series out to my arm64/acpi-pmu-lockdep branch [2].
This mostly looks ok to me; I've left some minor comments on individual
patches. My main concern is taking this as a fix, because there's an awful
lot here.
Is there anything simpler we can do for 4.15/stable?
Will
^ permalink raw reply
* [PATCH 3/5] arm_pmu: acpi: check for mismatched PPIs
From: Will Deacon @ 2017-12-11 17:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171101141239.45340-4-mark.rutland@arm.com>
On Wed, Nov 01, 2017 at 02:12:37PM +0000, Mark Rutland wrote:
> The arm_pmu platform code explicitly checks for mismatched PPIs at probe
> time, while the ACPI code leaves this to the core code. Future
> refactoring will make this difficult for the core code to check, so
> let's have the ACPI code check this explicitly.
>
> As before, upon a failure we'll continue on without an interrupt. Ho
> hum.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
> drivers/perf/arm_pmu.c | 16 ++++------------
> drivers/perf/arm_pmu_acpi.c | 42 ++++++++++++++++++++++++++++++++++++++----
> 2 files changed, 42 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index 3d6d4c5f2356..e0242103d904 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -557,18 +557,10 @@ int armpmu_request_irq(struct arm_pmu *armpmu, int cpu)
> if (!irq)
> return 0;
>
> - if (irq_is_percpu_devid(irq) && cpumask_empty(&armpmu->active_irqs)) {
> - err = request_percpu_irq(irq, handler, "arm-pmu",
> - &hw_events->percpu_pmu);
> - } else if (irq_is_percpu_devid(irq)) {
> - int other_cpu = cpumask_first(&armpmu->active_irqs);
> - int other_irq = per_cpu(hw_events->irq, other_cpu);
> -
> - if (irq != other_irq) {
> - pr_warn("mismatched PPIs detected.\n");
> - err = -EINVAL;
> - goto err_out;
> - }
> + if (irq_is_percpu_devid(irq)) {
> + if (cpumask_empty(&armpmu->active_irqs))
Why not leave this as before, with a '&&' operator?
Will
^ permalink raw reply
* [PATCH 2/5] arm_pmu: have armpmu_alloc() take GFP flags
From: Will Deacon @ 2017-12-11 17:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171101141239.45340-3-mark.rutland@arm.com>
On Wed, Nov 01, 2017 at 02:12:36PM +0000, Mark Rutland wrote:
> In ACPI systems, we don't know the makeup of CPUs until we hotplug them
> on, and thus have to allocate the PMU datastrcutures at hotplug time.
> Thus, we must use GFP_ATOMIC allocations.
>
> Reorganise the PMU allocators to take a GFP argument so that we can
> permit this.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
> drivers/perf/arm_pmu.c | 6 +++---
> drivers/perf/arm_pmu_acpi.c | 2 +-
> drivers/perf/arm_pmu_platform.c | 2 +-
> include/linux/perf/arm_pmu.h | 2 +-
> 4 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index 57df8dce8e19..3d6d4c5f2356 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -779,18 +779,18 @@ static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu)
> &cpu_pmu->node);
> }
>
> -struct arm_pmu *armpmu_alloc(void)
> +struct arm_pmu *armpmu_alloc(gfp_t flags)
> {
> struct arm_pmu *pmu;
> int cpu;
>
> - pmu = kzalloc(sizeof(*pmu), GFP_KERNEL);
> + pmu = kzalloc(sizeof(*pmu), flags);
> if (!pmu) {
> pr_info("failed to allocate PMU device!\n");
> goto out;
> }
>
> - pmu->hw_events = alloc_percpu(struct pmu_hw_events);
> + pmu->hw_events = alloc_percpu_gfp(struct pmu_hw_events, flags);
> if (!pmu->hw_events) {
> pr_info("failed to allocate per-cpu PMU data.\n");
> goto out_free_pmu;
> diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c
> index 705f1a390e31..a52f5b673a15 100644
> --- a/drivers/perf/arm_pmu_acpi.c
> +++ b/drivers/perf/arm_pmu_acpi.c
> @@ -127,7 +127,7 @@ static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void)
> return pmu;
> }
>
> - pmu = armpmu_alloc();
> + pmu = armpmu_alloc(GFP_ATOMIC);
I think I'd rather have armpmu_alloc_atomic as a wrapper around
__armpmu_alloc(GFP_ATOMIC) and then leave the armpmu_alloc to pass
GFP_KERNEL.
Will
^ permalink raw reply
* [PATCH 4/5] arm_pmu: note IRQs/PMUs per-cpu
From: Will Deacon @ 2017-12-11 17:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171101141239.45340-5-mark.rutland@arm.com>
On Wed, Nov 01, 2017 at 02:12:38PM +0000, Mark Rutland wrote:
> The current way we manage IRQs forces the ACPI PMU driver to request
> IRQs in the cpu bringup path, which isn't safe due to implicit memory
> allocations in the request_irq() path.
>
> To solve that, we need to decouple requesting IRQs from PMU management,
> requesting IRQs up-front, before we know the associated PMU. We will
> separately (and perhaps later) associate each IRQ with its PMU.
>
> This patch allows the IRQ handlers to be registered without a PMU dev
> argument, using a percpu pointer instead.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
> drivers/perf/arm_pmu.c | 93 ++++++++++++++++++++++++++++----------------
> include/linux/perf/arm_pmu.h | 3 +-
> 2 files changed, 62 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index e0242103d904..287b3edfb4cc 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -26,6 +26,9 @@
>
> #include <asm/irq_regs.h>
>
> +static DEFINE_PER_CPU(struct arm_pmu *, cpu_armpmu);
> +static DEFINE_PER_CPU(int, cpu_irq);
> +
> static int
> armpmu_map_cache_event(const unsigned (*cache_map)
> [PERF_COUNT_HW_CACHE_MAX]
> @@ -334,13 +337,9 @@ static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
> int ret;
> u64 start_clock, finish_clock;
>
> - /*
> - * we request the IRQ with a (possibly percpu) struct arm_pmu**, but
> - * the handlers expect a struct arm_pmu*. The percpu_irq framework will
> - * do any necessary shifting, we just need to perform the first
> - * dereference.
> - */
> - armpmu = *(void **)dev;
> + armpmu = this_cpu_read(cpu_armpmu);
> + if (WARN_ON_ONCE(!armpmu))
> + return IRQ_NONE;
>
> plat = armpmu_get_platdata(armpmu);
>
> @@ -531,40 +530,56 @@ int perf_num_counters(void)
> }
> EXPORT_SYMBOL_GPL(perf_num_counters);
>
> -void armpmu_free_irq(struct arm_pmu *armpmu, int cpu)
> +int armpmu_count_irq_users(const int irq)
> {
> - struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
> - int irq = per_cpu(hw_events->irq, cpu);
> + int cpu, count = 0;
> +
> + for_each_possible_cpu(cpu) {
> + if (per_cpu(cpu_irq, cpu) == irq)
> + count++;
> + }
> +
> + return count;
> +}
>
> - if (!cpumask_test_and_clear_cpu(cpu, &armpmu->active_irqs))
> +void __armpmu_free_irq(int irq, int cpu)
> +{
> + if (per_cpu(cpu_irq, cpu) == 0)
> + return;
> + if (WARN_ON(irq != per_cpu(cpu_irq, cpu)))
> return;
>
> if (irq_is_percpu_devid(irq)) {
> - free_percpu_irq(irq, &hw_events->percpu_pmu);
> - cpumask_clear(&armpmu->active_irqs);
> - return;
> + if (armpmu_count_irq_users(irq) == 1)
> + free_percpu_irq(irq, &cpu_armpmu);
Do you actually need the count, or could you just free the irq the first
time this is called and set all of the cpu_irqs to 0?
Will
^ permalink raw reply
* [PATCH 5/5] arm_pmu: acpi: request IRQs up-front
From: Will Deacon @ 2017-12-11 17:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171101141239.45340-6-mark.rutland@arm.com>
On Wed, Nov 01, 2017 at 02:12:39PM +0000, Mark Rutland wrote:
> We can't request IRQs in atomic context, so for ACPI systems we'll have
> to request them up-front, and later associate them with CPUs.
>
> This patch reorganises the arm_pmu code to do so. As we no longer have
> the arm_pmu strucutre at probe time, a number of prototypes need to be
> adjusted, requiring changes to the common arm_pmu code and arm_pmu
> platform code.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
> drivers/perf/arm_pmu.c | 37 +++----------------------------------
> drivers/perf/arm_pmu_acpi.c | 20 +++++++-------------
> drivers/perf/arm_pmu_platform.c | 25 ++++++++++++++++++++++---
> include/linux/perf/arm_pmu.h | 13 +++++++++++--
> 4 files changed, 43 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index 287b3edfb4cc..534b4b3fb440 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -323,13 +323,6 @@ validate_group(struct perf_event *event)
> return 0;
> }
>
> -static struct arm_pmu_platdata *armpmu_get_platdata(struct arm_pmu *armpmu)
> -{
> - struct platform_device *pdev = armpmu->plat_device;
> -
> - return pdev ? dev_get_platdata(&pdev->dev) : NULL;
> -}
> -
> static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
> {
> struct arm_pmu *armpmu;
> @@ -542,7 +535,7 @@ int armpmu_count_irq_users(const int irq)
> return count;
> }
>
> -void __armpmu_free_irq(int irq, int cpu)
> +void armpmu_free_irq(int irq, int cpu)
> {
> if (per_cpu(cpu_irq, cpu) == 0)
> return;
> @@ -559,16 +552,7 @@ void __armpmu_free_irq(int irq, int cpu)
> per_cpu(cpu_irq, cpu) = 0;
> }
>
> -void armpmu_free_irq(struct arm_pmu *armpmu, int cpu)
> -{
> - struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
> - int irq = per_cpu(hw_events->irq, cpu);
> -
> - __armpmu_free_irq(irq, cpu);
> - per_cpu(cpu_armpmu, cpu) = NULL;
> -}
> -
> -int armpmu_request_irq_flags(int irq, unsigned long irq_flags, int cpu)
> +int armpmu_request_irq(int irq, unsigned long irq_flags, int cpu)
> {
> int err = 0;
> const irq_handler_t handler = armpmu_dispatch_irq;
> @@ -603,24 +587,9 @@ int armpmu_request_irq_flags(int irq, unsigned long irq_flags, int cpu)
> return err;
> }
>
> -int armpmu_request_irq(struct arm_pmu *armpmu, int cpu)
> +void armpmu_bind_cpu(struct arm_pmu *armpmu, int cpu)
> {
> - struct arm_pmu_platdata *platdata = armpmu_get_platdata(armpmu);
> - unsigned long irq_flags;
> - struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
> - int irq = per_cpu(hw_events->irq, cpu);
> - if (!irq)
> - return 0;
> -
> - if (platdata && platdata->irq_flags) {
> - irq_flags = platdata->irq_flags;
> - } else {
> - irq_flags = ARM_PMU_IRQ_FLAGS;
> - }
> -
> per_cpu(cpu_armpmu, cpu) = armpmu;
Can we not make the binding implicit in armpmu_{request,free}_irq?
Will
^ permalink raw reply
* [PATCH] ASoC: sun4i-codec: fix to enable 12Khz and 24Khz audio playback and capture sample rates
From: Andrea Bondavalli @ 2017-12-11 17:31 UTC (permalink / raw)
To: linux-arm-kernel
H3 ASoC supports 12Khz and 24Khz audio sample rates but the current drivers doesn't advertise
these rates properly and they cannot be used.
For example attempt to capture at 12Khz uses 11Khz (same applies to audio playback):
# arecord -f S16_LE -c 2 -r 12000 -D hw:0,0 -t raw /tmp/testS16_LE.wav
Recording raw data '/tmp/testS16_LE.wav' : Signed 16 bit Little Endian, Rate 12000 Hz, Stereo
Warning: rate is not accurate (requested = 12000Hz, got = 11025Hz)
This patch fixes the audio sample rates declared and supported by the driver
according to the H3 data sheet.
Specifically for audio playback:
8000, 11050, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, 192000
and for audio capture:
8000, 11050, 12000, 16000, 22050, 24000, 32000, 44100, 48000
Signed-off-by: Andrea Bondavalli <andrea.bondavalli74@gmail.com>
---
sound/soc/sunxi/sun4i-codec.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 5da4efe..c79e8a4 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -590,12 +590,28 @@ static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
hwrate);
}
+
+static unsigned int sun4i_codec_src_rates[] = {
+ 8000, 11025, 12000, 16000, 22050, 24000, 32000,
+ 44100, 48000, 88200, 96000, 176400, 192000
+};
+
+
+static struct snd_pcm_hw_constraint_list sun4i_codec_constraints = {
+ .count = ARRAY_SIZE(sun4i_codec_src_rates),
+ .list = sun4i_codec_src_rates,
+};
+
+
static int sun4i_codec_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &sun4i_codec_constraints);
+
/*
* Stop issuing DRQ when we have room for less than 16 samples
* in our TX FIFO
@@ -633,9 +649,7 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
.channels_max = 2,
.rate_min = 8000,
.rate_max = 192000,
- .rates = SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_192000,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.sig_bits = 24,
@@ -645,11 +659,8 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
- .rate_max = 192000,
- .rates = SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_192000 |
- SNDRV_PCM_RATE_KNOT,
+ .rate_max = 48000,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.sig_bits = 24,
@@ -1128,7 +1139,7 @@ static const struct snd_soc_component_driver sun4i_codec_component = {
.name = "sun4i-codec",
};
-#define SUN4I_CODEC_RATES SNDRV_PCM_RATE_8000_192000
+#define SUN4I_CODEC_RATES SNDRV_PCM_RATE_CONTINUOUS
#define SUN4I_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
--
2.7.4
^ permalink raw reply related
* [PATCH] ASoC: sun4i-codec: fix to enable 12Khz and 24Khz audio playback and capture sample rates
From: Andrea Bondavalli @ 2017-12-11 17:24 UTC (permalink / raw)
To: linux-arm-kernel
H3 ASoC supports 12Khz and 24Khz audio sample rates but the current drivers doesn't
advertise these rates properly and they cannot be used.
For example attempt to capture at 12Khz uses 11Khz (same applies to audio playback):
Recording raw data '/tmp/test' : Signed 16 bit Little Endian, Rate 12000 Hz, Stereo
Warning: rate is not accurate (requested = 12000Hz, got = 11025Hz)
This patch fixes the audio sample rates declared and supported by the driver
according to the H3 data sheet.
Specifically for audio playback:
8000, 11050, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, 192000
and for audio capture:
8000, 11050, 12000, 16000, 22050, 24000, 32000, 44100, 48000
Signed-off-by: Andrea Bondavalli <andrea.bondavalli74@gmail.com>
---
sound/soc/sunxi/sun4i-codec.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 5da4efe..c79e8a4 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -590,12 +590,28 @@ static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
hwrate);
}
+
+static unsigned int sun4i_codec_src_rates[] = {
+ 8000, 11025, 12000, 16000, 22050, 24000, 32000,
+ 44100, 48000, 88200, 96000, 176400, 192000
+};
+
+
+static struct snd_pcm_hw_constraint_list sun4i_codec_constraints = {
+ .count = ARRAY_SIZE(sun4i_codec_src_rates),
+ .list = sun4i_codec_src_rates,
+};
+
+
static int sun4i_codec_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &sun4i_codec_constraints);
+
/*
* Stop issuing DRQ when we have room for less than 16 samples
* in our TX FIFO
@@ -633,9 +649,7 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
.channels_max = 2,
.rate_min = 8000,
.rate_max = 192000,
- .rates = SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_192000,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.sig_bits = 24,
@@ -645,11 +659,8 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
- .rate_max = 192000,
- .rates = SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_192000 |
- SNDRV_PCM_RATE_KNOT,
+ .rate_max = 48000,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.sig_bits = 24,
@@ -1128,7 +1139,7 @@ static const struct snd_soc_component_driver sun4i_codec_component = {
.name = "sun4i-codec",
};
-#define SUN4I_CODEC_RATES SNDRV_PCM_RATE_8000_192000
+#define SUN4I_CODEC_RATES SNDRV_PCM_RATE_CONTINUOUS
#define SUN4I_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
--
2.7.4
^ permalink raw reply related
* [PATCH 2/2] ARM: davinci: remove watchdog reset
From: David Lechner @ 2017-12-11 17:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513012869-7647-1-git-send-email-david@lechnology.com>
This removes the watchdog reset code. The reset has been moved to
drivers/watchdog/davinci_wdt.c. The watchdog driver registers the reset
with the kernel so defining a reset for each machine is no longer needed.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/board-da830-evm.c | 1 -
arch/arm/mach-davinci/board-da850-evm.c | 1 -
arch/arm/mach-davinci/board-dm355-evm.c | 1 -
arch/arm/mach-davinci/board-dm355-leopard.c | 1 -
arch/arm/mach-davinci/board-dm365-evm.c | 1 -
arch/arm/mach-davinci/board-dm644x-evm.c | 1 -
arch/arm/mach-davinci/board-dm646x-evm.c | 2 -
arch/arm/mach-davinci/board-mityomapl138.c | 1 -
arch/arm/mach-davinci/board-neuros-osd2.c | 1 -
arch/arm/mach-davinci/board-omapl138-hawk.c | 1 -
arch/arm/mach-davinci/board-sffsdr.c | 1 -
arch/arm/mach-davinci/clock.h | 3 --
arch/arm/mach-davinci/da8xx-dt.c | 1 -
arch/arm/mach-davinci/devices-da8xx.c | 13 -------
arch/arm/mach-davinci/devices.c | 7 +---
arch/arm/mach-davinci/include/mach/common.h | 1 -
arch/arm/mach-davinci/include/mach/da8xx.h | 1 -
arch/arm/mach-davinci/time.c | 57 -----------------------------
18 files changed, 1 insertion(+), 94 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index 2cc5426..7adf009 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -642,5 +642,4 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
.init_machine = da830_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = da8xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 458f26d..8602d0d 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1485,6 +1485,5 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
.init_machine = da850_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = da8xx_restart,
.reserve = da8xx_rproc_reserve_cma,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 2b4d553..3c15cb7 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -420,5 +420,4 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
.init_machine = dm355_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 69399d7..3ebc89d 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -275,5 +275,4 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
.init_machine = dm355_leopard_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index e414cb9..3daeac7 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -778,6 +778,5 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
.init_machine = dm365_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 6b26786..8d8c4ab 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -821,5 +821,4 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
.init_machine = davinci_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index b3b81a8..dafc852 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -804,7 +804,6 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
.init_machine = evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = davinci_restart,
MACHINE_END
MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
@@ -815,6 +814,5 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
.init_machine = evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index c930c31..f9a725a 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -574,5 +574,4 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
.init_machine = mityomapl138_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = da8xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 925ada1..ff871a0 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -231,5 +231,4 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
.init_machine = davinci_ntosd2_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index c1277b3..bc8a747 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -338,6 +338,5 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
.init_machine = omapl138_hawk_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = da8xx_restart,
.reserve = da8xx_rproc_reserve_cma,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 4038de8..2922da9 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -154,5 +154,4 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
.init_machine = davinci_sffsdr_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
- .restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index aea4f14..a0b559e 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -131,9 +131,6 @@ void davinci_clk_enable(struct davinci_clk *clk);
void davinci_clk_disable(struct davinci_clk *clk);
int davinci_clk_register(struct davinci_clk *clk);
-extern struct platform_device davinci_wdt_device;
-extern void davinci_watchdog_reset(struct platform_device *);
-
static inline struct davinci_clk *to_davinci_clk(struct clk_hw *hw)
{
if (IS_ERR_OR_NULL(hw))
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 3630f0a..ab199f4 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -100,7 +100,6 @@ DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
.init_machine = da850_init_machine,
.dt_compat = da850_boards_compat,
.init_late = davinci_init_late,
- .restart = da8xx_restart,
MACHINE_END
#endif
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 6724a8d..272e12e 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -371,19 +371,6 @@ static struct platform_device da8xx_wdt_device = {
.resource = da8xx_watchdog_resources,
};
-void da8xx_restart(enum reboot_mode mode, const char *cmd)
-{
- struct device *dev;
-
- dev = bus_find_device_by_name(&platform_bus_type, NULL, "davinci-wdt");
- if (!dev) {
- pr_err("%s: failed to find watchdog device\n", __func__);
- return;
- }
-
- davinci_watchdog_reset(to_platform_device(dev));
-}
-
int __init da8xx_register_watchdog(void)
{
return platform_device_register(&da8xx_wdt_device);
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 3ae70f2..0edda40 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -282,18 +282,13 @@ static struct resource wdt_resources[] = {
},
};
-struct platform_device davinci_wdt_device = {
+static struct platform_device davinci_wdt_device = {
.name = "davinci-wdt",
.id = -1,
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
};
-void davinci_restart(enum reboot_mode mode, const char *cmd)
-{
- davinci_watchdog_reset(&davinci_wdt_device);
-}
-
int davinci_init_wdt(void)
{
return platform_device_register(&davinci_wdt_device);
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 69a0ad9..f0d5e858 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -80,7 +80,6 @@ extern struct davinci_soc_info davinci_soc_info;
extern void davinci_common_init(const struct davinci_soc_info *soc_info);
extern void davinci_init_ide(void);
-void davinci_restart(enum reboot_mode mode, const char *cmd);
void davinci_init_late(void);
#ifdef CONFIG_DAVINCI_RESET_CLOCKS
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index dd12e39..3481a0d 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -121,7 +121,6 @@ int da850_register_vpif_display
(struct vpif_display_config *display_config);
int da850_register_vpif_capture
(struct vpif_capture_config *capture_config);
-void da8xx_restart(enum reboot_mode mode, const char *cmd);
void da8xx_rproc_reserve_cma(void);
int da8xx_register_rproc(void);
int da850_register_gpio(void);
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 034f865..1bb991a 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -80,13 +80,6 @@ enum {
#define TGCR_UNRESET 0x1
#define TGCR_RESET_MASK 0x3
-#define WDTCR_WDEN_SHIFT 14
-#define WDTCR_WDEN_DISABLE 0x0
-#define WDTCR_WDEN_ENABLE 0x1
-#define WDTCR_WDKEY_SHIFT 16
-#define WDTCR_WDKEY_SEQ0 0xa5c6
-#define WDTCR_WDKEY_SEQ1 0xda7e
-
struct timer_s {
char *name;
unsigned int id;
@@ -409,53 +402,3 @@ void __init davinci_timer_init(void)
for (i=0; i< ARRAY_SIZE(timers); i++)
timer32_config(&timers[i]);
}
-
-/* reset board using watchdog timer */
-void davinci_watchdog_reset(struct platform_device *pdev)
-{
- u32 tgcr, wdtcr;
- void __iomem *base;
- struct clk *wd_clk;
-
- base = ioremap(pdev->resource[0].start, SZ_4K);
- if (WARN_ON(!base))
- return;
-
- wd_clk = clk_get(&pdev->dev, NULL);
- if (WARN_ON(IS_ERR(wd_clk)))
- return;
- clk_prepare_enable(wd_clk);
-
- /* disable, internal clock source */
- __raw_writel(0, base + TCR);
-
- /* reset timer, set mode to 64-bit watchdog, and unreset */
- tgcr = 0;
- __raw_writel(tgcr, base + TGCR);
- tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
- tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
- (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
- __raw_writel(tgcr, base + TGCR);
-
- /* clear counter and period regs */
- __raw_writel(0, base + TIM12);
- __raw_writel(0, base + TIM34);
- __raw_writel(0, base + PRD12);
- __raw_writel(0, base + PRD34);
-
- /* put watchdog in pre-active state */
- wdtcr = __raw_readl(base + WDTCR);
- wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
- (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
- __raw_writel(wdtcr, base + WDTCR);
-
- /* put watchdog in active state */
- wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
- (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
- __raw_writel(wdtcr, base + WDTCR);
-
- /* write an invalid value to the WDKEY field to trigger
- * a watchdog reset */
- wdtcr = 0x00004000;
- __raw_writel(wdtcr, base + WDTCR);
-}
--
2.7.4
^ permalink raw reply related
* [PATCH 1/2] watchdog: davinci_wdt: add restart function
From: David Lechner @ 2017-12-11 17:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513012869-7647-1-git-send-email-david@lechnology.com>
This adds a restart function to the davinci watchdog timer driver.
This is copied from arch/arm/mach-davinci/time.c and will allow us to
remove the code from there.
Signed-off-by: David Lechner <david@lechnology.com>
---
drivers/watchdog/davinci_wdt.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 2f46487..3e4c592 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -140,6 +140,42 @@ static unsigned int davinci_wdt_get_timeleft(struct watchdog_device *wdd)
return wdd->timeout - timer_counter;
}
+static int davinci_wdt_restart(struct watchdog_device *wdd,
+ unsigned long action, void *data)
+{
+ struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd);
+ u32 tgcr, wdtcr;
+
+ /* disable, internal clock source */
+ iowrite32(0, davinci_wdt->base + TCR);
+
+ /* reset timer, set mode to 64-bit watchdog, and unreset */
+ tgcr = 0;
+ iowrite32(tgcr, davinci_wdt->base + TGCR);
+ tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET;
+ iowrite32(tgcr, davinci_wdt->base + TGCR);
+
+ /* clear counter and period regs */
+ iowrite32(0, davinci_wdt->base + TIM12);
+ iowrite32(0, davinci_wdt->base + TIM34);
+ iowrite32(0, davinci_wdt->base + PRD12);
+ iowrite32(0, davinci_wdt->base + PRD34);
+
+ /* put watchdog in pre-active state */
+ wdtcr = WDKEY_SEQ0 | WDEN;
+ iowrite32(wdtcr, davinci_wdt->base + WDTCR);
+
+ /* put watchdog in active state */
+ wdtcr = WDKEY_SEQ1 | WDEN;
+ iowrite32(wdtcr, davinci_wdt->base + WDTCR);
+
+ /* write an invalid value to the WDKEY field to trigger a restart */
+ wdtcr = 0x00004000;
+ iowrite32(wdtcr, davinci_wdt->base + WDTCR);
+
+ return 0;
+}
+
static const struct watchdog_info davinci_wdt_info = {
.options = WDIOF_KEEPALIVEPING,
.identity = "DaVinci/Keystone Watchdog",
@@ -151,6 +187,7 @@ static const struct watchdog_ops davinci_wdt_ops = {
.stop = davinci_wdt_ping,
.ping = davinci_wdt_ping,
.get_timeleft = davinci_wdt_get_timeleft,
+ .restart = davinci_wdt_restart,
};
static int davinci_wdt_probe(struct platform_device *pdev)
@@ -195,6 +232,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, davinci_wdt);
watchdog_set_nowayout(wdd, 1);
+ watchdog_set_restart_priority(wdd, 128);
wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem);
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox