Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/5] Add support for legacy SCPI protocol
From: Kevin Hilman @ 2016-10-19 15:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <ff62da76-a7b9-6891-c198-f9049dfa7bb5@arm.com>

Sudeep Holla <sudeep.holla@arm.com> writes:

> On 19/10/16 13:51, Neil Armstrong wrote:
>> This patchset aims to support the legacy SCPI firmware implementation that was
>> delivered as early technology preview for the JUNO platform.
>>
>> Finally a stable, maintained and public implementation for the SCPI protocol
>> has been upstreamed part of the JUNO support and it is the recommended way
>> of implementing SCP communication on ARMv8 platforms.
>>
>> The Amlogic GXBB platform is using this legacy protocol, as the RK3368 & RK3399
>> platforms. This patchset will only add support for Amlogic GXBB SoC.
>>
>> This patchset add support for the legacy protocol in the arm_scpi.c file,
>> avoiding code duplication.
>>
>> This patchset is rebased against scpi-updates/for-next from [2] and with
>> already merged patches [3], [4] and [5] and ommited in this patchset.
>>
>> Last RFC discution thread can be found at : https://lkml.org/lkml/2016/8/9/210
>>
>> Changes since v4 at : http://lkml.kernel.org/r/1475652814-30619-1-git-send-email-narmstrong at baylibre.com
>>  - Removed legacy locking scheme
>>  - Removed cmd copy back after token insert
>>  - Various cleanups
>>
>> Changes since v3 at : http://lkml.kernel.org/r/1473262477-18045-1-git-send-email-narmstrong at baylibre.com
>>  - Changed back author to Sudeep Holla for first patch
>>  - Merged legacy functions to scpi_send_message, tx_prepare and handle_remote_message
>>  - Added legacy locking scheme
>>  - Merged back legacy_scpi_sensor_get_value into scpi_sensor_get_value
>>  - Rebased on linux-next-20161004 with patchset [1]
>>
>> Changes since v2 at : http://lkml.kernel.org/r/1471952816-30877-1-git-send-email-narmstrong at baylibre.com
>>  - Added command indirection table and use it in each commands
>>  - Added bitmap for high priority commands
>>  - Cleaned up legacy tx_prepare/handle_message to align to standard functions
>>  - Dropped legacy_scpi_ops
>>
>> Changes since v1 at : http://lkml.kernel.org/r/1471515066-3626-1-git-send-email-narmstrong at baylibre.com
>>  - Dropped vendor_send_message and rockchip vendor mechanism patches
>>  - Merged alternate functions into main functions using is_legacy boolean
>>  - Added DT match table to set is_legacy to true
>>  - Kept alternate scpi_ops structure for legacy
>>
>> [1] http://lkml.kernel.org/r/1475595430-30075-1-git-send-email-narmstrong at baylibre.com
>> [2] git.kernel.org/sudeep.holla/linux
>> [3] scpi: Add cmd indirection table to prepare for legacy commands
>> [4] scpi: grow MAX_DVFS_OPPS to 16 entries
>> [5] dt-bindings: Add support for Amlogic GXBB SCPI Interface
>>
>> Neil Armstrong (5):
>>   scpi: Add alternative legacy structures, functions and macros
>>   scpi: Do not fail if get_capabilities is not implemented
>>   scpi: Add support for Legacy match table for Amlogic GXBB SoC
>>   ARM64: dts: meson-gxbb: Add SRAM node
>>   ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes
>>
>>  arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi |  57 ++++++++
>>  drivers/firmware/arm_scpi.c                 | 206 +++++++++++++++++++++++++---
>>  2 files changed, 245 insertions(+), 18 deletions(-)
>>
>
> Nice to see this diff stat from a whole new file legacy_scpi.c and 1000+
> delta. Thanks for working on this. I have applied the first 3 patches in
> this series with some subject/commit message changes to [1].
>
> I assume the DT changes needs to go via the corresponding platform
> maintainer.

Yes, I'll queue the DT changes through the amlogic tree (which then goes
through the arm-soc tree.)

Thanks,

Kevin

^ permalink raw reply

* [PATCH 1/3] ARM: socfpga: dtsi: add qspi node
From: Dinh Nguyen @ 2016-10-19 15:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018074304.6744-1-s.trumtrar@pengutronix.de>

On Tue, 18 Oct 2016, Steffen Trumtrar wrote:

> Add the qspi node to the socfpga dtsi file.
> 
> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> ---
>  arch/arm/boot/dts/socfpga.dtsi | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
> index 9f48141270b8..0dc96d2248a6 100644
> --- a/arch/arm/boot/dts/socfpga.dtsi
> +++ b/arch/arm/boot/dts/socfpga.dtsi
> @@ -705,6 +705,20 @@
>  			reg = <0xffff0000 0x10000>;
>  		};
>  
> +		qspi: spi at ff705000 {
> +			compatible = "cdns,qspi-nor";
> +                        #address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0xff705000 0x1000>,
> +			      <0xffa00000 0x1000>;

I think the QSPI data address space has a length of 0x100000. I've fixed it up locally.

BR,
Dinh

^ permalink raw reply

* Build failure with v4.9-rc1 and GCC trunk -- compiler weirdness
From: Linus Torvalds @ 2016-10-19 15:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019153746.GA4411@x4>

On Wed, Oct 19, 2016 at 8:37 AM, Markus Trippelsdorf
<markus@trippelsdorf.de> wrote:
>
> This is a gcc bug, see:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72785

Well, in the meantime we apparently have to live with it. Unless Will
is using some unreleased gcc version that nobody else is using and we
can just ignore it?

I don't think the link-time check is so important that we need to
notice it, and the "____ilog2_NaN()" could just be replaced with "0".

                 Linus

^ permalink raw reply

* [PATCH] mtd: nand: Add OX820 NAND Support
From: Boris Brezillon @ 2016-10-19 15:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <0f5398bb-52f1-d5bb-834c-dead4f708fd3@baylibre.com>

On Wed, 19 Oct 2016 17:46:01 +0200
Neil Armstrong <narmstrong@baylibre.com> wrote:

> >> +/* Single CS command control */
> >> +static void oxnas_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
> >> +				unsigned int ctrl)
> >> +{
> >> +	struct nand_chip *chip = mtd_to_nand(mtd);
> >> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
> >> +
> >> +	if (ctrl & NAND_CTRL_CHANGE) {
> >> +		if (ctrl & NAND_CLE)
> >> +			oxnas->ctrl = OXNAS_NAND_CMD_CLE;
> >> +		else if (ctrl & NAND_ALE)
> >> +			oxnas->ctrl = OXNAS_NAND_CMD_ALE;
> >> +		else
> >> +			oxnas->ctrl = 0;
> >> +	}
> >> +
> >> +	if (cmd != NAND_CMD_NONE)
> >> +		writeb(cmd, oxnas->io_base + oxnas->ctrl);  
> > 
> > There's no need to test the NAND_CTRL_CHANGE here, and I don't think
> > the CLE or ALE flag is ever set when cmd == CMD_NONE. So, you can kill
> > the ->ctrl field and simply do:
> > 
> > 	if (ctrl & NAND_CLE)
> > 		writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_CLE);
> > 	else if (ctrl & NAND_ALE)
> > 		writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_ALE);
> >   
> >> +}  
> 
> Hmm, except it's needed back in the oxnas_nand_write_buf() call (don't ask me why)
> so I don't see how to simplify more this function.

Are you sure? Can you add a WARN(oxnas->ctrl) in oxnas_nand_write_buf()
to check if it's ever the case? I'm almost sure there is a call to
->cmd_ctrl() with none of the CLE and ALE flags set before the
->write_buf() call.

^ permalink raw reply

* [PATCH] dmaengine: qcom_hidma: cleanup sysfs entries during remove
From: Sinan Kaya @ 2016-10-19 15:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019132622.GN2467@localhost>

On 10/19/2016 6:26 AM, Vinod Koul wrote:
>> -static int hidma_create_sysfs_entry(struct hidma_dev *dev, char *name,
>> > -				    int mode)
>> > +static int hidma_sysfs_uninit(struct hidma_dev *dev)
>> > +{
>> > +	if (!dev->chid_attrs)
>> > +		return -ENOMEM;
> why is this check required? Probe would fail in init case right.
> Second returning error doesnt help as you are calling this from remove and
> return is not checked so redundant!

Agreed, I'll get rid of the attrs and also the return value.

-- 
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH 2/3] ARM: convert to generated system call tables
From: Russell King - ARM Linux @ 2016-10-19 15:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <13702107.LdHY4HTXyY@wuerfel>

On Wed, Oct 19, 2016 at 05:30:49PM +0200, Arnd Bergmann wrote:
> On Tuesday, October 18, 2016 8:31:38 PM CEST Russell King wrote:
> > Convert ARM to use a similar mechanism to x86 to generate the unistd.h
> > system call numbers and the various kernel system call tables.  This
> > means that rather than having to edit three places (asm/unistd.h for
> > the total number of system calls, uapi/asm/unistd.h for the system call
> > numbers, and arch/arm/kernel/calls.S for the call table) we have only
> > one place to edit, making the process much more simple.
> > 
> > The scripts have knowledge of the table padding requirements, so there's
> > no need to worry about __NR_syscalls not fitting within the immediate
> > constant field of ALU instructions anymore.
> > 
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> 
> Ah, very nice!
> 
> I have some vague plans to do something like this for all architectures,
> so having it done for one of the more complex examples (there are very
> few architectures with more than one table) simplifies it a lot.
> 
> The next step is probably to do it for asm-generic/unistd.h, which
> covers a lot of architectures, and then we can introduce a shared
> table for all future additions so we only have to add the new calls
> in one place, and change the scripts so they can merge two input
> files into one.

Architecture maintainers like to verify that the system call works on
their architecture before they push it out into the wild; your idea
effectively bypasses architecture maintainer review and testing, so
is bad.  For something as critical as system call interfaces, that
step is critical: introducing a new system call across all architectures
that then fails to work correctly on a particular architecture invites
userspace to work around the problem, and the brokenness then becomes
user API which can't be fixed.

> > +# Where abi is:
> > +#  common - for system calls shared between oabi and eabi
> > +#  oabi   - for oabi-only system calls (may have compat)
> > +#  eabi   - for eabi-only system calls
> 
> Why do we need all three? I would have guessed that these two are
> sufficient to cover all cases:
> 
> arm	- one entry for eabi, optional second entry for oabi if different
> oabi	- only one entry for oabi, syscall is not used on eabi

You haven't quite understood if you think the second entry gets used
for OABI - but that's not surprising because the issues here are
quite complex.

For OABI-only, all the oabi and first entry in common gets used.
For EABI-only, all the eabi and first entry in common gets used.
For EABI with OABI compat, EABI uses eabi and the first entry in common,
but the OABI compat table uses the oabi and common entries, prefering
the second entry where present.

Yes, for the cases where we list the oabi and eabi together like you
quoted, currently there are no differences between the system calls,
and in my latest version, they've already been modified down to just
a single "common" entry, leaving us without any eabi entries.
However, I want to retain the ability to have separate eabi entries
if needs be.  Such a case would be a system call which needs a helper
for arguments passed in >4 registers on EABI but not OABI (eg, because
of an non-naturally aligned 64-bit quantity passed in r1/r2 on OABI
but r2/r3 in EABI.)

You'll find the latest version in the next linux-next, or my current
for-next branch.

> > diff --git a/arch/arm/tools/syscallhdr.sh b/arch/arm/tools/syscallhdr.sh
> > new file mode 100644
> > index 000000000000..72d4b2e3bdec
> > --- /dev/null
> > +++ b/arch/arm/tools/syscallhdr.sh
> 
> The scripts are still very similar to the x86 version. Any chance
> we can move them to a top-level scripts/syscall/ directory and make
> them work for both architectures? It would be good to avoid duplicating
> them for all the other architectures too, so starting out with a common
> version could make that easier.

The fileguard prefix would have to be specified as an additional
argument to achieve that, but I don't see that as a big problem.

The syscalltbl.sh script is particularly architecture specific, as
our "compat" isn't the same as x86's "compat" requirements.

The syscallnr.sh script kind-of looks like a candidate, but it has
ARM arch specifics to it (knowing that the number of system calls
needs to fit within the 8-bit value plus 4-bit shift constant
representation of ARM ALU instructions.)  Maybe a generic version
without that knowledge would work, provided architectures can
override it.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* [PATCH v20 10/10] fpga-manager: Add Socfpga Arria10 support
From: atull @ 2016-10-19 15:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018210159.GA1916@live.com>

On Tue, 18 Oct 2016, Moritz Fischer wrote:

> On Mon, Oct 17, 2016 at 11:09:41AM -0500, Alan Tull wrote:
> > Add low level driver to support reprogramming FPGAs for Altera
> > SoCFPGA Arria10.
> > 
> > Signed-off-by: Alan Tull <atull@opensource.altera.com>
> 
> Reviewed-by: Moritz Fischer <moritz.fischer@ettus.com>

> > +
> > +MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
> > +MODULE_DESCRIPTION("SoCFPGA Arria10 FPGA Manager");
> > +MODULE_LICENSE("GPL v2");
> > -- 
> > 2.10.1
> > 
> 
> Looking good,
> 
> Moritz
> 

Hi Moritz,

Thanks!

Alan

^ permalink raw reply

* [PATCH] mtd: nand: Add OX820 NAND Support
From: Neil Armstrong @ 2016-10-19 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019173704.75592f52@bbrezillon>

On 10/19/2016 05:37 PM, Boris Brezillon wrote:
> On Wed, 19 Oct 2016 16:55:23 +0200
> Neil Armstrong <narmstrong@baylibre.com> wrote:

[...]

>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mtd/oxnas-nand.txt
>> @@ -0,0 +1,24 @@
>> +* Oxford Semiconductor OXNAS NAND Controller
>> +
>> +Please refer to nand.txt for generic information regarding MTD NAND bindings.
>> +
>> +Required properties:
>> + - compatible: "oxsemi,ox820-nand"
>> + - reg: Base address and length for NAND mapped memory.
>> +
>> +Optional Properties:
>> + - clocks: phandle to the NAND gate clock if needed.
>> + - resets: phandle to the NAND reset control if needed.
>> +
>> +Example:
>> +
>> +nand: nand at 41000000 {
> 
> nandc: nand-controller at 41000000 {
> 
>> +	compatible = "oxsemi,ox820-nand";
>> +	reg = <0x41000000 0x100000>;
>> +	nand-ecc-mode = "soft";
>> +	clocks = <&stdclk CLK_820_NAND>;
>> +	resets = <&reset RESET_NAND>;
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>> +	status = "disabled";
>> +};
> 
> You should probably provide an example where the NAND controller is
> enabled and at least one nand chip is connected to the NAND bus.

Indeed, I forgot that.

[...]

>> +
>> +static uint8_t oxnas_nand_read_byte(struct mtd_info *mtd)
>> +{
>> +	struct nand_chip *chip = mtd_to_nand(mtd);
>> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
>> +
>> +	return readb(oxnas->io_base);
>> +}
>> +
>> +static void oxnas_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
>> +{
>> +	struct nand_chip *chip = mtd_to_nand(mtd);
>> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
>> +
>> +	ioread8_rep(oxnas->io_base, buf, len);
>> +}
>> +
>> +static void oxnas_nand_write_buf(struct mtd_info *mtd,
>> +				 const uint8_t *buf, int len)
>> +{
>> +	struct nand_chip *chip = mtd_to_nand(mtd);
>> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
>> +
>> +	iowrite8_rep(oxnas->io_base + oxnas->ctrl, buf, len);
>> +}
>> +
>> +/* Single CS command control */
>> +static void oxnas_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
>> +				unsigned int ctrl)
>> +{
>> +	struct nand_chip *chip = mtd_to_nand(mtd);
>> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
>> +
>> +	if (ctrl & NAND_CTRL_CHANGE) {
>> +		if (ctrl & NAND_CLE)
>> +			oxnas->ctrl = OXNAS_NAND_CMD_CLE;
>> +		else if (ctrl & NAND_ALE)
>> +			oxnas->ctrl = OXNAS_NAND_CMD_ALE;
>> +		else
>> +			oxnas->ctrl = 0;
>> +	}
>> +
>> +	if (cmd != NAND_CMD_NONE)
>> +		writeb(cmd, oxnas->io_base + oxnas->ctrl);
> 
> There's no need to test the NAND_CTRL_CHANGE here, and I don't think
> the CLE or ALE flag is ever set when cmd == CMD_NONE. So, you can kill
> the ->ctrl field and simply do:
> 
> 	if (ctrl & NAND_CLE)
> 		writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_CLE);
> 	else if (ctrl & NAND_ALE)
> 		writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_ALE);
> 
>> +}

Hmm, except it's needed back in the oxnas_nand_write_buf() call (don't ask me why)
so I don't see how to simplify more this function.

^ permalink raw reply

* Build failure with v4.9-rc1 and GCC trunk -- compiler weirdness
From: Arnd Bergmann @ 2016-10-19 15:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKv+Gu_100mM7EvaxAMoZvnr1Ce_EC=wzYkB80AjUmBx9exkGQ@mail.gmail.com>

On Wednesday, October 19, 2016 4:27:51 PM CEST Ard Biesheuvel wrote:
> >
> > Why not turn it into a runtime warning in this driver?
> >
> > diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
> > index cecb0fdfaef6..711d1d9842cc 100644
> > --- a/drivers/clk/mvebu/armada-37xx-periph.c
> > +++ b/drivers/clk/mvebu/armada-37xx-periph.c
> > @@ -349,8 +349,10 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
> >                         rate->reg = reg + (u64)rate->reg;
> >                         for (clkt = rate->table; clkt->div; clkt++)
> >                                 table_size++;
> > -                       rate->width = order_base_2(table_size);
> > -                       rate->lock = lock;
> > +                       if (!WARN_ON(table_size == 0)) {
> > +                               rate->width = order_base_2(table_size);
> > +                               rate->lock = lock;
> > +                       }
> >                 }
> >         }
> >
> 
> I guess Will is not looking for a way to fix the driver, but for a way
> to eliminate this issue entirely going forward.
>
> In general, I think the issue where constant folding results in
> ilog2() or other similar functions being called with invalid build
> time constant parameter values is simply something we have to deal
> with.
> 
> In this case, it is in fact order_base_2() that deviates from its
> documented behavior (as Will points out), and fixing /that/ should
> make this particular issue go away afaict.

Ah, right. I also noticed that order_base_2() is defined as
log2(1 << (log2(n-1)+1)), which seems a bit redundant.
Maybe we can simplify it to something like

#define order_base_2(n) ((n) <= 1) ? 0 : log2((n) - 1) + 1)

	Arnd

^ permalink raw reply

* Build failure with v4.9-rc1 and GCC trunk -- compiler weirdness
From: Markus Trippelsdorf @ 2016-10-19 15:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161017183806.GG5601@arm.com>

On 2016.10.17 at 19:38 +0100, Will Deacon wrote:
> Hi all,
> 
> I'm seeing an arm64 build failure with -rc1 and GCC trunk, although I
> believe that the new compiler behaviour at the heart of the problem
> has the potential to affect other architectures and other pieces of
> kernel code relying on dead-code elimination to remove deliberately
> undefined functions.
> 
> The failure looks like:
> 
>   | drivers/built-in.o: In function `armada_3700_add_composite_clk':
>   |
>   | linux/drivers/clk/mvebu/armada-37xx-periph.c:351:
>   | undefined reference to `____ilog2_NaN'
>   |
>   | linux/drivers/clk/mvebu/armada-37xx-periph.c:351:(.text+0xc72e0):
>   | relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol
>   | `____ilog2_NaN'
>   |
>   | make: *** [vmlinux] Error 1
> 

This is a gcc bug, see:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72785

-- 
Markus

^ permalink raw reply

* [RESEND PATCH v2 4/9] pinctrl: meson: allow gpio to request irq
From: Jerome Brunet @ 2016-10-19 15:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476890480-8884-5-git-send-email-jbrunet@baylibre.com>

Add the ability for gpio to request irq from the gpio interrupt controller
if present. We have to specificaly that the parent interrupt controller is
the gpio interrupt controller because gpio on meson SoCs can't generate
interrupt directly on the GIC.

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---

I messed up in v2 and actually sent the v1 again. Here is the actual v2
with the fix. Again, sorry for the inconvenience.

 drivers/pinctrl/Kconfig               |  2 +
 drivers/pinctrl/meson/pinctrl-meson.c | 69 +++++++++++++++++++++++++++++++++++
 drivers/pinctrl/meson/pinctrl-meson.h |  1 +
 3 files changed, 72 insertions(+)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 0e75d94972ba..d5bfbfcddab0 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -126,7 +126,9 @@ config PINCTRL_MESON
 	select PINCONF
 	select GENERIC_PINCONF
 	select GPIOLIB
+	select IRQ_DOMAIN
 	select OF_GPIO
+	select OF_IRQ
 	select REGMAP_MMIO
 
 config PINCTRL_OXNAS
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 57122eda155a..e3f5241f337f 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -50,6 +50,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinctrl.h>
@@ -481,6 +482,58 @@ static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
 			   value ? BIT(bit) : 0);
 }
 
+static int meson_gpio_to_hwirq(struct meson_bank *bank, unsigned int offset)
+{
+	unsigned int hwirq;
+
+	if (bank->irq_first < 0)
+		/* this bank cannot generate irqs */
+		return -1;
+
+	hwirq = offset - bank->first + bank->irq_first;
+
+	if (hwirq > bank->irq_last)
+		/* this pin cannot generate irqs */
+		return -1;
+
+	return hwirq;
+}
+
+static int meson_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+	struct meson_pinctrl *pc = gpiochip_get_data(chip);
+	struct meson_bank *bank;
+	struct irq_fwspec fwspec;
+	unsigned int hwirq;
+	int ret;
+
+	ret = meson_get_bank(pc, offset, &bank);
+	if (ret)
+		return ret;
+
+	/*
+	 * The interrupt controller might be missing, in such case we can't
+	 * provide an interrupt for a pin
+	 */
+	if (is_fwnode_irqchip(pc->fwnode)) {
+		dev_info(pc->dev, "interrupt controller not found\n");
+		return 0;
+	}
+
+	hwirq = meson_gpio_to_hwirq(bank, offset);
+	if (hwirq < 0) {
+		dev_dbg(pc->dev, "no interrupt for pin %u\n", offset);
+		return 0;
+	}
+
+	fwspec.fwnode = pc->fwnode;
+	fwspec.param_count = 2;
+	fwspec.param[0] = hwirq;
+	fwspec.param[1] = IRQ_TYPE_NONE;
+
+	return irq_create_fwspec_mapping(&fwspec);
+}
+
 static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
 {
 	struct meson_pinctrl *pc = gpiochip_get_data(chip);
@@ -539,6 +592,7 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc)
 	pc->chip.direction_output = meson_gpio_direction_output;
 	pc->chip.get = meson_gpio_get;
 	pc->chip.set = meson_gpio_set;
+	pc->chip.to_irq = meson_gpio_to_irq;
 	pc->chip.base = pc->data->pin_base;
 	pc->chip.ngpio = pc->data->num_pins;
 	pc->chip.can_sleep = false;
@@ -598,6 +652,19 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
 	return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config);
 }
 
+static void meson_pinctrl_get_irq_gpio_intc(struct meson_pinctrl *pc,
+					    struct device_node *node)
+{
+	struct device_node *np = of_irq_find_parent(node);
+
+	if (!np || !of_device_is_compatible(np, pc->data->irq_compat)) {
+		dev_info(pc->dev, "gpio interrupt disabled\n");
+		pc->fwnode = NULL;
+	} else {
+		pc->fwnode = of_node_to_fwnode(np);
+	}
+}
+
 static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
 				  struct device_node *node)
 {
@@ -643,6 +710,8 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
 		return PTR_ERR(pc->reg_gpio);
 	}
 
+	meson_pinctrl_get_irq_gpio_intc(pc, gpio_np);
+
 	return 0;
 }
 
diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h
index b90d69e366df..2e6c83adbd1f 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.h
+++ b/drivers/pinctrl/meson/pinctrl-meson.h
@@ -123,6 +123,7 @@ struct meson_pinctrl {
 	struct regmap *reg_gpio;
 	struct gpio_chip chip;
 	struct device_node *of_node;
+	struct fwnode_handle *fwnode;
 };
 
 #define PIN(x, b)	(b + x)
-- 
2.7.4

^ permalink raw reply related

* [PATCH] mtd: nand: Add OX820 NAND Support
From: Boris Brezillon @ 2016-10-19 15:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019145523.6763-1-narmstrong@baylibre.com>

On Wed, 19 Oct 2016 16:55:23 +0200
Neil Armstrong <narmstrong@baylibre.com> wrote:

> Add NAND driver to support the Oxford Semiconductor OX820 NAND Controller.
> This is a simple memory mapped NAND controller with single chip select and
> software ECC.
> 
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>

It looks pretty good already (I like those dummy controllers :-)). Just
a few comments below.

> ---
>  .../devicetree/bindings/mtd/oxnas-nand.txt         |  24 +++
>  drivers/mtd/nand/Kconfig                           |   5 +
>  drivers/mtd/nand/Makefile                          |   1 +
>  drivers/mtd/nand/oxnas_nand.c                      | 204 +++++++++++++++++++++
>  4 files changed, 234 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mtd/oxnas-nand.txt
>  create mode 100644 drivers/mtd/nand/oxnas_nand.c
> 
> Changes since RFC http://lkml.kernel.org/r/20161018090927.1990-1-narmstrong at baylibre.com :
>  - Avoid using chip->IO_ADDR*
>  - Use new DT structure
>  - Assign a chip for the subnode
>  - Use the nand_hw_control structure
>  - Cleanup probe
>  - Cleanup cmd_ctrl by using a context ctrl offset used in write_bytes
> 
> diff --git a/Documentation/devicetree/bindings/mtd/oxnas-nand.txt b/Documentation/devicetree/bindings/mtd/oxnas-nand.txt
> new file mode 100644
> index 0000000..83b684d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/oxnas-nand.txt
> @@ -0,0 +1,24 @@
> +* Oxford Semiconductor OXNAS NAND Controller
> +
> +Please refer to nand.txt for generic information regarding MTD NAND bindings.
> +
> +Required properties:
> + - compatible: "oxsemi,ox820-nand"
> + - reg: Base address and length for NAND mapped memory.
> +
> +Optional Properties:
> + - clocks: phandle to the NAND gate clock if needed.
> + - resets: phandle to the NAND reset control if needed.
> +
> +Example:
> +
> +nand: nand at 41000000 {

nandc: nand-controller at 41000000 {

> +	compatible = "oxsemi,ox820-nand";
> +	reg = <0x41000000 0x100000>;
> +	nand-ecc-mode = "soft";
> +	clocks = <&stdclk CLK_820_NAND>;
> +	resets = <&reset RESET_NAND>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	status = "disabled";
> +};

You should probably provide an example where the NAND controller is
enabled and at least one nand chip is connected to the NAND bus.

> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index 7b7a887..c023125 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -426,6 +426,11 @@ config MTD_NAND_ORION
>  	  No board specific support is done by this driver, each board
>  	  must advertise a platform_device for the driver to attach.
>  
> +config MTD_NAND_OXNAS
> +	tristate "NAND Flash support for Oxford Semiconductor SoC"
> +	help
> +	  This enables the NAND flash controller on Oxford Semiconductor SoCs.
> +
>  config MTD_NAND_FSL_ELBC
>  	tristate "NAND support for Freescale eLBC controllers"
>  	depends on FSL_SOC
> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> index cafde6f..05fc054 100644
> --- a/drivers/mtd/nand/Makefile
> +++ b/drivers/mtd/nand/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_MTD_NAND_TMIO)		+= tmio_nand.o
>  obj-$(CONFIG_MTD_NAND_PLATFORM)		+= plat_nand.o
>  obj-$(CONFIG_MTD_NAND_PASEMI)		+= pasemi_nand.o
>  obj-$(CONFIG_MTD_NAND_ORION)		+= orion_nand.o
> +obj-$(CONFIG_MTD_NAND_OXNAS)		+= oxnas_nand.o
>  obj-$(CONFIG_MTD_NAND_FSL_ELBC)		+= fsl_elbc_nand.o
>  obj-$(CONFIG_MTD_NAND_FSL_IFC)		+= fsl_ifc_nand.o
>  obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
> diff --git a/drivers/mtd/nand/oxnas_nand.c b/drivers/mtd/nand/oxnas_nand.c
> new file mode 100644
> index 0000000..a9fe1ac
> --- /dev/null
> +++ b/drivers/mtd/nand/oxnas_nand.c
> @@ -0,0 +1,204 @@
> +/*
> + * Oxford Semiconductor OXNAS NAND driver
> +
> + * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
> + * Heavily based on plat_nand.c :
> + * Author: Vitaly Wool <vitalywool@gmail.com>
> + * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
> + * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/nand.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/of.h>
> +
> +/* Nand commands */
> +#define OXNAS_NAND_CMD_ALE		BIT(18)
> +#define OXNAS_NAND_CMD_CLE		BIT(19)
> +
> +#define OXNAS_NAND_MAX_CHIPS	1
> +
> +struct oxnas_nand {
> +	struct nand_hw_control base;
> +	void __iomem *io_base;
> +	struct clk *clk;
> +	struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS];
> +	unsigned long ctrl;
> +};
> +
> +static uint8_t oxnas_nand_read_byte(struct mtd_info *mtd)
> +{
> +	struct nand_chip *chip = mtd_to_nand(mtd);
> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
> +
> +	return readb(oxnas->io_base);
> +}
> +
> +static void oxnas_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
> +{
> +	struct nand_chip *chip = mtd_to_nand(mtd);
> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
> +
> +	ioread8_rep(oxnas->io_base, buf, len);
> +}
> +
> +static void oxnas_nand_write_buf(struct mtd_info *mtd,
> +				 const uint8_t *buf, int len)
> +{
> +	struct nand_chip *chip = mtd_to_nand(mtd);
> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
> +
> +	iowrite8_rep(oxnas->io_base + oxnas->ctrl, buf, len);
> +}
> +
> +/* Single CS command control */
> +static void oxnas_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
> +				unsigned int ctrl)
> +{
> +	struct nand_chip *chip = mtd_to_nand(mtd);
> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
> +
> +	if (ctrl & NAND_CTRL_CHANGE) {
> +		if (ctrl & NAND_CLE)
> +			oxnas->ctrl = OXNAS_NAND_CMD_CLE;
> +		else if (ctrl & NAND_ALE)
> +			oxnas->ctrl = OXNAS_NAND_CMD_ALE;
> +		else
> +			oxnas->ctrl = 0;
> +	}
> +
> +	if (cmd != NAND_CMD_NONE)
> +		writeb(cmd, oxnas->io_base + oxnas->ctrl);

There's no need to test the NAND_CTRL_CHANGE here, and I don't think
the CLE or ALE flag is ever set when cmd == CMD_NONE. So, you can kill
the ->ctrl field and simply do:

	if (ctrl & NAND_CLE)
		writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_CLE);
	else if (ctrl & NAND_ALE)
		writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_ALE);

> +}

^ permalink raw reply

* [PATCH V5 00/10] dmaengine: qcom_hidma: add MSI interrupt support
From: Sinan Kaya @ 2016-10-19 15:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019133406.GO2467@localhost>

On 10/19/2016 6:34 AM, Vinod Koul wrote:
> On Fri, Oct 07, 2016 at 01:25:05AM -0400, Sinan Kaya wrote:
>> The new version of the HW supports MSI interrupts instead of wired
>> interrupts. The MSI interrupts are especially useful for the guest machine
>> execution. The wired interrupts usually trap to the hypervisor and then are
>> relayed to the actual interrupt.
>>
>> The MSI interrupts can be directly fed into the interrupt controller.
>>
>> Adding a new OF compat string (qcom,hidma-1.1) and ACPI string (QCOM8062)
>> to distinguish newer HW from the older ones.
> 
> I was only able to apply 6 patches in this series. Which tree were these
> generated against?
> 
> Please rebase rest..
> 

Sure, let me do that. The other two patches (sysfs and debugfs) probably broke
the git merge.

-- 
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* Build failure with v4.9-rc1 and GCC trunk -- compiler weirdness
From: Gregory CLEMENT @ 2016-10-19 15:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4333753.kxspqi1Miz@wuerfel>

Hi Arnd,
 
 On mer., oct. 19 2016, Arnd Bergmann <arnd@arndb.de> wrote:

> On Wednesday, October 19, 2016 4:01:58 PM CEST Ard Biesheuvel wrote:
>> On 19 October 2016 at 15:59, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>> > On 19 October 2016 at 14:35, Will Deacon <will.deacon@arm.com> wrote:
>> >> On Mon, Oct 17, 2016 at 08:43:19PM +0100, Ard Biesheuvel wrote:
>> >>> On 17 October 2016 at 19:38, Will Deacon <will.deacon@arm.com> wrote:
>> >
>> > Yes, and that would be perfectly legal from a correctness point of
>> > view, and would likely help performance as well. By using
>> > __builtin_constant_p(), you are choosing to perform a build time
>> > evaluation of an expression that would ordinarily be evaluated only at
>> > runtime. This implies that you have to address undefined behavior at
>> > build time rather than at runtime as well.
>> >
>> >>> If order_base_2() is not defined for input 0, it should BUG() in that
>> >>> case, and the associated __builtin_unreachable() should prevent the
>> >>> special version from being emitted. If order_base_2() is defined for input
>> >>> 0, it should not invoke ilog2() with that argument, and the problem should
>> >>> go away as well.
>> >>
>> >> I don't necessarily think it should BUG() if it's not defined for input
>> >> 0; things like __ffs don't do that and we'd be introducing conditional
>> >> checks for cases that should not happen. The comment above order_base_2
>> >> does suggest that ob2(0) should return 0, but it can actually end up
>> >> invoking ilog2(-1), which is obviously wrong.
>> >>
>> >> I could update the comment, but that doesn't fix the build issue.
>> >>
>> >
>> > Fixing roundup_pow_of_two() [which is arguably incorrect]
>> 
>> I just spotted the comment that says it is undefined. But that means
>> it could legally return 1 for input 0, i suppose
>
> I think having the link error in roundup_pow_of_two() is safer than
> returning 1.
>
> Why not turn it into a runtime warning in this driver?
>
> diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
> index cecb0fdfaef6..711d1d9842cc 100644
> --- a/drivers/clk/mvebu/armada-37xx-periph.c
> +++ b/drivers/clk/mvebu/armada-37xx-periph.c
> @@ -349,8 +349,10 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
>  			rate->reg = reg + (u64)rate->reg;
>  			for (clkt = rate->table; clkt->div; clkt++)
>  				table_size++;
> -			rate->width = order_base_2(table_size);
> -			rate->lock = lock;
> +			if (!WARN_ON(table_size == 0)) {
> +				rate->width = order_base_2(table_size);
> +				rate->lock = lock;
> +			}

With the way the data are constructed in the driver I don't see how the
table_size can be 0.

However I understand it is more something for the compiler.

In this case it is better to nullify the rate_hw as having width=0 will
lead to trouble in the clk_divider operations


If it is the needed solution for this build error I can submit this kind
of patch:
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index 45905fc0d75b..dbc49359406d 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -345,11 +345,16 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
                        const struct clk_div_table *clkt;
                        int table_size = 0;
 
-                       rate->reg = reg + (u64)rate->reg;
                        for (clkt = rate->table; clkt->div; clkt++)
                                table_size++;
-                       rate->width = order_base_2(table_size);
-                       rate->lock = lock;
+                       if (!WARN_ON(table_size == 0)) {
+                               rate->reg = reg + (u64)rate->reg;
+                               rate->width = order_base_2(table_size);
+                               rate->lock = lock;
+                       } else {
+                               rate_hw = NULL;
+                               rate_ops = NULL;
+                       }
                }
        }


Gregory

>  		}
>  	}
>  
>
> 	
> 	Arnd
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply related

* [PATCH 2/3] ARM: convert to generated system call tables
From: Arnd Bergmann @ 2016-10-19 15:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <E1bwa6s-0004ZY-4k@rmk-PC.armlinux.org.uk>

On Tuesday, October 18, 2016 8:31:38 PM CEST Russell King wrote:
> Convert ARM to use a similar mechanism to x86 to generate the unistd.h
> system call numbers and the various kernel system call tables.  This
> means that rather than having to edit three places (asm/unistd.h for
> the total number of system calls, uapi/asm/unistd.h for the system call
> numbers, and arch/arm/kernel/calls.S for the call table) we have only
> one place to edit, making the process much more simple.
> 
> The scripts have knowledge of the table padding requirements, so there's
> no need to worry about __NR_syscalls not fitting within the immediate
> constant field of ALU instructions anymore.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Ah, very nice!

I have some vague plans to do something like this for all architectures,
so having it done for one of the more complex examples (there are very
few architectures with more than one table) simplifies it a lot.

The next step is probably to do it for asm-generic/unistd.h, which
covers a lot of architectures, and then we can introduce a shared
table for all future additions so we only have to add the new calls
in one place, and change the scripts so they can merge two input
files into one.

> diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
> new file mode 100644
> index 000000000000..62285cbd09c0
> --- /dev/null
> +++ b/arch/arm/tools/syscall.tbl
> @@ -0,0 +1,428 @@
> +#
> +# Linux system call numbers and entry vectors
> +#
> +# The format is:
> +# <num>	<abi>	<name>			<entry point>			<oabi compat entry point>
> +#
> +# Where abi is:
> +#  common - for system calls shared between oabi and eabi
> +#  oabi   - for oabi-only system calls (may have compat)
> +#  eabi   - for eabi-only system calls

Why do we need all three? I would have guessed that these two are
sufficient to cover all cases:

arm	- one entry for eabi, optional second entry for oabi if different
oabi	- only one entry for oabi, syscall is not used on eabi

> +180	oabi	pread64			sys_pread64		sys_oabi_pread64
> +180	eabi	pread64			sys_pread64
> +181	oabi	pwrite64		sys_pwrite64		sys_oabi_pwrite64
> +181	eabi	pwrite64		sys_pwrite64

That would avoid having to list those numbers twice, which looks
a bit odd here, and is inconsistent with how x86 handles their
compat table for x32

> diff --git a/arch/arm/tools/syscallhdr.sh b/arch/arm/tools/syscallhdr.sh
> new file mode 100644
> index 000000000000..72d4b2e3bdec
> --- /dev/null
> +++ b/arch/arm/tools/syscallhdr.sh

The scripts are still very similar to the x86 version. Any chance
we can move them to a top-level scripts/syscall/ directory and make
them work for both architectures? It would be good to avoid duplicating
them for all the other architectures too, so starting out with a common
version could make that easier.

If necessary, I can do that once I get to the following stage of
doing the asm-generic/unistd.h replacement.

	Arnd

^ permalink raw reply

* [PATCH] mtd: nand: Add OX820 NAND Support
From: Neil Armstrong @ 2016-10-19 15:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019145523.6763-1-narmstrong@baylibre.com>

On 10/19/2016 04:55 PM, Neil Armstrong wrote:
> Add NAND driver to support the Oxford Semiconductor OX820 NAND Controller.
> This is a simple memory mapped NAND controller with single chip select and
> software ECC.
> 
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>

Forgot
Acked-by: Rob Herring <robh@kernel.org>

Will add in v2 if a respin is needed.

> ---
>  .../devicetree/bindings/mtd/oxnas-nand.txt         |  24 +++
>  drivers/mtd/nand/Kconfig                           |   5 +
>  drivers/mtd/nand/Makefile                          |   1 +
>  drivers/mtd/nand/oxnas_nand.c                      | 204 +++++++++++++++++++++
>  4 files changed, 234 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mtd/oxnas-nand.txt
>  create mode 100644 drivers/mtd/nand/oxnas_nand.c
> 
> Changes since RFC http://lkml.kernel.org/r/20161018090927.1990-1-narmstrong at baylibre.com :
>  - Avoid using chip->IO_ADDR*
>  - Use new DT structure
>  - Assign a chip for the subnode
>  - Use the nand_hw_control structure
>  - Cleanup probe
>  - Cleanup cmd_ctrl by using a context ctrl offset used in write_bytes
> 
> diff --git a/Documentation/devicetree/bindings/mtd/oxnas-nand.txt b/Documentation/devicetree/bindings/mtd/oxnas-nand.txt
> new file mode 100644
> index 0000000..83b684d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/oxnas-nand.txt
> @@ -0,0 +1,24 @@
> +* Oxford Semiconductor OXNAS NAND Controller
> +
> +Please refer to nand.txt for generic information regarding MTD NAND bindings.
> +
> +Required properties:
> + - compatible: "oxsemi,ox820-nand"
> + - reg: Base address and length for NAND mapped memory.
> +
> +Optional Properties:
> + - clocks: phandle to the NAND gate clock if needed.
> + - resets: phandle to the NAND reset control if needed.
> +
> +Example:
> +
> +nand: nand at 41000000 {
> +	compatible = "oxsemi,ox820-nand";
> +	reg = <0x41000000 0x100000>;
> +	nand-ecc-mode = "soft";
> +	clocks = <&stdclk CLK_820_NAND>;
> +	resets = <&reset RESET_NAND>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	status = "disabled";
> +};
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index 7b7a887..c023125 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -426,6 +426,11 @@ config MTD_NAND_ORION
>  	  No board specific support is done by this driver, each board
>  	  must advertise a platform_device for the driver to attach.
>  
> +config MTD_NAND_OXNAS
> +	tristate "NAND Flash support for Oxford Semiconductor SoC"
> +	help
> +	  This enables the NAND flash controller on Oxford Semiconductor SoCs.
> +
>  config MTD_NAND_FSL_ELBC
>  	tristate "NAND support for Freescale eLBC controllers"
>  	depends on FSL_SOC
> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> index cafde6f..05fc054 100644
> --- a/drivers/mtd/nand/Makefile
> +++ b/drivers/mtd/nand/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_MTD_NAND_TMIO)		+= tmio_nand.o
>  obj-$(CONFIG_MTD_NAND_PLATFORM)		+= plat_nand.o
>  obj-$(CONFIG_MTD_NAND_PASEMI)		+= pasemi_nand.o
>  obj-$(CONFIG_MTD_NAND_ORION)		+= orion_nand.o
> +obj-$(CONFIG_MTD_NAND_OXNAS)		+= oxnas_nand.o
>  obj-$(CONFIG_MTD_NAND_FSL_ELBC)		+= fsl_elbc_nand.o
>  obj-$(CONFIG_MTD_NAND_FSL_IFC)		+= fsl_ifc_nand.o
>  obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
> diff --git a/drivers/mtd/nand/oxnas_nand.c b/drivers/mtd/nand/oxnas_nand.c
> new file mode 100644
> index 0000000..a9fe1ac
> --- /dev/null
> +++ b/drivers/mtd/nand/oxnas_nand.c
> @@ -0,0 +1,204 @@
> +/*
> + * Oxford Semiconductor OXNAS NAND driver
> +
> + * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
> + * Heavily based on plat_nand.c :
> + * Author: Vitaly Wool <vitalywool@gmail.com>
> + * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
> + * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/nand.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/of.h>
> +
> +/* Nand commands */
> +#define OXNAS_NAND_CMD_ALE		BIT(18)
> +#define OXNAS_NAND_CMD_CLE		BIT(19)
> +
> +#define OXNAS_NAND_MAX_CHIPS	1
> +
> +struct oxnas_nand {
> +	struct nand_hw_control base;
> +	void __iomem *io_base;
> +	struct clk *clk;
> +	struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS];
> +	unsigned long ctrl;
> +};
> +
> +static uint8_t oxnas_nand_read_byte(struct mtd_info *mtd)
> +{
> +	struct nand_chip *chip = mtd_to_nand(mtd);
> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
> +
> +	return readb(oxnas->io_base);
> +}
> +
> +static void oxnas_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
> +{
> +	struct nand_chip *chip = mtd_to_nand(mtd);
> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
> +
> +	ioread8_rep(oxnas->io_base, buf, len);
> +}
> +
> +static void oxnas_nand_write_buf(struct mtd_info *mtd,
> +				 const uint8_t *buf, int len)
> +{
> +	struct nand_chip *chip = mtd_to_nand(mtd);
> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
> +
> +	iowrite8_rep(oxnas->io_base + oxnas->ctrl, buf, len);
> +}
> +
> +/* Single CS command control */
> +static void oxnas_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
> +				unsigned int ctrl)
> +{
> +	struct nand_chip *chip = mtd_to_nand(mtd);
> +	struct oxnas_nand *oxnas = nand_get_controller_data(chip);
> +
> +	if (ctrl & NAND_CTRL_CHANGE) {
> +		if (ctrl & NAND_CLE)
> +			oxnas->ctrl = OXNAS_NAND_CMD_CLE;
> +		else if (ctrl & NAND_ALE)
> +			oxnas->ctrl = OXNAS_NAND_CMD_ALE;
> +		else
> +			oxnas->ctrl = 0;
> +	}
> +
> +	if (cmd != NAND_CMD_NONE)
> +		writeb(cmd, oxnas->io_base + oxnas->ctrl);
> +}
> +
> +/*
> + * Probe for the NAND device.
> + */
> +static int oxnas_nand_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct device_node *nand_np;
> +	struct oxnas_nand *oxnas;
> +	struct nand_chip *chip;
> +	struct mtd_info *mtd;
> +	struct resource *res;
> +	int nchips = 0;
> +	int count = 0;
> +	int err = 0;
> +
> +	/* Allocate memory for the device structure (and zero it) */
> +	oxnas = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
> +			    GFP_KERNEL);
> +	if (!oxnas)
> +		return -ENOMEM;
> +
> +	nand_hw_control_init(&oxnas->base);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	oxnas->io_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(oxnas->io_base))
> +		return PTR_ERR(oxnas->io_base);
> +
> +	oxnas->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(oxnas->clk))
> +		oxnas->clk = NULL;
> +
> +	/* Only a single chip node is supported */
> +	count = of_get_child_count(np);
> +	if (count > 1)
> +		return -EINVAL;
> +
> +	clk_prepare_enable(oxnas->clk);
> +	device_reset_optional(&pdev->dev);
> +
> +	for_each_child_of_node(np, nand_np) {
> +		chip = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
> +				    GFP_KERNEL);
> +		if (!chip)
> +			return -ENOMEM;
> +
> +		chip->controller = &oxnas->base;
> +
> +		nand_set_flash_node(chip, nand_np);
> +		nand_set_controller_data(chip, oxnas);
> +
> +		mtd = nand_to_mtd(chip);
> +		mtd->dev.parent = &pdev->dev;
> +		mtd->priv = chip;
> +
> +		chip->cmd_ctrl = oxnas_nand_cmd_ctrl;
> +		chip->read_buf = oxnas_nand_read_buf;
> +		chip->read_byte = oxnas_nand_read_byte;
> +		chip->write_buf = oxnas_nand_write_buf;
> +		chip->chip_delay = 30;
> +
> +		/* Scan to find existence of the device */
> +		err = nand_scan(mtd, 1);
> +		if (err)
> +			return err;
> +
> +		err = mtd_device_register(mtd, NULL, 0);
> +		if (err) {
> +			nand_release(mtd);
> +			return err;
> +		}
> +
> +		oxnas->chips[nchips] = chip;
> +		++nchips;
> +	}
> +
> +	/* Exit if no chips found */
> +	if (!nchips)
> +		return -ENODEV;
> +
> +	platform_set_drvdata(pdev, oxnas);
> +
> +	return 0;
> +}
> +
> +static int oxnas_nand_remove(struct platform_device *pdev)
> +{
> +	struct oxnas_nand *oxnas = platform_get_drvdata(pdev);
> +
> +	if (oxnas->chips[0])
> +		nand_release(nand_to_mtd(oxnas->chips[0]));
> +
> +	clk_disable_unprepare(oxnas->clk);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id oxnas_nand_match[] = {
> +	{ .compatible = "oxsemi,ox820-nand" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, oxnas_nand_match);
> +
> +static struct platform_driver oxnas_nand_driver = {
> +	.probe	= oxnas_nand_probe,
> +	.remove	= oxnas_nand_remove,
> +	.driver	= {
> +		.name		= "oxnas_nand",
> +		.of_match_table = oxnas_nand_match,
> +	},
> +};
> +
> +module_platform_driver(oxnas_nand_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
> +MODULE_DESCRIPTION("Oxnas NAND driver");
> +MODULE_ALIAS("platform:oxnas_nand");
> 

^ permalink raw reply

* Build failure with v4.9-rc1 and GCC trunk -- compiler weirdness
From: Ard Biesheuvel @ 2016-10-19 15:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4333753.kxspqi1Miz@wuerfel>

On 19 October 2016 at 16:11, Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday, October 19, 2016 4:01:58 PM CEST Ard Biesheuvel wrote:
>> On 19 October 2016 at 15:59, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>> > On 19 October 2016 at 14:35, Will Deacon <will.deacon@arm.com> wrote:
>> >> On Mon, Oct 17, 2016 at 08:43:19PM +0100, Ard Biesheuvel wrote:
>> >>> On 17 October 2016 at 19:38, Will Deacon <will.deacon@arm.com> wrote:
>> >
>> > Yes, and that would be perfectly legal from a correctness point of
>> > view, and would likely help performance as well. By using
>> > __builtin_constant_p(), you are choosing to perform a build time
>> > evaluation of an expression that would ordinarily be evaluated only at
>> > runtime. This implies that you have to address undefined behavior at
>> > build time rather than at runtime as well.
>> >
>> >>> If order_base_2() is not defined for input 0, it should BUG() in that
>> >>> case, and the associated __builtin_unreachable() should prevent the
>> >>> special version from being emitted. If order_base_2() is defined for input
>> >>> 0, it should not invoke ilog2() with that argument, and the problem should
>> >>> go away as well.
>> >>
>> >> I don't necessarily think it should BUG() if it's not defined for input
>> >> 0; things like __ffs don't do that and we'd be introducing conditional
>> >> checks for cases that should not happen. The comment above order_base_2
>> >> does suggest that ob2(0) should return 0, but it can actually end up
>> >> invoking ilog2(-1), which is obviously wrong.
>> >>
>> >> I could update the comment, but that doesn't fix the build issue.
>> >>
>> >
>> > Fixing roundup_pow_of_two() [which is arguably incorrect]
>>
>> I just spotted the comment that says it is undefined. But that means
>> it could legally return 1 for input 0, i suppose
>
> I think having the link error in roundup_pow_of_two() is safer than
> returning 1.
>
> Why not turn it into a runtime warning in this driver?
>
> diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
> index cecb0fdfaef6..711d1d9842cc 100644
> --- a/drivers/clk/mvebu/armada-37xx-periph.c
> +++ b/drivers/clk/mvebu/armada-37xx-periph.c
> @@ -349,8 +349,10 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
>                         rate->reg = reg + (u64)rate->reg;
>                         for (clkt = rate->table; clkt->div; clkt++)
>                                 table_size++;
> -                       rate->width = order_base_2(table_size);
> -                       rate->lock = lock;
> +                       if (!WARN_ON(table_size == 0)) {
> +                               rate->width = order_base_2(table_size);
> +                               rate->lock = lock;
> +                       }
>                 }
>         }
>

I guess Will is not looking for a way to fix the driver, but for a way
to eliminate this issue entirely going forward.

In general, I think the issue where constant folding results in
ilog2() or other similar functions being called with invalid build
time constant parameter values is simply something we have to deal
with.

In this case, it is in fact order_base_2() that deviates from its
documented behavior (as Will points out), and fixing /that/ should
make this particular issue go away afaict.

^ permalink raw reply

* [PATCH v2 9/9] ARM: dts: amlogic: enable gpio interrupt controller on meson8
From: Jerome Brunet @ 2016-10-19 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476890480-8884-1-git-send-email-jbrunet@baylibre.com>

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 arch/arm/boot/dts/meson8.dtsi  | 11 +++++++++++
 arch/arm/boot/dts/meson8b.dtsi | 11 +++++++++++
 2 files changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi
index 45619f6162c5..713a22456ff1 100644
--- a/arch/arm/boot/dts/meson8.dtsi
+++ b/arch/arm/boot/dts/meson8.dtsi
@@ -43,6 +43,8 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/gpio/meson8-gpio.h>
 /include/ "meson.dtsi"
 
@@ -91,6 +93,13 @@
 		clock-frequency = <141666666>;
 	};
 
+	gpio_interrupt: interrupt-controller at c1109880 {
+		compatible = "amlogic,meson8-gpio-intc";
+		reg = <0xc1109880 0x10>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
 	pinctrl_cbus: pinctrl at c1109880 {
 		compatible = "amlogic,meson8-cbus-pinctrl";
 		reg = <0xc1109880 0x10>;
@@ -106,6 +115,7 @@
 			reg-names = "mux", "pull", "pull-enable", "gpio";
 			gpio-controller;
 			#gpio-cells = <2>;
+			interrupt-parent = <&gpio_interrupt>;
 		};
 
 		spi_nor_pins: nor {
@@ -148,6 +158,7 @@
 			reg-names = "mux", "pull", "gpio";
 			gpio-controller;
 			#gpio-cells = <2>;
+			interrupt-parent = <&gpio_interrupt>;
 		};
 
 		uart_ao_a_pins: uart_ao_a {
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi
index 41fd53671859..36a239a645f5 100644
--- a/arch/arm/boot/dts/meson8b.dtsi
+++ b/arch/arm/boot/dts/meson8b.dtsi
@@ -44,6 +44,8 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/meson8b-clkc.h>
 #include <dt-bindings/gpio/meson8b-gpio.h>
 #include <dt-bindings/reset/amlogic,meson8b-reset.h>
@@ -183,6 +185,13 @@
 			status = "disabled";
 		};
 
+		gpio_interrupt: interrupt-controller at c1109880 {
+			compatible = "amlogic,meson8b-gpio-intc";
+			reg = <0xc1109880 0x10>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
 		pinctrl_cbus: pinctrl at c1109880 {
 			compatible = "amlogic,meson8b-cbus-pinctrl";
 			reg = <0xc1109880 0x10>;
@@ -198,6 +207,7 @@
 				reg-names = "mux", "pull", "pull-enable", "gpio";
 				gpio-controller;
 				#gpio-cells = <2>;
+				interrupt-parent = <&gpio_interrupt>;
 			};
 		};
 
@@ -215,6 +225,7 @@
 				reg-names = "mux", "pull", "gpio";
 				gpio-controller;
 				#gpio-cells = <2>;
+				interrupt-parent = <&gpio_interrupt>;
 			};
 
 			uart_ao_a_pins: uart_ao_a {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 8/9] ARM64: dts: amlogic: enable gpio interrupt controller on gxbb
From: Jerome Brunet @ 2016-10-19 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476890480-8884-1-git-send-email-jbrunet@baylibre.com>

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index aad639ab0112..5208cb80b55e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -141,6 +141,13 @@
 		#reset-cells = <1>;
 	};
 
+	gpio_interrupt: interrupt-controller at 9880 {
+		compatible = "amlogic,meson-gxbb-gpio-intc";
+		reg = <0x0 0x9880 0x0 0x10>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
 	uart_B: serial at 84dc {
 		compatible = "amlogic,meson-uart";
 		reg = <0x0 0x84dc 0x0 0x14>;
@@ -238,6 +245,7 @@
 			reg-names = "mux", "pull", "gpio";
 			gpio-controller;
 			#gpio-cells = <2>;
+			interrupt-parent = <&gpio_interrupt>;
 		};
 
 		uart_ao_a_pins: uart_ao_a {
@@ -343,6 +351,7 @@
 			reg-names = "mux", "pull", "pull-enable", "gpio";
 			gpio-controller;
 			#gpio-cells = <2>;
+			interrupt-parent = <&gpio_interrupt>;
 		};
 
 		emmc_pins: emmc {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 7/9] ARM: meson: enable MESON_IRQ_GPIO in Kconfig for meson8
From: Jerome Brunet @ 2016-10-19 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476890480-8884-1-git-send-email-jbrunet@baylibre.com>

Add select MESON_IRQ_GPIO in Kconfig for Amlogic's meson8 and meson8b SoC

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 arch/arm/mach-meson/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index b6e3acc63e14..63157295cd9d 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -21,11 +21,13 @@ config MACH_MESON8
 	bool "Amlogic Meson8 SoCs support"
 	default ARCH_MESON
 	select MESON6_TIMER
+	select MESON_IRQ_GPIO
 
 config MACH_MESON8B
 	bool "Amlogic Meson8b SoCs support"
 	default ARCH_MESON
 	select MESON6_TIMER
 	select COMMON_CLK_MESON8B
+	select MESON_IRQ_GPIO
 
 endif
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 6/9] ARM64: meson: enable MESON_IRQ_GPIO in Kconfig
From: Jerome Brunet @ 2016-10-19 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476890480-8884-1-git-send-email-jbrunet@baylibre.com>

Add select MESON_IRQ_GPIO in Kconfig for Amlogic's meson SoC family

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index cfbdf02ef566..846479d4492d 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -95,6 +95,7 @@ config ARCH_MESON
 	select PINCTRL_MESON
 	select COMMON_CLK_AMLOGIC
 	select COMMON_CLK_GXBB
+	select MESON_GPIO_IRQ
 	help
 	  This enables support for the Amlogic S905 SoCs.
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 5/9] dt-bindings: pinctrl: meson: update gpio dt-bindings
From: Jerome Brunet @ 2016-10-19 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476890480-8884-1-git-send-email-jbrunet@baylibre.com>

Add description for the interrupt-parent property of the gpio sub-node
If provided here, this property must be a phandle to an interrupt
controller suitable for meson pinctrl, like the meson gpio interrupt
controller.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
index fe7fe0b03cfb..39932c4dfb32 100644
--- a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
@@ -23,6 +23,10 @@ Required properties for sub-nodes are:
  - gpio-controller: identifies the node as a gpio controller
  - #gpio-cells: must be 2
 
+Optional property for sub-nodes is:
+ - interrupt-parent: must be a phandle to the meson gpio interrupt controller.
+   if this property is provided, enables gpio ability to generate interrupts
+
 === Other sub-nodes ===
 
 Child nodes without the "gpio-controller" represent some desired
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 4/9] pinctrl: meson: allow gpio to request irq
From: Jerome Brunet @ 2016-10-19 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476890480-8884-1-git-send-email-jbrunet@baylibre.com>

Add the ability for gpio to request irq from the gpio interrupt controller
if present. We have to specificaly that the parent interrupt controller is
the gpio interrupt controller because gpio on meson SoCs can't generate
interrupt directly on the GIC.

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 drivers/pinctrl/Kconfig               |  2 +
 drivers/pinctrl/meson/pinctrl-meson.c | 77 ++++++++++++++++++++++++++++++++++-
 drivers/pinctrl/meson/pinctrl-meson.h |  1 +
 3 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 0e75d94972ba..d5bfbfcddab0 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -126,7 +126,9 @@ config PINCTRL_MESON
 	select PINCONF
 	select GENERIC_PINCONF
 	select GPIOLIB
+	select IRQ_DOMAIN
 	select OF_GPIO
+	select OF_IRQ
 	select REGMAP_MMIO
 
 config PINCTRL_OXNAS
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 57122eda155a..fd3c1d44978b 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -50,6 +50,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinctrl.h>
@@ -481,6 +482,58 @@ static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
 			   value ? BIT(bit) : 0);
 }
 
+static int meson_gpio_to_hwirq(struct meson_bank *bank, unsigned int offset)
+{
+	unsigned int hwirq;
+
+	if (bank->irq_first < 0)
+		/* this bank cannot generate irqs */
+		return -1;
+
+	hwirq = offset - bank->first + bank->irq_first;
+
+	if (hwirq > bank->irq_last)
+		/* this pin cannot generate irqs */
+		return -1;
+
+	return hwirq;
+}
+
+static int meson_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+	struct meson_pinctrl *pc = gpiochip_get_data(chip);
+	struct meson_bank *bank;
+	struct irq_fwspec fwspec;
+	unsigned int hwirq;
+	int ret;
+
+	ret = meson_get_bank(pc, offset, &bank);
+	if (ret)
+		return ret;
+
+	/*
+	 * The interrupt controller might be missing, in such case we can't
+	 * provide an interrupt for a pin
+	 */
+	if (is_fwnode_irqchip(pc->fwnode)) {
+		dev_info(pc->dev, "interrupt controller not found\n");
+		return 0;
+	}
+
+	hwirq = meson_gpio_to_hwirq(bank, offset);
+	if (hwirq < 0) {
+		dev_dbg(pc->dev, "no interrupt for pin %u\n", offset);
+		return 0;
+	}
+
+	fwspec.fwnode = pc->fwnode;
+	fwspec.param_count = 2;
+	fwspec.param[0] = hwirq;
+	fwspec.param[1] = IRQ_TYPE_NONE;
+
+	return irq_create_fwspec_mapping(&fwspec);
+}
+
 static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
 {
 	struct meson_pinctrl *pc = gpiochip_get_data(chip);
@@ -539,6 +592,7 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc)
 	pc->chip.direction_output = meson_gpio_direction_output;
 	pc->chip.get = meson_gpio_get;
 	pc->chip.set = meson_gpio_set;
+	pc->chip.to_irq = meson_gpio_to_irq;
 	pc->chip.base = pc->data->pin_base;
 	pc->chip.ngpio = pc->data->num_pins;
 	pc->chip.can_sleep = false;
@@ -598,6 +652,27 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
 	return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config);
 }
 
+static int meson_pinctrl_get_irq_gpio_intc(struct meson_pinctrl *pc,
+					   struct device_node *node)
+{
+	struct device_node *np;
+
+	np = of_irq_find_parent(node);
+	if (unlikely(!np)) {
+		dev_err(pc->dev, "interrupt parent not found\n");
+		return -EINVAL;
+	}
+
+	if (!of_device_is_compatible(np, pc->data->irq_compat)) {
+		dev_info(pc->dev, "gpio interrupt disabled\n");
+		pc->fwnode = NULL;
+	}
+
+	pc->fwnode = of_node_to_fwnode(np);
+
+	return 0;
+}
+
 static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
 				  struct device_node *node)
 {
@@ -643,7 +718,7 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
 		return PTR_ERR(pc->reg_gpio);
 	}
 
-	return 0;
+	return meson_pinctrl_get_irq_gpio_intc(pc, gpio_np);
 }
 
 static int meson_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h
index b90d69e366df..2e6c83adbd1f 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.h
+++ b/drivers/pinctrl/meson/pinctrl-meson.h
@@ -123,6 +123,7 @@ struct meson_pinctrl {
 	struct regmap *reg_gpio;
 	struct gpio_chip chip;
 	struct device_node *of_node;
+	struct fwnode_handle *fwnode;
 };
 
 #define PIN(x, b)	(b + x)
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 3/9] pinctrl: meson: update pinctrl data with gpio irq data
From: Jerome Brunet @ 2016-10-19 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476890480-8884-1-git-send-email-jbrunet@baylibre.com>

This patch extends meson's pinctrl SoC specific data by adding the gpio
irq base number and the compatible controller for each SoC. This will
allow gpios to request an interrupt on the gpio interrupt controller
using this base irq number the pin offset inbank

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 24 +++++++++++----------
 drivers/pinctrl/meson/pinctrl-meson.h      | 16 +++++++++-----
 drivers/pinctrl/meson/pinctrl-meson8.c     | 22 ++++++++++---------
 drivers/pinctrl/meson/pinctrl-meson8b.c    | 34 +++++++++++++++++++++---------
 4 files changed, 60 insertions(+), 36 deletions(-)

diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
index c3928aa3fefa..ed8a1222de3b 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
@@ -715,24 +715,25 @@ static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
 };
 
 static struct meson_bank meson_gxbb_periphs_banks[] = {
-	/*   name    first                      last                    pullen  pull    dir     out     in  */
-	BANK("X",    PIN(GPIOX_0, EE_OFF),	PIN(GPIOX_22, EE_OFF),  4,  0,  4,  0,  12, 0,  13, 0,  14, 0),
-	BANK("Y",    PIN(GPIOY_0, EE_OFF),	PIN(GPIOY_16, EE_OFF),  1,  0,  1,  0,  3,  0,  4,  0,  5,  0),
-	BANK("DV",   PIN(GPIODV_0, EE_OFF),	PIN(GPIODV_29, EE_OFF), 0,  0,  0,  0,  0,  0,  1,  0,  2,  0),
-	BANK("H",    PIN(GPIOH_0, EE_OFF),	PIN(GPIOH_3, EE_OFF),   1, 20,  1, 20,  3, 20,  4, 20,  5, 20),
-	BANK("Z",    PIN(GPIOZ_0, EE_OFF),	PIN(GPIOZ_15, EE_OFF),  3,  0,  3,  0,  9,  0,  10, 0, 11,  0),
-	BANK("CARD", PIN(CARD_0, EE_OFF),	PIN(CARD_6, EE_OFF),    2, 20,  2, 20,  6, 20,  7, 20,  8, 20),
-	BANK("BOOT", PIN(BOOT_0, EE_OFF),	PIN(BOOT_17, EE_OFF),   2,  0,  2,  0,  6,  0,  7,  0,  8,  0),
-	BANK("CLK",  PIN(GPIOCLK_0, EE_OFF),	PIN(GPIOCLK_3, EE_OFF), 3, 28,  3, 28,  9, 28, 10, 28, 11, 28),
+	/*   name    first                      last                    irq       pullen  pull    dir     out     in  */
+	BANK("X",    PIN(GPIOX_0, EE_OFF),	PIN(GPIOX_22, EE_OFF),  106, 128, 4,  0,  4,  0,  12, 0,  13, 0,  14, 0),
+	BANK("Y",    PIN(GPIOY_0, EE_OFF),	PIN(GPIOY_16, EE_OFF),   89, 105, 1,  0,  1,  0,  3,  0,  4,  0,  5,  0),
+	BANK("DV",   PIN(GPIODV_0, EE_OFF),	PIN(GPIODV_29, EE_OFF),  59,  88, 0,  0,  0,  0,  0,  0,  1,  0,  2,  0),
+	BANK("H",    PIN(GPIOH_0, EE_OFF),	PIN(GPIOH_3, EE_OFF),    30,  33, 1, 20,  1, 20,  3, 20,  4, 20,  5, 20),
+	BANK("Z",    PIN(GPIOZ_0, EE_OFF),	PIN(GPIOZ_15, EE_OFF),   14,  29, 3,  0,  3,  0,  9,  0,  10, 0, 11,  0),
+	BANK("CARD", PIN(CARD_0, EE_OFF),	PIN(CARD_6, EE_OFF),     52,  58, 2, 20,  2, 20,  6, 20,  7, 20,  8, 20),
+	BANK("BOOT", PIN(BOOT_0, EE_OFF),	PIN(BOOT_17, EE_OFF),    34,  51, 2,  0,  2,  0,  6,  0,  7,  0,  8,  0),
+	BANK("CLK",  PIN(GPIOCLK_0, EE_OFF),	PIN(GPIOCLK_3, EE_OFF), 129, 132, 3, 28,  3, 28,  9, 28, 10, 28, 11, 28),
 };
 
 static struct meson_bank meson_gxbb_aobus_banks[] = {
-	/*   name    first              last               pullen  pull    dir     out     in  */
-	BANK("AO",   PIN(GPIOAO_0, 0),  PIN(GPIOAO_13, 0), 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
+	/*   name    first              last               irq    pullen  pull    dir     out     in  */
+	BANK("AO",   PIN(GPIOAO_0, 0),  PIN(GPIOAO_13, 0), 0, 13, 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
 };
 
 struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = {
 	.name		= "periphs-banks",
+	.irq_compat	= "amlogic,meson-gxbb-gpio-intc",
 	.pin_base	= 14,
 	.pins		= meson_gxbb_periphs_pins,
 	.groups		= meson_gxbb_periphs_groups,
@@ -746,6 +747,7 @@ struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = {
 
 struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = {
 	.name		= "aobus-banks",
+	.irq_compat	= "amlogic,meson-gxbb-gpio-intc",
 	.pin_base	= 0,
 	.pins		= meson_gxbb_aobus_pins,
 	.groups		= meson_gxbb_aobus_groups,
diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h
index 98b5080650c1..b90d69e366df 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.h
+++ b/drivers/pinctrl/meson/pinctrl-meson.h
@@ -81,6 +81,7 @@ enum meson_reg_type {
  * @name:	bank name
  * @first:	first pin of the bank
  * @last:	last pin of the bank
+ * @irq:	hwirq base number of the bank
  * @regs:	array of register descriptors
  *
  * A bank represents a set of pins controlled by a contiguous set of
@@ -92,11 +93,14 @@ struct meson_bank {
 	const char *name;
 	unsigned int first;
 	unsigned int last;
+	int irq_first;
+	int irq_last;
 	struct meson_reg_desc regs[NUM_REG];
 };
 
 struct meson_pinctrl_data {
 	const char *name;
+	const char *irq_compat;
 	const struct pinctrl_pin_desc *pins;
 	struct meson_pmx_group *groups;
 	struct meson_pmx_func *funcs;
@@ -147,12 +151,14 @@ struct meson_pinctrl {
 		.num_groups = ARRAY_SIZE(fn ## _groups),		\
 	}
 
-#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib)		\
+#define BANK(n, f, l, fi, li, per, peb, pr, pb, dr, db, or, ob, ir, ib)	\
 	{								\
-		.name	= n,						\
-		.first	= f,						\
-		.last	= l,						\
-		.regs	= {						\
+		.name		= n,					\
+		.first		= f,					\
+		.last		= l,					\
+		.irq_first	= fi,					\
+		.irq_last	= li,					\
+		.regs = {						\
 			[REG_PULLEN]	= { per, peb },			\
 			[REG_PULL]	= { pr, pb },			\
 			[REG_DIR]	= { dr, db },			\
diff --git a/drivers/pinctrl/meson/pinctrl-meson8.c b/drivers/pinctrl/meson/pinctrl-meson8.c
index 07f1cb21c1b8..eddab1091408 100644
--- a/drivers/pinctrl/meson/pinctrl-meson8.c
+++ b/drivers/pinctrl/meson/pinctrl-meson8.c
@@ -916,23 +916,24 @@ static struct meson_pmx_func meson8_aobus_functions[] = {
 };
 
 static struct meson_bank meson8_cbus_banks[] = {
-	/*   name    first             last                 pullen  pull    dir     out     in  */
-	BANK("X",    PIN(GPIOX_0, 0),  PIN(GPIOX_21, 0),    4,  0,  4,  0,  0,  0,  1,  0,  2,  0),
-	BANK("Y",    PIN(GPIOY_0, 0),  PIN(GPIOY_16, 0),    3,  0,  3,  0,  3,  0,  4,  0,  5,  0),
-	BANK("DV",   PIN(GPIODV_0, 0), PIN(GPIODV_29, 0),   0,  0,  0,  0,  7,  0,  8,  0,  9,  0),
-	BANK("H",    PIN(GPIOH_0, 0),  PIN(GPIOH_9, 0),     1, 16,  1, 16,  9, 19, 10, 19, 11, 19),
-	BANK("Z",    PIN(GPIOZ_0, 0),  PIN(GPIOZ_14, 0),    1,  0,  1,  0,  3, 17,  4, 17,  5, 17),
-	BANK("CARD", PIN(CARD_0, 0),   PIN(CARD_6, 0),      2, 20,  2, 20,  0, 22,  1, 22,  2, 22),
-	BANK("BOOT", PIN(BOOT_0, 0),   PIN(BOOT_18, 0),     2,  0,  2,  0,  9,  0, 10,  0, 11,  0),
+	/*   name    first             last                 irq       pullen  pull    dir     out     in  */
+	BANK("X",    PIN(GPIOX_0, 0),  PIN(GPIOX_21, 0),    112, 133, 4,  0,  4,  0,  0,  0,  1,  0,  2,  0),
+	BANK("Y",    PIN(GPIOY_0, 0),  PIN(GPIOY_16, 0),    95,  111, 3,  0,  3,  0,  3,  0,  4,  0,  5,  0),
+	BANK("DV",   PIN(GPIODV_0, 0), PIN(GPIODV_29, 0),   65,   94, 0,  0,  0,  0,  7,  0,  8,  0,  9,  0),
+	BANK("H",    PIN(GPIOH_0, 0),  PIN(GPIOH_9, 0),     29,   38, 1, 16,  1, 16,  9, 19, 10, 19, 11, 19),
+	BANK("Z",    PIN(GPIOZ_0, 0),  PIN(GPIOZ_14, 0),    14,   28, 1,  0,  1,  0,  3, 17,  4, 17,  5, 17),
+	BANK("CARD", PIN(CARD_0, 0),   PIN(CARD_6, 0),      58,   64, 2, 20,  2, 20,  0, 22,  1, 22,  2, 22),
+	BANK("BOOT", PIN(BOOT_0, 0),   PIN(BOOT_18, 0),     39,   57, 2,  0,  2,  0,  9,  0, 10,  0, 11,  0),
 };
 
 static struct meson_bank meson8_aobus_banks[] = {
-	/*   name    first                  last                      pullen  pull    dir     out     in  */
-	BANK("AO",   PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
+	/*   name    first                  last                      irq    pullen  pull    dir     out     in  */
+	BANK("AO",   PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 13, 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
 };
 
 struct meson_pinctrl_data meson8_cbus_pinctrl_data = {
 	.name		= "cbus-banks",
+	.irq_compat	= "amlogic,meson8-gpio-intc",
 	.pin_base	= 0,
 	.pins		= meson8_cbus_pins,
 	.groups		= meson8_cbus_groups,
@@ -946,6 +947,7 @@ struct meson_pinctrl_data meson8_cbus_pinctrl_data = {
 
 struct meson_pinctrl_data meson8_aobus_pinctrl_data = {
 	.name		= "ao-bank",
+	.irq_compat	= "amlogic,meson8-gpio-intc",
 	.pin_base	= 120,
 	.pins		= meson8_aobus_pins,
 	.groups		= meson8_aobus_groups,
diff --git a/drivers/pinctrl/meson/pinctrl-meson8b.c b/drivers/pinctrl/meson/pinctrl-meson8b.c
index 76f077f18193..d7505f492639 100644
--- a/drivers/pinctrl/meson/pinctrl-meson8b.c
+++ b/drivers/pinctrl/meson/pinctrl-meson8b.c
@@ -124,6 +124,12 @@ static const struct pinctrl_pin_desc meson8b_aobus_pins[] = {
 	MESON_PIN(GPIOAO_11, AO_OFF),
 	MESON_PIN(GPIOAO_12, AO_OFF),
 	MESON_PIN(GPIOAO_13, AO_OFF),
+
+	/*
+	 * The following 2 pins are not mentionned in the public datasheet
+	 * According to this datasheet, they can't be used with the gpio
+	 * interrupt controller
+	 */
 	MESON_PIN(GPIO_BSD_EN, AO_OFF),
 	MESON_PIN(GPIO_TEST_N, AO_OFF),
 };
@@ -881,23 +887,30 @@ static struct meson_pmx_func meson8b_aobus_functions[] = {
 };
 
 static struct meson_bank meson8b_cbus_banks[] = {
-	/*   name    first                      last                   pullen  pull    dir     out     in  */
-	BANK("X",    PIN(GPIOX_0, 0),		PIN(GPIOX_21, 0),      4,  0,  4,  0,  0,  0,  1,  0,  2,  0),
-	BANK("Y",    PIN(GPIOY_0, 0),		PIN(GPIOY_14, 0),      3,  0,  3,  0,  3,  0,  4,  0,  5,  0),
-	BANK("DV",   PIN(GPIODV_9, 0),		PIN(GPIODV_29, 0),     0,  0,  0,  0,  7,  0,  8,  0,  9,  0),
-	BANK("H",    PIN(GPIOH_0, 0),		PIN(GPIOH_9, 0),       1, 16,  1, 16,  9, 19, 10, 19, 11, 19),
-	BANK("CARD", PIN(CARD_0, 0),		PIN(CARD_6, 0),        2, 20,  2, 20,  0, 22,  1, 22,  2, 22),
-	BANK("BOOT", PIN(BOOT_0, 0),		PIN(BOOT_18, 0),       2,  0,  2,  0,  9,  0, 10,  0, 11,  0),
-	BANK("DIF",  PIN(DIF_0_P, 0),		PIN(DIF_4_N, 0),       5,  8,  5,  8, 12, 12, 13, 12, 14, 12),
+	/*   name    first                      last                irq      pullen  pull    dir     out     in  */
+	BANK("X",    PIN(GPIOX_0, 0),		PIN(GPIOX_21, 0),   97, 118, 4,  0,  4,  0,  0,  0,  1,  0,  2,  0),
+	BANK("Y",    PIN(GPIOY_0, 0),		PIN(GPIOY_14, 0),   80,  96, 3,  0,  3,  0,  3,  0,  4,  0,  5,  0),
+	BANK("DV",   PIN(GPIODV_9, 0),		PIN(GPIODV_29, 0),  59,  79, 0,  0,  0,  0,  7,  0,  8,  0,  9,  0),
+	BANK("H",    PIN(GPIOH_0, 0),		PIN(GPIOH_9, 0),    14,  23, 1, 16,  1, 16,  9, 19, 10, 19, 11, 19),
+	BANK("CARD", PIN(CARD_0, 0),		PIN(CARD_6, 0),     43,  49, 2, 20,  2, 20,  0, 22,  1, 22,  2, 22),
+	BANK("BOOT", PIN(BOOT_0, 0),		PIN(BOOT_18, 0),    24,  42, 2,  0,  2,  0,  9,  0, 10,  0, 11,  0),
+
+	/*
+	 * The following bank is not mentionned in the public datasheet
+	 * There is no information whether it can be used with the gpio
+	 * interrupt controller
+	 */
+	BANK("DIF",  PIN(DIF_0_P, 0),		PIN(DIF_4_N, 0),    -1,  -1, 5,  8,  5,  8, 12, 12, 13, 12, 14, 12),
 };
 
 static struct meson_bank meson8b_aobus_banks[] = {
-	/*   name    first                  last                      pullen  pull    dir     out     in  */
-	BANK("AO",   PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
+	/*   name    first                  last                      irq    pullen  pull    dir     out     in  */
+	BANK("AO",   PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0, 13, 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
 };
 
 struct meson_pinctrl_data meson8b_cbus_pinctrl_data = {
 	.name		= "cbus-banks",
+	.irq_compat	= "amlogic,meson8b-gpio-intc",
 	.pin_base	= 0,
 	.pins		= meson8b_cbus_pins,
 	.groups		= meson8b_cbus_groups,
@@ -911,6 +924,7 @@ struct meson_pinctrl_data meson8b_cbus_pinctrl_data = {
 
 struct meson_pinctrl_data meson8b_aobus_pinctrl_data = {
 	.name		= "aobus-banks",
+	.irq_compat	= "amlogic,meson8b-gpio-intc",
 	.pin_base	= 130,
 	.pins		= meson8b_aobus_pins,
 	.groups		= meson8b_aobus_groups,
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 2/9] dt-bindings: interrupt-controller: add DT binding for meson GPIO interrupt controller
From: Jerome Brunet @ 2016-10-19 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476890480-8884-1-git-send-email-jbrunet@baylibre.com>


This commit adds the device tree bindings description for Amlogic's GPIO
interrupt controller available on the meson8, meson8b and gxbb SoC families

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
Rob, I did not include the Ack you gave for the RFC as bindings have slightly
changed. Only the interrupt property has be removed following a discussion I
had with Marc

 .../amlogic,meson-gpio-intc.txt                    | 31 ++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt

diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
new file mode 100644
index 000000000000..2464d9a0865d
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
@@ -0,0 +1,31 @@
+Amlogic meson GPIO interrupt controller
+
+Meson SoCs contains an interrupt controller which is able watch the SoC pads
+and generate an interrupt on edges or level. The controller is essentially a
+256 pads to 8 GIC interrupt multiplexer, with a filter block to select edge
+or level and polarity. We don?t expose all 256 mux inputs because the
+documentation shows that upper part is not mapped to any pad. The actual number
+of interrupt exposed depends on the SoC.
+
+Required properties:
+
+- compatible : should be either
+   "amlogic,meson8-gpio-intc? for meson8 SoCs (AML7826MX) or
+   ?amlogic,meson8b-gpio-intc? for meson8b SoCs (S805) or
+   ?amlogic,meson-gxbb-gpio-intc? for GXBB SoCs (S905)
+- interrupt-parent : a phandle to the GIC the interrupts are routed to.
+   Usually this is provided at the root level of the device tree as it is
+   common to most of the SoC
+- reg : Specifies base physical address and size of the registers.
+- interrupt-controller : Identifies the node as an interrupt controller.
+- #interrupt-cells : Specifies the number of cells needed to encode an
+   interrupt source. The value must be 2.
+
+Example:
+
+gpio_interrupt: interrupt-controller at 9880 {
+	compatible = "amlogic,meson-gxbb-gpio-intc";
+	reg = <0x0 0x9880 0x0 0x10>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+};
-- 
2.7.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox