* [GIT PULL] power: ab8500-bm: Latest Mainline<->STE delta reduction patch-set
From: Anton Vorontsov @ 2013-02-03 3:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130131120833.GH5301@gmail.com>
On Thu, Jan 31, 2013 at 12:08:33PM +0000, Lee Jones wrote:
> > Okay, after Linus Walleij's diligent observaions, I have removed all
> > new functionallity related to Deep Debug and will continue to
> > investigate what I need to do in that regard.
> >
> > In the mean-time, here's the fresh deep-debug:less pull-request:
> >
> > ----------------------------------------------------------------
> >
> > The following changes since commit 8fd526fd18233887ba652079a369f4eee0de9d9d:
> >
> > qnap-poweroff: Fix license string (2013-01-19 18:04:04 -0800)
> >
> > are available in the git repository at:
> >
> > git://git.linaro.org/people/ljones/linux-3.0-ux500.git tb-power-2
> >
> > for you to fetch changes up to 34c11a709e928090cf34ecd706f7d3170f4e5026:
> >
> > u8500-charger: Delay for USB enumeration (2013-01-23 14:39:22 +0000)
>
> Did you pull this in the end?
I was buried under my homework, sorry. :-) The changes look good, thanks a
lot! Pulled now.
Anton
^ permalink raw reply
* [PATCH] power/reset: restart: remove __dev{init,exit}
From: Anton Vorontsov @ 2013-02-03 3:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130131202000.GI7717@titan.lakedaemon.net>
On Thu, Jan 31, 2013 at 03:20:00PM -0500, Jason Cooper wrote:
> On Thu, Jan 31, 2013 at 09:02:50PM +0100, Andrew Lunn wrote:
> > On Thu, Jan 31, 2013 at 06:54:29PM +0000, Jason Cooper wrote:
> > > Signed-off-by: Jason Cooper <jason@lakedaemon.net>
> >
> > Hi Jason
> >
> > I Acked-by: a very similar patch to this yesterday....
> >
> > https://lkml.org/lkml/2013/1/30/233
I've added Jason's Signed-off-by to the Thierry's patch.
Thanks!
Anton
^ permalink raw reply
* [PATCH 1/1] net: fec: fix miss init spinlock
From: David Miller @ 2013-02-03 4:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359708986-23634-1-git-send-email-Frank.Li@freescale.com>
From: Frank Li <Frank.Li@freescale.com>
Date: Fri, 1 Feb 2013 16:56:26 +0800
> @@ -1607,6 +1607,7 @@ static int fec_enet_init(struct net_device *ndev)
> }
>
> spin_lock_init(&fep->hw_lock);
> + spin_lock_init(&fep->tmreg_lock);
This breaks the build, tmreg_lock is only present in certain
configurations.
^ permalink raw reply
* [PATCH] gpio: mvebu: Add clk support to prevent lockup
From: Andrew Lunn @ 2013-02-03 9:55 UTC (permalink / raw)
To: linux-arm-kernel
The kirkwood SoC GPIO cores use the tclk. Add code to
clk_prepare_enable() tclk, otherwise there is a danger of locking up
the SoC by accessing the GPIO registers when tclk is not ticking.
Reported-by: Simon Baatz <gmbnomis@gmail.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
arch/arm/boot/dts/kirkwood.dtsi | 2 ++
drivers/gpio/gpio-mvebu.c | 7 +++++++
2 files changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index d6ab442..6c5d75f 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -38,6 +38,7 @@
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <35>, <36>, <37>, <38>;
+ clocks = <&gate_clk 7>;
};
gpio1: gpio at 10140 {
@@ -49,6 +50,7 @@
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <39>, <40>, <41>;
+ clocks = <&gate_clk 7>;
};
serial at 12000 {
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 6819d63..456663c 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -41,6 +41,7 @@
#include <linux/io.h>
#include <linux/of_irq.h>
#include <linux/of_device.h>
+#include <linux/clk.h>
#include <linux/pinctrl/consumer.h>
/*
@@ -495,6 +496,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
struct resource *res;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
+ struct clk *clk;
unsigned int ngpios;
int soc_variant;
int i, cpu, id;
@@ -528,6 +530,11 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
return id;
}
+ clk = devm_clk_get(&pdev->dev, NULL);
+ /* Not all SoCs require a clock.*/
+ if (!IS_ERR(clk))
+ clk_prepare_enable(clk);
+
mvchip->soc_variant = soc_variant;
mvchip->chip.label = dev_name(&pdev->dev);
mvchip->chip.dev = &pdev->dev;
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 13/15] ARM: CCI: ensure powerdown-time data is flushed from cache
From: Santosh Shilimkar @ 2013-02-03 10:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1302021708460.6300@xanadu.home>
On Sunday 03 February 2013 03:53 AM, Nicolas Pitre wrote:
> On Fri, 1 Feb 2013, Santosh Shilimkar wrote:
>
>> On Tuesday 29 January 2013 01:21 PM, Nicolas Pitre wrote:
>>> From: Dave Martin <dave.martin@linaro.org>
>>>
>>> Non-local variables used by the CCI management function called after
>>> disabling the cache must be flushed out to main memory in advance,
>>> otherwise incoherency of those values may occur if they are sitting
>>> in the cache of some other CPU when cci_disable() executes.
>>>
>> Any CPU calling cci_disable() would have already cleaned its local
>> cache and the snoop unit should take care of syncing the shared data
>> before hand from other CPU local caches for shared accesses.
>> May be I am unable to visualize the issue here or missing some key
>> point.
>
> Let's suppose CPU0 initializes the CCI. Without this patch, the CCI
> base address might be sitting in CPU0's cache.
>
> The last CPU in a cluster to shut itself down is responsible for calling
> cci_disable(). And being the last, it is also responsible for flushing
> out its L1 and L2 caches before doing that. If CPU0 went down before
> that, it did flush its L1 already. So the base address will be flushed
> to RAM in that case.
>
Yes. This is valid case. Thanks for description.
> But if it is a CPU in _another_ cluster which is shutting down and
> becoming the last man _there_. It will flush its L1 and L2 cache
> before calling cci_disable(). And
> because the cache is disabled at that point, that CPU won't
> send any snoop request across to the other cluster where CPU0 holds the
> base address in its L1 or even L2 cache.
>
> This is why we must push out that value out to RAM before cci_disable()
> is used.
>
>>> This patch adds the appropriate flushing to the CCI driver to ensure
>>> that the relevant data is available in RAM ahead of time.
>>>
>>> Because this creates a dependency on arch-specific cacheflushing
>>> functions, this patch also makes ARM_CCI depend on ARM.
>>>
>> You should do that otherwise to avoid other arch building this
>> driver for random builds and breaking their builds.
>
> Before this patch the driver was buildable on any architecture. That's
> why this dependency is added only in this patch.
>
I was just trying to counter the reasoning in the changelog which says
dependency is added because of arch specific cache flushing function.
Meaning even without that ARM dependency should be in place to avoid
driver getting build for other archs.
Regards,
Santosh
^ permalink raw reply
* [PATCH v2 00/10] rework pxa gpio driver for pinctrl
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
Changelog:
v2:
* Fix the build issue without CONFIG_OF
* Append to check PINCTRL_SINGLE because of arch pxa not moved to DT
* Use bool for inverted, ed_mask, gafr variable
^ permalink raw reply
* [PATCH v2 01/10] gpio: pxa: identify ed mask reg with platform data
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
Avoid to judge whether edge mask register exists by CPU. Use platform
data to identify it instead. The gpio edge mask register exists in MMP
series SoC.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
arch/arm/mach-mmp/aspenite.c | 7 +++++++
arch/arm/mach-mmp/avengers_lite.c | 7 +++++++
arch/arm/mach-mmp/brownstone.c | 7 +++++++
arch/arm/mach-mmp/flint.c | 7 +++++++
arch/arm/mach-mmp/gplugd.c | 7 +++++++
arch/arm/mach-mmp/tavorevb.c | 7 +++++++
arch/arm/mach-mmp/teton_bga.c | 7 +++++++
arch/arm/mach-mmp/ttc_dkb.c | 7 +++++++
drivers/gpio/gpio-pxa.c | 10 +++++++++-
include/linux/gpio-pxa.h | 1 +
10 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 9f64d56..36f5781 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -9,6 +9,7 @@
* publishhed by the Free Software Foundation.
*/
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
@@ -110,6 +111,10 @@ static unsigned long common_pin_config[] __initdata = {
GPIO121_KP_MKIN4,
};
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .ed_mask = true,
+};
+
static struct smc91x_platdata smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
@@ -248,6 +253,8 @@ static void __init common_init(void)
pxa168_add_nand(&aspenite_nand_info);
pxa168_add_fb(&aspenite_lcd_info);
pxa168_add_keypad(&aspenite_keypad_info);
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa168_device_gpio);
/* off-chip devices */
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index 1f94957..b8fe447 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/gpio-pxa.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
@@ -32,12 +33,18 @@ static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
GPIO89_UART2_RXD,
};
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .ed_mask = true,
+};
+
static void __init avengers_lite_init(void)
{
mfp_config(ARRAY_AND_SIZE(avengers_lite_pin_config_V16F));
/* on-chip devices */
pxa168_add_uart(2);
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa168_device_gpio);
}
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index 2358011..d6ea5c4 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/gpio-pxa.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/max8649.h>
#include <linux/regulator/fixed.h>
@@ -104,6 +105,10 @@ static unsigned long brownstone_pin_config[] __initdata = {
GPIO89_GPIO,
};
+static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+ .ed_mask = true,
+};
+
static struct regulator_consumer_supply max8649_supply[] = {
REGULATOR_SUPPLY("vcc_core", NULL),
};
@@ -202,6 +207,8 @@ static void __init brownstone_init(void)
/* on-chip devices */
mmp2_add_uart(1);
mmp2_add_uart(3);
+ platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&mmp2_device_gpio);
mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 754c352..0955f44 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -16,6 +16,7 @@
#include <linux/smc91x.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/interrupt.h>
#include <asm/mach-types.h>
@@ -77,6 +78,10 @@ static unsigned long flint_pin_config[] __initdata = {
GPIO160_ND_RDY1,
};
+static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+ .ed_mask = true,
+};
+
static struct smc91x_platdata flint_smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
@@ -111,6 +116,8 @@ static void __init flint_init(void)
/* on-chip devices */
mmp2_add_uart(1);
mmp2_add_uart(2);
+ platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&mmp2_device_gpio);
/* off-chip devices */
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index d1e2d59..2315cce 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@@ -127,6 +128,10 @@ static unsigned long gplugd_pin_config[] __initdata = {
GPIO116_I2S_TXD
};
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .ed_mask = true,
+};
+
static struct i2c_board_info gplugd_i2c_board_info[] = {
{
.type = "isl1208",
@@ -185,6 +190,8 @@ static void __init gplugd_init(void)
pxa168_add_uart(3);
pxa168_add_ssp(1);
pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa168_device_gpio);
pxa168_add_eth(&gplugd_eth_platform_data);
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index 4c127d2..eaec649 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -8,6 +8,7 @@
* publishhed by the Free Software Foundation.
*/
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
@@ -60,6 +61,10 @@ static unsigned long tavorevb_pin_config[] __initdata = {
DF_RDY0_DF_RDY0,
};
+static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+ .ed_mask = true,
+};
+
static struct smc91x_platdata tavorevb_smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
@@ -93,6 +98,8 @@ static void __init tavorevb_init(void)
/* on-chip devices */
pxa910_add_uart(1);
+ platform_device_add_data(&pxa910_device_gpio, &ttc_dkb_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa910_device_gpio);
/* off-chip devices */
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 8609967..6682100 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/input.h>
#include <linux/platform_data/keypad-pxa27x.h>
#include <linux/i2c.h>
@@ -49,6 +50,10 @@ static unsigned long teton_bga_pin_config[] __initdata = {
GPIO78_GPIO,
};
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .ed_mask = true,
+};
+
static unsigned int teton_bga_matrix_key_map[] = {
KEY(0, 6, KEY_ESC),
KEY(0, 7, KEY_ENTER),
@@ -79,6 +84,8 @@ static void __init teton_bga_init(void)
pxa168_add_uart(1);
pxa168_add_keypad(&teton_bga_keypad_info);
pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info));
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa168_device_gpio);
}
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 6e47490..984d902 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/i2c/pca953x.h>
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/mfd/88pm860x.h>
#include <linux/platform_data/mv_usb.h>
@@ -73,6 +74,10 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
DF_RDY0_DF_RDY0,
};
+static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+ .ed_mask = true,
+};
+
static struct mtd_partition ttc_dkb_onenand_partitions[] = {
{
.name = "bootloader",
@@ -196,6 +201,8 @@ static void __init ttc_dkb_init(void)
/* off-chip devices */
pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info));
+ platform_device_add_data(&pxa910_device_gpio, &ttc_dkb_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));
#ifdef CONFIG_USB_MV_UDC
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 9cc108d..a4c6687 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -493,6 +493,7 @@ const struct irq_domain_ops pxa_irq_domain_ops = {
static int pxa_gpio_probe_dt(struct platform_device *pdev)
{
int ret, nr_banks, nr_gpios;
+ struct pxa_gpio_platform_data *pdata;
struct device_node *prev, *next, *np = pdev->dev.of_node;
const struct of_device_id *of_id =
of_match_device(pxa_gpio_dt_ids, &pdev->dev);
@@ -501,6 +502,13 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
dev_err(&pdev->dev, "Failed to find gpio controller\n");
return -EFAULT;
}
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ if (of_find_property(np, "marvell,gpio-ed-mask", NULL))
+ pdata->ed_mask = true;
+ /* set the platform data */
+ pdev->dev.platform_data = pdata;
gpio_type = (int)of_id->data;
next = of_get_next_child(np, NULL);
@@ -604,7 +612,7 @@ static int pxa_gpio_probe(struct platform_device *pdev)
writel_relaxed(0, c->regbase + GRER_OFFSET);
writel_relaxed(~0,c->regbase + GEDR_OFFSET);
/* unmask GPIO edge detect for AP side */
- if (gpio_is_mmp_type(gpio_type))
+ if (info->ed_mask)
writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
}
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index d755b28..bc5cae5 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -14,6 +14,7 @@ extern int pxa_last_gpio;
extern int pxa_irq_to_gpio(int irq);
struct pxa_gpio_platform_data {
+ bool ed_mask; /* true means that ed_mask reg is available */
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 02/10] gpio: pxa: avoid to use global irq base
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
Avoid to use global irq_base in gpio-pxa driver. Define irq_base in each
pxa_gpio_chip instead. Then we can avoid to use macro PXA_GPIO_TO_IRQ() &
MMP_GPIO_TO_IRQ().
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
arch/arm/mach-pxa/pxa25x.c | 2 +-
arch/arm/mach-pxa/pxa27x.c | 2 +-
drivers/gpio/Kconfig | 1 +
drivers/gpio/gpio-pxa.c | 156 ++++++++++++++++++++++----------------------
include/linux/gpio-pxa.h | 4 +-
5 files changed, 85 insertions(+), 80 deletions(-)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 3f5171e..f4c293a 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -289,7 +289,7 @@ static inline void pxa25x_init_pm(void) {}
static int pxa25x_set_wake(struct irq_data *d, unsigned int on)
{
- int gpio = pxa_irq_to_gpio(d->irq);
+ int gpio = pxa_irq_to_gpio(d);
uint32_t mask = 0;
if (gpio >= 0 && gpio < 85)
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 69985b06..67f5fd2 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -364,7 +364,7 @@ static inline void pxa27x_init_pm(void) {}
*/
static int pxa27x_set_wake(struct irq_data *d, unsigned int on)
{
- int gpio = pxa_irq_to_gpio(d->irq);
+ int gpio = pxa_irq_to_gpio(d);
uint32_t mask;
if (gpio >= 0 && gpio < 128)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 176fb3d..b8c0da8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -201,6 +201,7 @@ config GPIO_PL061
config GPIO_PXA
bool "PXA GPIO support"
depends on ARCH_PXA || ARCH_MMP
+ select IRQ_DOMAIN
help
Say yes here to support the PXA GPIO device
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index a4c6687..2310665 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -13,6 +13,7 @@
*/
#include <linux/module.h>
#include <linux/clk.h>
+#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio-pxa.h>
@@ -61,16 +62,15 @@
#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
int pxa_last_gpio;
-static int irq_base;
#ifdef CONFIG_OF
-static struct irq_domain *domain;
static struct device_node *pxa_gpio_of_node;
#endif
struct pxa_gpio_chip {
struct gpio_chip chip;
void __iomem *regbase;
+ unsigned int irq_base;
char label[10];
unsigned long irq_mask;
@@ -170,14 +170,22 @@ static inline int __gpio_is_occupied(unsigned gpio)
return ret;
}
-static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+static int pxa_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
{
- return chip->base + offset + irq_base;
+ struct pxa_gpio_chip *chip = NULL;
+
+ chip = container_of(gc, struct pxa_gpio_chip, chip);
+ return chip->irq_base + offset;
}
-int pxa_irq_to_gpio(int irq)
+int pxa_irq_to_gpio(struct irq_data *d)
{
- return irq - irq_base;
+ struct pxa_gpio_chip *chip;
+ int gpio;
+
+ chip = (struct pxa_gpio_chip *)d->domain->host_data;
+ gpio = d->irq - chip->irq_base + chip->chip.base;
+ return gpio;
}
static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -250,47 +258,6 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
}
#endif
-static int pxa_init_gpio_chip(int gpio_end,
- int (*set_wake)(unsigned int, unsigned int))
-{
- int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
- struct pxa_gpio_chip *chips;
-
- chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL);
- if (chips == NULL) {
- pr_err("%s: failed to allocate GPIO chips\n", __func__);
- return -ENOMEM;
- }
-
- for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
- struct gpio_chip *c = &chips[i].chip;
-
- sprintf(chips[i].label, "gpio-%d", i);
- chips[i].regbase = gpio_reg_base + BANK_OFF(i);
- chips[i].set_wake = set_wake;
-
- c->base = gpio;
- c->label = chips[i].label;
-
- c->direction_input = pxa_gpio_direction_input;
- c->direction_output = pxa_gpio_direction_output;
- c->get = pxa_gpio_get;
- c->set = pxa_gpio_set;
- c->to_irq = pxa_gpio_to_irq;
-#ifdef CONFIG_OF_GPIO
- c->of_node = pxa_gpio_of_node;
- c->of_xlate = pxa_gpio_of_xlate;
- c->of_gpio_n_cells = 2;
-#endif
-
- /* number of GPIOs on last bank may be less than 32 */
- c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
- gpiochip_add(c);
- }
- pxa_gpio_chips = chips;
- return 0;
-}
-
/* Update only those GRERx and GFERx edge detection register bits if those
* bits are set in c->irq_mask
*/
@@ -309,7 +276,7 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c)
static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
{
struct pxa_gpio_chip *c;
- int gpio = pxa_irq_to_gpio(d->irq);
+ int gpio = pxa_irq_to_gpio(d);
unsigned long gpdr, mask = GPIO_bit(gpio);
c = gpio_to_pxachip(gpio);
@@ -383,7 +350,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
static void pxa_ack_muxed_gpio(struct irq_data *d)
{
- int gpio = pxa_irq_to_gpio(d->irq);
+ int gpio = pxa_irq_to_gpio(d);
struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
@@ -391,7 +358,7 @@ static void pxa_ack_muxed_gpio(struct irq_data *d)
static void pxa_mask_muxed_gpio(struct irq_data *d)
{
- int gpio = pxa_irq_to_gpio(d->irq);
+ int gpio = pxa_irq_to_gpio(d);
struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
uint32_t grer, gfer;
@@ -405,7 +372,7 @@ static void pxa_mask_muxed_gpio(struct irq_data *d)
static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
{
- int gpio = pxa_irq_to_gpio(d->irq);
+ int gpio = pxa_irq_to_gpio(d);
struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
if (c->set_wake)
@@ -416,7 +383,7 @@ static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
static void pxa_unmask_muxed_gpio(struct irq_data *d)
{
- int gpio = pxa_irq_to_gpio(d->irq);
+ int gpio = pxa_irq_to_gpio(d);
struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
c->irq_mask |= GPIO_bit(gpio);
@@ -469,13 +436,6 @@ static int pxa_gpio_nums(void)
return count;
}
-#ifdef CONFIG_OF
-static struct of_device_id pxa_gpio_dt_ids[] = {
- { .compatible = "mrvl,pxa-gpio" },
- { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
- {}
-};
-
static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
@@ -485,11 +445,18 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
return 0;
}
-const struct irq_domain_ops pxa_irq_domain_ops = {
+static const struct irq_domain_ops pxa_irq_domain_ops = {
.map = pxa_irq_domain_map,
.xlate = irq_domain_xlate_twocell,
};
+#ifdef CONFIG_OF
+static struct of_device_id pxa_gpio_dt_ids[] = {
+ { .compatible = "mrvl,pxa-gpio" },
+ { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
+ {}
+};
+
static int pxa_gpio_probe_dt(struct platform_device *pdev)
{
int ret, nr_banks, nr_gpios;
@@ -528,14 +495,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
nr_gpios = nr_banks << 5;
pxa_last_gpio = nr_gpios - 1;
- irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
- if (irq_base < 0) {
- dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
- goto err;
- }
- domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
- &pxa_irq_domain_ops, NULL);
- pxa_gpio_of_node = np;
return 0;
err:
iounmap(gpio_reg_base);
@@ -545,6 +504,56 @@ err:
#define pxa_gpio_probe_dt(pdev) (-1)
#endif
+static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
+ int (*set_wake)(unsigned int, unsigned int))
+{
+ int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
+ struct pxa_gpio_chip *chips;
+
+ chips = devm_kzalloc(&pdev->dev, nbanks * sizeof(*chips), GFP_KERNEL);
+ if (chips == NULL) {
+ pr_err("%s: failed to allocate GPIO chips\n", __func__);
+ return -ENOMEM;
+ }
+
+ for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
+ struct gpio_chip *c = &chips[i].chip;
+
+ sprintf(chips[i].label, "gpio-%d", i);
+ chips[i].regbase = gpio_reg_base + BANK_OFF(i);
+ chips[i].set_wake = set_wake;
+
+ c->base = gpio;
+ c->label = chips[i].label;
+
+ c->direction_input = pxa_gpio_direction_input;
+ c->direction_output = pxa_gpio_direction_output;
+ c->get = pxa_gpio_get;
+ c->set = pxa_gpio_set;
+ c->to_irq = pxa_gpio_to_irq;
+#ifdef CONFIG_OF_GPIO
+ c->of_node = pxa_gpio_of_node;
+ c->of_xlate = pxa_gpio_of_xlate;
+ c->of_gpio_n_cells = 2;
+#endif
+
+ /* number of GPIOs on last bank may be less than 32 */
+ c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
+
+ chips[i].irq_base = irq_alloc_descs(-1, 0, c->ngpio, 0);
+ if (chips[i].irq_base < 0)
+ return -EINVAL;
+ if (!irq_domain_add_legacy(pdev->dev.of_node, c->ngpio,
+ chips[i].irq_base, 0,
+ &pxa_irq_domain_ops, &chips[i]))
+ return -ENODEV;
+
+ gpiochip_add(c);
+ }
+ pxa_gpio_chips = chips;
+ return 0;
+}
+
static int pxa_gpio_probe(struct platform_device *pdev)
{
struct pxa_gpio_chip *c;
@@ -557,14 +566,6 @@ static int pxa_gpio_probe(struct platform_device *pdev)
ret = pxa_gpio_probe_dt(pdev);
if (ret < 0) {
pxa_last_gpio = pxa_gpio_nums();
-#ifdef CONFIG_ARCH_PXA
- if (gpio_is_pxa_type(gpio_type))
- irq_base = PXA_GPIO_TO_IRQ(0);
-#endif
-#ifdef CONFIG_ARCH_MMP
- if (gpio_is_mmp_type(gpio_type))
- irq_base = MMP_GPIO_TO_IRQ(0);
-#endif
} else {
use_of = 1;
}
@@ -604,7 +605,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
/* Initialize GPIO chips */
info = dev_get_platdata(&pdev->dev);
- pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);
+ pxa_init_gpio_chip(pdev, pxa_last_gpio,
+ info ? info->gpio_set_wake : NULL);
/* clear all GPIO edge detects */
for_each_gpio_chip(gpio, c) {
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index bc5cae5..49120b8 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -1,6 +1,8 @@
#ifndef __GPIO_PXA_H
#define __GPIO_PXA_H
+#include <linux/irq.h>
+
#define GPIO_bit(x) (1 << ((x) & 0x1f))
#define gpio_to_bank(gpio) ((gpio) >> 5)
@@ -11,7 +13,7 @@
*/
extern int pxa_last_gpio;
-extern int pxa_irq_to_gpio(int irq);
+extern int pxa_irq_to_gpio(struct irq_data *d);
struct pxa_gpio_platform_data {
bool ed_mask; /* true means that ed_mask reg is available */
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 03/10] gpio: pxa: use platform data for gpio inverted
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
Avoid to judge whether gpio is inverted by identifying cpu in gpio
driver. Move this into platform data of gpio driver.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
arch/arm/mach-pxa/pxa25x.c | 3 +++
drivers/gpio/gpio-pxa.c | 40 +++++++++++++++++++++++++---------------
include/linux/gpio-pxa.h | 1 +
3 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index f4c293a..66dafb7 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -340,6 +340,9 @@ void __init pxa25x_map_io(void)
}
static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
+#ifdef CONFIG_CPU_PXA26x
+ .inverted = true,
+#endif
.gpio_set_wake = gpio_set_wake,
};
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 2310665..1f8dfc8 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -71,6 +71,7 @@ struct pxa_gpio_chip {
struct gpio_chip chip;
void __iomem *regbase;
unsigned int irq_base;
+ bool inverted;
char label[10];
unsigned long irq_mask;
@@ -126,9 +127,9 @@ static inline int gpio_is_mmp_type(int type)
/* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted,
* as well as their Alternate Function value being '1' for GPIO in GAFRx.
*/
-static inline int __gpio_is_inverted(int gpio)
+static inline int __gpio_is_inverted(struct pxa_gpio_chip *chip, int gpio)
{
- if ((gpio_type == PXA26X_GPIO) && (gpio > 85))
+ if ((chip->inverted) && (gpio > 85))
return 1;
return 0;
}
@@ -139,15 +140,13 @@ static inline int __gpio_is_inverted(int gpio)
* is attributed as "occupied" here (I know this terminology isn't
* accurate, you are welcome to propose a better one :-)
*/
-static inline int __gpio_is_occupied(unsigned gpio)
+static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
{
- struct pxa_gpio_chip *pxachip;
void __iomem *base;
unsigned long gafr = 0, gpdr = 0;
int ret, af = 0, dir = 0;
- pxachip = gpio_to_pxachip(gpio);
- base = gpio_chip_base(&pxachip->chip);
+ base = gpio_chip_base(&chip->chip);
gpdr = readl_relaxed(base + GPDR_OFFSET);
switch (gpio_type) {
@@ -158,7 +157,7 @@ static inline int __gpio_is_occupied(unsigned gpio)
af = (gafr >> ((gpio & 0xf) * 2)) & 0x3;
dir = gpdr & GPIO_bit(gpio);
- if (__gpio_is_inverted(gpio))
+ if (__gpio_is_inverted(chip, gpio))
ret = (af != 1) || (dir == 0);
else
ret = (af != 0) || (dir != 0);
@@ -188,16 +187,19 @@ int pxa_irq_to_gpio(struct irq_data *d)
return gpio;
}
-static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+static int pxa_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{
- void __iomem *base = gpio_chip_base(chip);
+ struct pxa_gpio_chip *chip = NULL;
+ void __iomem *base = gpio_chip_base(gc);
uint32_t value, mask = 1 << offset;
unsigned long flags;
+ chip = container_of(gc, struct pxa_gpio_chip, chip);
+
spin_lock_irqsave(&gpio_lock, flags);
value = readl_relaxed(base + GPDR_OFFSET);
- if (__gpio_is_inverted(chip->base + offset))
+ if (__gpio_is_inverted(chip, gc->base + offset))
value |= mask;
else
value &= ~mask;
@@ -207,19 +209,22 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
return 0;
}
-static int pxa_gpio_direction_output(struct gpio_chip *chip,
+static int pxa_gpio_direction_output(struct gpio_chip *gc,
unsigned offset, int value)
{
- void __iomem *base = gpio_chip_base(chip);
+ struct pxa_gpio_chip *chip = NULL;
+ void __iomem *base = gpio_chip_base(gc);
uint32_t tmp, mask = 1 << offset;
unsigned long flags;
+ chip = container_of(gc, struct pxa_gpio_chip, chip);
+
writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET));
spin_lock_irqsave(&gpio_lock, flags);
tmp = readl_relaxed(base + GPDR_OFFSET);
- if (__gpio_is_inverted(chip->base + offset))
+ if (__gpio_is_inverted(chip, gc->base + offset))
tmp &= ~mask;
else
tmp |= mask;
@@ -288,7 +293,7 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio))
return 0;
- if (__gpio_is_occupied(gpio))
+ if (__gpio_is_occupied(c, gpio))
return 0;
type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
@@ -296,7 +301,7 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
gpdr = readl_relaxed(c->regbase + GPDR_OFFSET);
- if (__gpio_is_inverted(gpio))
+ if (__gpio_is_inverted(c, gpio))
writel_relaxed(gpdr | mask, c->regbase + GPDR_OFFSET);
else
writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET);
@@ -474,6 +479,9 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
return -ENOMEM;
if (of_find_property(np, "marvell,gpio-ed-mask", NULL))
pdata->ed_mask = true;
+ /* It's only valid for PXA26x */
+ if (of_find_property(np, "marvell,gpio-inverted", NULL))
+ pdata->inverted = true;
/* set the platform data */
pdev->dev.platform_data = pdata;
gpio_type = (int)of_id->data;
@@ -616,6 +624,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
/* unmask GPIO edge detect for AP side */
if (info->ed_mask)
writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
+ /* update for gpio inverted */
+ c->inverted = info->inverted;
}
if (!use_of) {
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index 49120b8..0c212a1 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -17,6 +17,7 @@ extern int pxa_irq_to_gpio(struct irq_data *d);
struct pxa_gpio_platform_data {
bool ed_mask; /* true means that ed_mask reg is available */
+ bool inverted; /* only valid for PXA26x */
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 04/10] gpio: pxa: remove gpio_type
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
Since gpio_type is used to check whether gafr register is valid. So
move it into platform data.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
arch/arm/mach-pxa/pxa25x.c | 1 +
arch/arm/mach-pxa/pxa27x.c | 1 +
drivers/gpio/gpio-pxa.c | 43 ++++++-------------------------------------
include/linux/gpio-pxa.h | 1 +
4 files changed, 9 insertions(+), 37 deletions(-)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 66dafb7..3460de1 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -343,6 +343,7 @@ static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
#ifdef CONFIG_CPU_PXA26x
.inverted = true,
#endif
+ .gafr = true,
.gpio_set_wake = gpio_set_wake,
};
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 67f5fd2..999d681 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -430,6 +430,7 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
}
static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
+ .gafr = true,
.gpio_set_wake = gpio_set_wake,
};
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 1f8dfc8..6c6e21c 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -72,6 +72,7 @@ struct pxa_gpio_chip {
void __iomem *regbase;
unsigned int irq_base;
bool inverted;
+ bool gafr;
char label[10];
unsigned long irq_mask;
@@ -87,18 +88,8 @@ struct pxa_gpio_chip {
#endif
};
-enum {
- PXA25X_GPIO = 0,
- PXA26X_GPIO,
- PXA27X_GPIO,
- PXA3XX_GPIO,
- PXA93X_GPIO,
- MMP_GPIO = 0x10,
-};
-
static DEFINE_SPINLOCK(gpio_lock);
static struct pxa_gpio_chip *pxa_gpio_chips;
-static int gpio_type;
static void __iomem *gpio_reg_base;
#define for_each_gpio_chip(i, c) \
@@ -114,16 +105,6 @@ static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio)
return &pxa_gpio_chips[gpio_to_bank(gpio)];
}
-static inline int gpio_is_pxa_type(int type)
-{
- return (type & MMP_GPIO) == 0;
-}
-
-static inline int gpio_is_mmp_type(int type)
-{
- return (type & MMP_GPIO) != 0;
-}
-
/* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted,
* as well as their Alternate Function value being '1' for GPIO in GAFRx.
*/
@@ -149,10 +130,7 @@ static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
base = gpio_chip_base(&chip->chip);
gpdr = readl_relaxed(base + GPDR_OFFSET);
- switch (gpio_type) {
- case PXA25X_GPIO:
- case PXA26X_GPIO:
- case PXA27X_GPIO:
+ if (chip->gafr) {
gafr = readl_relaxed(base + GAFR_OFFSET);
af = (gafr >> ((gpio & 0xf) * 2)) & 0x3;
dir = gpdr & GPIO_bit(gpio);
@@ -161,10 +139,8 @@ static inline int __gpio_is_occupied(struct pxa_gpio_chip *chip, unsigned gpio)
ret = (af != 1) || (dir == 0);
else
ret = (af != 0) || (dir != 0);
- break;
- default:
+ } else {
ret = gpdr & GPIO_bit(gpio);
- break;
}
return ret;
}
@@ -412,30 +388,23 @@ static int pxa_gpio_nums(void)
if (cpu_is_pxa25x()) {
#ifdef CONFIG_CPU_PXA26x
count = 89;
- gpio_type = PXA26X_GPIO;
#elif defined(CONFIG_PXA25x)
count = 84;
- gpio_type = PXA26X_GPIO;
#endif /* CONFIG_CPU_PXA26x */
} else if (cpu_is_pxa27x()) {
count = 120;
- gpio_type = PXA27X_GPIO;
} else if (cpu_is_pxa93x()) {
count = 191;
- gpio_type = PXA93X_GPIO;
} else if (cpu_is_pxa3xx()) {
count = 127;
- gpio_type = PXA3XX_GPIO;
}
#endif /* CONFIG_ARCH_PXA */
#ifdef CONFIG_ARCH_MMP
if (cpu_is_pxa168() || cpu_is_pxa910()) {
count = 127;
- gpio_type = MMP_GPIO;
} else if (cpu_is_mmp2()) {
count = 191;
- gpio_type = MMP_GPIO;
}
#endif /* CONFIG_ARCH_MMP */
return count;
@@ -458,7 +427,7 @@ static const struct irq_domain_ops pxa_irq_domain_ops = {
#ifdef CONFIG_OF
static struct of_device_id pxa_gpio_dt_ids[] = {
{ .compatible = "mrvl,pxa-gpio" },
- { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
+ { .compatible = "mrvl,mmp-gpio" },
{}
};
@@ -484,7 +453,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
pdata->inverted = true;
/* set the platform data */
pdev->dev.platform_data = pdata;
- gpio_type = (int)of_id->data;
next = of_get_next_child(np, NULL);
prev = next;
@@ -624,8 +592,9 @@ static int pxa_gpio_probe(struct platform_device *pdev)
/* unmask GPIO edge detect for AP side */
if (info->ed_mask)
writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
- /* update for gpio inverted */
+ /* update for gpio inverted & gafr */
c->inverted = info->inverted;
+ c->gafr = info->gafr;
}
if (!use_of) {
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index 0c212a1..80e0322 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -18,6 +18,7 @@ extern int pxa_irq_to_gpio(struct irq_data *d);
struct pxa_gpio_platform_data {
bool ed_mask; /* true means that ed_mask reg is available */
bool inverted; /* only valid for PXA26x */
+ bool gafr; /* only valid for PXA25x/PXA26x/PXA27x */
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 05/10] gpio: pxa: define nr gpios in platform data
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
Avoid to define gpio numbers in gpio driver. Define it in platform data
instead.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
arch/arm/mach-mmp/aspenite.c | 1 +
arch/arm/mach-mmp/avengers_lite.c | 1 +
arch/arm/mach-mmp/brownstone.c | 1 +
arch/arm/mach-mmp/flint.c | 1 +
arch/arm/mach-mmp/gplugd.c | 1 +
arch/arm/mach-mmp/tavorevb.c | 1 +
arch/arm/mach-mmp/teton_bga.c | 1 +
arch/arm/mach-mmp/ttc_dkb.c | 1 +
arch/arm/mach-pxa/pxa25x.c | 3 +++
arch/arm/mach-pxa/pxa27x.c | 1 +
arch/arm/mach-pxa/pxa3xx.c | 15 +++++++++++-
drivers/gpio/gpio-pxa.c | 48 +++++++------------------------------
include/linux/gpio-pxa.h | 1 +
13 files changed, 35 insertions(+), 41 deletions(-)
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 36f5781..a3e42dc 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -112,6 +112,7 @@ static unsigned long common_pin_config[] __initdata = {
};
static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .nr_gpios = 128,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index b8fe447..1ea6502 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -34,6 +34,7 @@ static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
};
static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .nr_gpios = 128,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index d6ea5c4..a32156f 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -106,6 +106,7 @@ static unsigned long brownstone_pin_config[] __initdata = {
};
static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+ .nr_gpios = 192,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 0955f44..3f301b5 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -79,6 +79,7 @@ static unsigned long flint_pin_config[] __initdata = {
};
static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+ .nr_gpios = 192,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 2315cce..019b178 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -129,6 +129,7 @@ static unsigned long gplugd_pin_config[] __initdata = {
};
static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .nr_gpios = 128,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index eaec649..6e8cf80 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -62,6 +62,7 @@ static unsigned long tavorevb_pin_config[] __initdata = {
};
static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+ .nr_gpios = 128,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 6682100..b5146bb 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -51,6 +51,7 @@ static unsigned long teton_bga_pin_config[] __initdata = {
};
static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .nr_gpios = 128,
.ed_mask = true,
};
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 984d902..123a0bf 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -75,6 +75,7 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
};
static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+ .nr_gpios = 128,
.ed_mask = true,
};
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 3460de1..ff91660 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -342,6 +342,9 @@ void __init pxa25x_map_io(void)
static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
#ifdef CONFIG_CPU_PXA26x
.inverted = true,
+ .nr_gpios = 90,
+#else
+ .nr_gpios = 85,
#endif
.gafr = true,
.gpio_set_wake = gpio_set_wake,
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 999d681..4de9572 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -431,6 +431,7 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
.gafr = true,
+ .nr_gpios = 121,
.gpio_set_wake = gpio_set_wake,
};
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 656a1bb..a0cc797 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -435,6 +435,10 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
pxa_register_device(&pxa3xx_device_i2c_power, info);
}
+static struct pxa_gpio_platform_data pxa3xx_gpio_info __initdata = {
+ .nr_gpios = 128,
+};
+
static struct platform_device *devices[] __initdata = {
&pxa_device_gpio,
&pxa27x_device_udc,
@@ -482,8 +486,17 @@ static int __init pxa3xx_init(void)
register_syscore_ops(&pxa3xx_mfp_syscore_ops);
register_syscore_ops(&pxa3xx_clock_syscore_ops);
- if (!of_have_populated_dt())
+ if (!of_have_populated_dt()) {
+ if (cpu_is_pxa93x())
+ pxa3xx_gpio_info.nr_gpios = 192;
+ ret = platform_device_add_data(&pxa_device_gpio,
+ &pxa3xx_gpio_info,
+ sizeof(struct pxa_gpio_platform_data);
+ if (ret < 0)
+ break;
+
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
}
return ret;
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 6c6e21c..8fbf4c6 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -380,36 +380,6 @@ static struct irq_chip pxa_muxed_gpio_chip = {
.irq_set_wake = pxa_gpio_set_wake,
};
-static int pxa_gpio_nums(void)
-{
- int count = 0;
-
-#ifdef CONFIG_ARCH_PXA
- if (cpu_is_pxa25x()) {
-#ifdef CONFIG_CPU_PXA26x
- count = 89;
-#elif defined(CONFIG_PXA25x)
- count = 84;
-#endif /* CONFIG_CPU_PXA26x */
- } else if (cpu_is_pxa27x()) {
- count = 120;
- } else if (cpu_is_pxa93x()) {
- count = 191;
- } else if (cpu_is_pxa3xx()) {
- count = 127;
- }
-#endif /* CONFIG_ARCH_PXA */
-
-#ifdef CONFIG_ARCH_MMP
- if (cpu_is_pxa168() || cpu_is_pxa910()) {
- count = 127;
- } else if (cpu_is_mmp2()) {
- count = 191;
- }
-#endif /* CONFIG_ARCH_MMP */
- return count;
-}
-
static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
@@ -433,7 +403,7 @@ static struct of_device_id pxa_gpio_dt_ids[] = {
static int pxa_gpio_probe_dt(struct platform_device *pdev)
{
- int ret, nr_banks, nr_gpios;
+ int ret, nr_banks;
struct pxa_gpio_platform_data *pdata;
struct device_node *prev, *next, *np = pdev->dev.of_node;
const struct of_device_id *of_id =
@@ -451,6 +421,11 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
/* It's only valid for PXA26x */
if (of_find_property(np, "marvell,gpio-inverted", NULL))
pdata->inverted = true;
+ ret = of_property_read_u32(np, "marvell,nr-gpios", &pdata->nr_gpios);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "nr-gpios isn't specified\n");
+ return -ENOTSUPP;
+ }
/* set the platform data */
pdev->dev.platform_data = pdata;
@@ -468,8 +443,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
prev = next;
}
of_node_put(prev);
- nr_gpios = nr_banks << 5;
- pxa_last_gpio = nr_gpios - 1;
return 0;
err:
@@ -540,14 +513,8 @@ static int pxa_gpio_probe(struct platform_device *pdev)
int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
ret = pxa_gpio_probe_dt(pdev);
- if (ret < 0) {
- pxa_last_gpio = pxa_gpio_nums();
- } else {
+ if (!ret)
use_of = 1;
- }
-
- if (!pxa_last_gpio)
- return -EINVAL;
irq0 = platform_get_irq_byname(pdev, "gpio0");
irq1 = platform_get_irq_byname(pdev, "gpio1");
@@ -581,6 +548,7 @@ static int pxa_gpio_probe(struct platform_device *pdev)
/* Initialize GPIO chips */
info = dev_get_platdata(&pdev->dev);
+ pxa_last_gpio = info->nr_gpios - 1;
pxa_init_gpio_chip(pdev, pxa_last_gpio,
info ? info->gpio_set_wake : NULL);
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index 80e0322..b357fdc 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -19,6 +19,7 @@ struct pxa_gpio_platform_data {
bool ed_mask; /* true means that ed_mask reg is available */
bool inverted; /* only valid for PXA26x */
bool gafr; /* only valid for PXA25x/PXA26x/PXA27x */
+ unsigned nr_gpios;
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 06/10] gpio: pxa: clean code for compatible name
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
Use compatible variable name in gpio pxa driver.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
drivers/gpio/gpio-pxa.c | 194 ++++++++++++++++++++++++-----------------------
1 file changed, 98 insertions(+), 96 deletions(-)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 8fbf4c6..95561d6 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -95,9 +95,9 @@ static void __iomem *gpio_reg_base;
#define for_each_gpio_chip(i, c) \
for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
-static inline void __iomem *gpio_chip_base(struct gpio_chip *c)
+static inline void __iomem *gpio_chip_base(struct gpio_chip *gc)
{
- return container_of(c, struct pxa_gpio_chip, chip)->regbase;
+ return container_of(gc, struct pxa_gpio_chip, chip)->regbase;
}
static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio)
@@ -210,14 +210,14 @@ static int pxa_gpio_direction_output(struct gpio_chip *gc,
return 0;
}
-static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
+static int pxa_gpio_get(struct gpio_chip *gc, unsigned offset)
{
- return readl_relaxed(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset);
+ return readl_relaxed(gpio_chip_base(gc) + GPLR_OFFSET) & (1 << offset);
}
-static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+static void pxa_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
{
- writel_relaxed(1 << offset, gpio_chip_base(chip) +
+ writel_relaxed(1 << offset, gpio_chip_base(gc) +
(value ? GPSR_OFFSET : GPCR_OFFSET));
}
@@ -242,57 +242,58 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
/* Update only those GRERx and GFERx edge detection register bits if those
* bits are set in c->irq_mask
*/
-static inline void update_edge_detect(struct pxa_gpio_chip *c)
+static inline void update_edge_detect(struct pxa_gpio_chip *chip)
{
uint32_t grer, gfer;
- grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~c->irq_mask;
- gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~c->irq_mask;
- grer |= c->irq_edge_rise & c->irq_mask;
- gfer |= c->irq_edge_fall & c->irq_mask;
- writel_relaxed(grer, c->regbase + GRER_OFFSET);
- writel_relaxed(gfer, c->regbase + GFER_OFFSET);
+ grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~chip->irq_mask;
+ gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~chip->irq_mask;
+ grer |= chip->irq_edge_rise & chip->irq_mask;
+ gfer |= chip->irq_edge_fall & chip->irq_mask;
+ writel_relaxed(grer, chip->regbase + GRER_OFFSET);
+ writel_relaxed(gfer, chip->regbase + GFER_OFFSET);
}
static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
{
- struct pxa_gpio_chip *c;
+ struct pxa_gpio_chip *chip;
int gpio = pxa_irq_to_gpio(d);
unsigned long gpdr, mask = GPIO_bit(gpio);
- c = gpio_to_pxachip(gpio);
+ chip = gpio_to_pxachip(gpio);
if (type == IRQ_TYPE_PROBE) {
/* Don't mess with enabled GPIOs using preconfigured edges or
* GPIOs set to alternate function or to output during probe
*/
- if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio))
+ if ((chip->irq_edge_rise | chip->irq_edge_fall)
+ & GPIO_bit(gpio))
return 0;
- if (__gpio_is_occupied(c, gpio))
+ if (__gpio_is_occupied(chip, gpio))
return 0;
type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
}
- gpdr = readl_relaxed(c->regbase + GPDR_OFFSET);
+ gpdr = readl_relaxed(chip->regbase + GPDR_OFFSET);
- if (__gpio_is_inverted(c, gpio))
- writel_relaxed(gpdr | mask, c->regbase + GPDR_OFFSET);
+ if (__gpio_is_inverted(chip, gpio))
+ writel_relaxed(gpdr | mask, chip->regbase + GPDR_OFFSET);
else
- writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET);
+ writel_relaxed(gpdr & ~mask, chip->regbase + GPDR_OFFSET);
if (type & IRQ_TYPE_EDGE_RISING)
- c->irq_edge_rise |= mask;
+ chip->irq_edge_rise |= mask;
else
- c->irq_edge_rise &= ~mask;
+ chip->irq_edge_rise &= ~mask;
if (type & IRQ_TYPE_EDGE_FALLING)
- c->irq_edge_fall |= mask;
+ chip->irq_edge_fall |= mask;
else
- c->irq_edge_fall &= ~mask;
+ chip->irq_edge_fall &= ~mask;
- update_edge_detect(c);
+ update_edge_detect(chip);
pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, d->irq, gpio,
((type & IRQ_TYPE_EDGE_RISING) ? " rising" : ""),
@@ -302,21 +303,21 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
{
- struct pxa_gpio_chip *c;
+ struct pxa_gpio_chip *chip;
int loop, gpio, gpio_base, n;
unsigned long gedr;
- struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct irq_chip *ic = irq_desc_get_chip(desc);
- chained_irq_enter(chip, desc);
+ chained_irq_enter(ic, desc);
do {
loop = 0;
- for_each_gpio_chip(gpio, c) {
- gpio_base = c->chip.base;
+ for_each_gpio_chip(gpio, chip) {
+ gpio_base = chip->chip.base;
- gedr = readl_relaxed(c->regbase + GEDR_OFFSET);
- gedr = gedr & c->irq_mask;
- writel_relaxed(gedr, c->regbase + GEDR_OFFSET);
+ gedr = readl_relaxed(chip->regbase + GEDR_OFFSET);
+ gedr = gedr & chip->irq_mask;
+ writel_relaxed(gedr, chip->regbase + GEDR_OFFSET);
for_each_set_bit(n, &gedr, BITS_PER_LONG) {
loop = 1;
@@ -326,38 +327,38 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
}
} while (loop);
- chained_irq_exit(chip, desc);
+ chained_irq_exit(ic, desc);
}
static void pxa_ack_muxed_gpio(struct irq_data *d)
{
int gpio = pxa_irq_to_gpio(d);
- struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+ struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
- writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
+ writel_relaxed(GPIO_bit(gpio), chip->regbase + GEDR_OFFSET);
}
static void pxa_mask_muxed_gpio(struct irq_data *d)
{
int gpio = pxa_irq_to_gpio(d);
- struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+ struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
uint32_t grer, gfer;
- c->irq_mask &= ~GPIO_bit(gpio);
+ chip->irq_mask &= ~GPIO_bit(gpio);
- grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
- gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
- writel_relaxed(grer, c->regbase + GRER_OFFSET);
- writel_relaxed(gfer, c->regbase + GFER_OFFSET);
+ grer = readl_relaxed(chip->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
+ gfer = readl_relaxed(chip->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
+ writel_relaxed(grer, chip->regbase + GRER_OFFSET);
+ writel_relaxed(gfer, chip->regbase + GFER_OFFSET);
}
static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
{
int gpio = pxa_irq_to_gpio(d);
- struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+ struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
- if (c->set_wake)
- return c->set_wake(gpio, on);
+ if (chip->set_wake)
+ return chip->set_wake(gpio, on);
else
return 0;
}
@@ -365,10 +366,10 @@ static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
static void pxa_unmask_muxed_gpio(struct irq_data *d)
{
int gpio = pxa_irq_to_gpio(d);
- struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+ struct pxa_gpio_chip *chip = gpio_to_pxachip(gpio);
- c->irq_mask |= GPIO_bit(gpio);
- update_edge_detect(c);
+ chip->irq_mask |= GPIO_bit(gpio);
+ update_edge_detect(chip);
}
static struct irq_chip pxa_muxed_gpio_chip = {
@@ -466,38 +467,37 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
}
for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
- struct gpio_chip *c = &chips[i].chip;
+ struct gpio_chip *gc = &chips[i].chip;
sprintf(chips[i].label, "gpio-%d", i);
chips[i].regbase = gpio_reg_base + BANK_OFF(i);
chips[i].set_wake = set_wake;
- c->base = gpio;
- c->label = chips[i].label;
-
- c->direction_input = pxa_gpio_direction_input;
- c->direction_output = pxa_gpio_direction_output;
- c->get = pxa_gpio_get;
- c->set = pxa_gpio_set;
- c->to_irq = pxa_gpio_to_irq;
-#ifdef CONFIG_OF_GPIO
- c->of_node = pxa_gpio_of_node;
- c->of_xlate = pxa_gpio_of_xlate;
- c->of_gpio_n_cells = 2;
-#endif
-
/* number of GPIOs on last bank may be less than 32 */
- c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
+ gc->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
- chips[i].irq_base = irq_alloc_descs(-1, 0, c->ngpio, 0);
+ chips[i].irq_base = irq_alloc_descs(-1, 0, gc->ngpio, 0);
if (chips[i].irq_base < 0)
return -EINVAL;
- if (!irq_domain_add_legacy(pdev->dev.of_node, c->ngpio,
+ if (!irq_domain_add_legacy(pdev->dev.of_node, gc->ngpio,
chips[i].irq_base, 0,
&pxa_irq_domain_ops, &chips[i]))
return -ENODEV;
- gpiochip_add(c);
+ gc->base = gpio;
+ gc->label = chips[i].label;
+
+ gc->direction_input = pxa_gpio_direction_input;
+ gc->direction_output = pxa_gpio_direction_output;
+ gc->get = pxa_gpio_get;
+ gc->set = pxa_gpio_set;
+ gc->to_irq = pxa_gpio_to_irq;
+#ifdef CONFIG_OF_GPIO
+ gc->of_node = pxa_gpio_of_node;
+ gc->of_xlate = pxa_gpio_of_xlate;
+ gc->of_gpio_n_cells = 2;
+#endif
+ gpiochip_add(gc);
}
pxa_gpio_chips = chips;
return 0;
@@ -505,10 +505,10 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
static int pxa_gpio_probe(struct platform_device *pdev)
{
- struct pxa_gpio_chip *c;
+ struct pxa_gpio_chip *chip;
struct resource *res;
struct clk *clk;
- struct pxa_gpio_platform_data *info;
+ struct pxa_gpio_platform_data *pdata;
int gpio, irq, ret, use_of = 0;
int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
@@ -547,22 +547,24 @@ static int pxa_gpio_probe(struct platform_device *pdev)
}
/* Initialize GPIO chips */
- info = dev_get_platdata(&pdev->dev);
- pxa_last_gpio = info->nr_gpios - 1;
- pxa_init_gpio_chip(pdev, pxa_last_gpio,
- info ? info->gpio_set_wake : NULL);
+ pdata = dev_get_platdata(&pdev->dev);
+ pxa_last_gpio = pdata->nr_gpios - 1;
+ ret = pxa_init_gpio_chip(pdev, pxa_last_gpio,
+ pdata ? pdata->gpio_set_wake : NULL);
+ if (ret < 0)
+ return ret;
/* clear all GPIO edge detects */
- for_each_gpio_chip(gpio, c) {
- writel_relaxed(0, c->regbase + GFER_OFFSET);
- writel_relaxed(0, c->regbase + GRER_OFFSET);
- writel_relaxed(~0,c->regbase + GEDR_OFFSET);
+ for_each_gpio_chip(gpio, chip) {
+ writel_relaxed(0, chip->regbase + GFER_OFFSET);
+ writel_relaxed(0, chip->regbase + GRER_OFFSET);
+ writel_relaxed(~0,chip->regbase + GEDR_OFFSET);
/* unmask GPIO edge detect for AP side */
- if (info->ed_mask)
- writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
+ if (pdata->ed_mask)
+ writel_relaxed(~0, chip->regbase + ED_MASK_OFFSET);
/* update for gpio inverted & gafr */
- c->inverted = info->inverted;
- c->gafr = info->gafr;
+ chip->inverted = pdata->inverted;
+ chip->gafr = pdata->gafr;
}
if (!use_of) {
@@ -604,34 +606,34 @@ module_platform_driver(pxa_gpio_driver);
#ifdef CONFIG_PM
static int pxa_gpio_suspend(void)
{
- struct pxa_gpio_chip *c;
+ struct pxa_gpio_chip *chip;
int gpio;
- for_each_gpio_chip(gpio, c) {
- c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET);
- c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET);
- c->saved_grer = readl_relaxed(c->regbase + GRER_OFFSET);
- c->saved_gfer = readl_relaxed(c->regbase + GFER_OFFSET);
+ for_each_gpio_chip(gpio, chip) {
+ chip->saved_gplr = readl_relaxed(chip->regbase + GPLR_OFFSET);
+ chip->saved_gpdr = readl_relaxed(chip->regbase + GPDR_OFFSET);
+ chip->saved_grer = readl_relaxed(chip->regbase + GRER_OFFSET);
+ chip->saved_gfer = readl_relaxed(chip->regbase + GFER_OFFSET);
/* Clear GPIO transition detect bits */
- writel_relaxed(0xffffffff, c->regbase + GEDR_OFFSET);
+ writel_relaxed(~0, chip->regbase + GEDR_OFFSET);
}
return 0;
}
static void pxa_gpio_resume(void)
{
- struct pxa_gpio_chip *c;
+ struct pxa_gpio_chip *chip;
int gpio;
- for_each_gpio_chip(gpio, c) {
+ for_each_gpio_chip(gpio, chip) {
/* restore level with set/clear */
- writel_relaxed( c->saved_gplr, c->regbase + GPSR_OFFSET);
- writel_relaxed(~c->saved_gplr, c->regbase + GPCR_OFFSET);
+ writel_relaxed( chip->saved_gplr, chip->regbase + GPSR_OFFSET);
+ writel_relaxed(~chip->saved_gplr, chip->regbase + GPCR_OFFSET);
- writel_relaxed(c->saved_grer, c->regbase + GRER_OFFSET);
- writel_relaxed(c->saved_gfer, c->regbase + GFER_OFFSET);
- writel_relaxed(c->saved_gpdr, c->regbase + GPDR_OFFSET);
+ writel_relaxed(chip->saved_grer, chip->regbase + GRER_OFFSET);
+ writel_relaxed(chip->saved_gfer, chip->regbase + GFER_OFFSET);
+ writel_relaxed(chip->saved_gpdr, chip->regbase + GPDR_OFFSET);
}
}
#else
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 07/10] gpio: pxa: remove arch related macro
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
Remove macro CONFIG_ARCH_PXA.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
drivers/gpio/gpio-pxa.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 95561d6..8130e3b 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -568,21 +568,21 @@ static int pxa_gpio_probe(struct platform_device *pdev)
}
if (!use_of) {
-#ifdef CONFIG_ARCH_PXA
- irq = gpio_to_irq(0);
- irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
- handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler);
-
- irq = gpio_to_irq(1);
- irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
- handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
-#endif
-
- for (irq = gpio_to_irq(gpio_offset);
+ if (irq0 > 0) {
+ irq = gpio_to_irq(0);
+ irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ irq_set_chained_handler(irq0, pxa_gpio_demux_handler);
+ }
+ if (irq1 > 0) {
+ irq = gpio_to_irq(1);
+ irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ irq_set_chained_handler(irq1, pxa_gpio_demux_handler);
+ }
+ for (irq = gpio_to_irq(gpio_offset);
irq <= gpio_to_irq(pxa_last_gpio); irq++) {
irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
handle_edge_irq);
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 08/10] gpio: pxa: move gpio properties into child node
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
Move gpio properties into child node. So pinctrl driver could binds to
each gpio chip with gpio range.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
drivers/gpio/gpio-pxa.c | 45 +++++++++++++++++----------------------------
1 file changed, 17 insertions(+), 28 deletions(-)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 8130e3b..5c39db3 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -63,10 +63,6 @@
int pxa_last_gpio;
-#ifdef CONFIG_OF
-static struct device_node *pxa_gpio_of_node;
-#endif
-
struct pxa_gpio_chip {
struct gpio_chip chip;
void __iomem *regbase;
@@ -404,9 +400,9 @@ static struct of_device_id pxa_gpio_dt_ids[] = {
static int pxa_gpio_probe_dt(struct platform_device *pdev)
{
- int ret, nr_banks;
+ int ret;
struct pxa_gpio_platform_data *pdata;
- struct device_node *prev, *next, *np = pdev->dev.of_node;
+ struct device_node *np = pdev->dev.of_node;
const struct of_device_id *of_id =
of_match_device(pxa_gpio_dt_ids, &pdev->dev);
@@ -430,25 +426,7 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
/* set the platform data */
pdev->dev.platform_data = pdata;
- next = of_get_next_child(np, NULL);
- prev = next;
- if (!next) {
- dev_err(&pdev->dev, "Failed to find child gpio node\n");
- ret = -EINVAL;
- goto err;
- }
- for (nr_banks = 1; ; nr_banks++) {
- next = of_get_next_child(np, prev);
- if (!next)
- break;
- prev = next;
- }
- of_node_put(prev);
-
return 0;
-err:
- iounmap(gpio_reg_base);
- return ret;
}
#else
#define pxa_gpio_probe_dt(pdev) (-1)
@@ -459,6 +437,7 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
{
int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
struct pxa_gpio_chip *chips;
+ struct device_node *next = NULL, *np = NULL;
chips = devm_kzalloc(&pdev->dev, nbanks * sizeof(*chips), GFP_KERNEL);
if (chips == NULL) {
@@ -466,6 +445,11 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
return -ENOMEM;
}
+ np = pdev->dev.of_node;
+#ifdef CONFIG_OF
+ if (np)
+ next = of_get_next_child(np, NULL);
+#endif
for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
struct gpio_chip *gc = &chips[i].chip;
@@ -492,13 +476,18 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
gc->get = pxa_gpio_get;
gc->set = pxa_gpio_set;
gc->to_irq = pxa_gpio_to_irq;
-#ifdef CONFIG_OF_GPIO
- gc->of_node = pxa_gpio_of_node;
- gc->of_xlate = pxa_gpio_of_xlate;
- gc->of_gpio_n_cells = 2;
+#ifdef CONFIG_OF
+ if (np) {
+ gc->of_node = next;
+ next = of_get_next_child(np, next);
+
+ gc->of_xlate = pxa_gpio_of_xlate;
+ gc->of_gpio_n_cells = 2;
+ }
#endif
gpiochip_add(gc);
}
+ of_node_put(next);
pxa_gpio_chips = chips;
return 0;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 09/10] gpio: pxa: bind to pinctrl by request
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
While gpio pins is requested, request the pin of pinctrl driver first.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
drivers/gpio/gpio-pxa.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 5c39db3..c9cc636 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -23,6 +23,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>
#include <linux/slab.h>
@@ -159,6 +160,23 @@ int pxa_irq_to_gpio(struct irq_data *d)
return gpio;
}
+static int pxa_gpio_request(struct gpio_chip *gc, unsigned offset)
+{
+ /*
+ * Map back to global GPIO space and request muxing, the direction
+ * parameter does not matter for this controller.
+ */
+ int gpio = gc->base + offset;
+
+ /*
+ * Platforms in ARCH_PXA doesn't move to device tree yet,
+ * and PINCTRL_SINGLE is depend on device tree.
+ */
+ if (IS_ENABLED(CONFIG_PINCTRL_SINGLE))
+ return pinctrl_request_gpio(gpio);
+ return 0;
+}
+
static int pxa_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{
struct pxa_gpio_chip *chip = NULL;
@@ -471,6 +489,7 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
gc->base = gpio;
gc->label = chips[i].label;
+ gc->request = pxa_gpio_request;
gc->direction_input = pxa_gpio_direction_input;
gc->direction_output = pxa_gpio_direction_output;
gc->get = pxa_gpio_get;
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 10/10] ARM: dts: support pinmux in pxa910
From: Haojian Zhuang @ 2013-02-03 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359886551-20950-1-git-send-email-haojian.zhuang@linaro.org>
Add gpio range, pinmux settings in pxa910 dkb DTS file.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
arch/arm/boot/dts/pxa910-dkb.dts | 264 ++++++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/pxa910.dtsi | 29 ++++-
2 files changed, 291 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index 595492a..72eb6bc 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -170,6 +170,270 @@
rtc: rtc at d4010000 {
status = "okay";
};
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ /* in6, out3, out4 */
+ right {
+ label = "right";
+ gpios = <&gcb0 12 0>;
+ linux,code = <106>; /* KEY_RIGHT */
+ };
+ num5 {
+ label = "5";
+ gpios = <&gcb0 4 0>;
+ linux,code = <6>; /* KEY_5 */
+ };
+ };
+ gpio at d4019000 {
+ status = "okay";
+
+ /*
+ * In theorical, some gpios could be routed to
+ * multiple pins. So define the gpio-ranges in
+ * board file, not silicon file.
+ */
+ gcb0: gpio at d4019000 {
+ /* <gpio_offset, pin_offset, nr_pins> */
+ gpio-ranges = <&pmx 0 55 32>;
+ };
+ gcb1: gpio at d4019004 {
+ /* <gpio_offset, pin_offset, nr_pins> */
+ gpio-ranges = <&pmx 0 87 23 &pmx 23 188 9>;
+ };
+ gcb2: gpio at d4019008 {
+ /* <gpio_offset, pin_offset, nr_pins> */
+ gpio-ranges = <&pmx 0 197 3 &pmx 3 110 29>;
+ };
+ gcb3: gpio at d4019100 {
+ /* <gpio_offset, pin_offset, nr_pins> */
+ gpio-ranges = < &pmx 0 139 14 &pmx 14 166 7
+ &pmx 21 45 4 &pmx 25 203 1
+ &pmx 26 50 4 &pmx 30 27 2>;
+ };
+ };
+ pmx: pinmux at d401e000 {
+ /* pin base, nr pins & gpio function */
+ pinctrl-single,gpio-range = <
+ /*
+ * GPIO number is hardcoded for range@here.
+ * In gpio chip, GPIO number is not hardcoded for range.
+ * Since one gpio pin may be routed to multiple pins,
+ * define these gpio range in pxa910-dkb.dts not pxa910.dtsi.
+ */
+ &range 55 55 0 /* GPIO0 ~ GPIO54 */
+ &range 188 5 1 /* GPIO55 ~ GPIO59 */
+ &range 193 7 0 /* GPIO60 ~ GPIO66 */
+ &range 110 43 0 /* GPIO67 ~ GPIO109 */
+ &range 166 7 0 /* GPIO110 ~ GPIO116 */
+ &range 45 4 0 /* GPIO117 ~ GPIO120 */
+ &range 50 2 1 /* GPIO122 ~ GPIO123 */
+ &range 203 1 0 /* GPIO121 */
+ &range 52 1 0 /* GPIO124 */
+ &range 53 1 1 /* GPIO125 */
+ &range 27 2 0 /* GPIO126 ~ GPIO127 */
+ >;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&keypad_pmx_func>;
+
+ uart1_pmx_func: pinmux_uart1_pins at 0 {
+ pinctrl-single,pins = <
+ 0x198 0x6 /* GPIO47_UART1_RXD */
+ 0x19c 0x6 /* GPIO48_UART1_TXD */
+ >;
+ /* slew rate set value, mask */
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ /* bias set value, match, mask */
+ pinctrl-single,bias-disable = <0x8000 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x4000 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ /* input schmitt set value, mask */
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ /* input schmitt disable value, match, mask */
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ uart2_pmx_func: pinmux_uart2_pins at 0 {
+ pinctrl-single,pins = <
+ 0x150 0x4 /* GPIO29_UART2_CTS */
+ 0x154 0x4 /* GPIO30_UART2_RTS */
+ 0x158 0x4 /* GPIO31_UART2_TXD */
+ 0x15c 0x4 /* GPIO32_UART2_RXD */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ uart3_pmx_func: pinmux_uart3_pins at 0 {
+ pinctrl-single,pins = <
+ 0x188 0x7 /* GPIO43_UART3_RXD */
+ 0x18c 0x7 /* GPIO44_UART3_TXD */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ twsi1_pmx_func: pinmux_twsi1_pins at 0 {
+ pinctrl-single,pins = <
+ 0x1b0 0x2 /* GPIO53_TWSI_SCL */
+ 0x1b4 0x2 /* GPIO54_TWSI_SDA */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ nand_pmx_func: pinmux_nand_pins at 0 {
+ pinctrl-single,pins = <
+ 0x040 0x0 /* ND_IO0 */
+ 0x03c 0x0 /* ND_IO1 */
+ 0x038 0x0 /* ND_IO2 */
+ 0x034 0x0 /* ND_IO3 */
+ 0x030 0x0 /* ND_IO4 */
+ 0x02c 0x0 /* ND_IO5 */
+ 0x028 0x0 /* ND_IO6 */
+ 0x024 0x0 /* ND_IO7 */
+ 0x020 0x0 /* ND_IO8 */
+ 0x01c 0x0 /* ND_IO9 */
+ 0x018 0x0 /* ND_IO10 */
+ 0x014 0x0 /* ND_IO11 */
+ 0x010 0x0 /* ND_IO12 */
+ 0x00c 0x0 /* ND_IO13 */
+ 0x008 0x0 /* ND_IO14 */
+ 0x004 0x0 /* ND_IO15 */
+ 0x044 0x0 /* ND_nCS0 */
+ 0x060 0x1 /* ND_ALE */
+ 0x05c 0x0 /* ND_CLE */
+ 0x054 0x1 /* ND_nWE */
+ 0x058 0x1 /* ND_nRE */
+ 0x068 0x0 /* ND_RDY0 */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ mmc1_pmx_func1: pinmux_mmc1_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0a0 0x0 /* MMC1_DATA0 */
+ 0x09c 0x0 /* MMC1_DATA1 */
+ 0x098 0x0 /* MMC1_DATA2 */
+ 0x094 0x0 /* MMC1_DATA3 */
+ 0x090 0x0 /* MMC1_DATA4 */
+ 0x08c 0x0 /* MMC1_DATA5 */
+ 0x088 0x0 /* MMC1_DATA6 */
+ 0x084 0x0 /* MMC1_DATA7 */
+ 0x0a4 0x0 /* MMC1_CMD */
+ 0x0a8 0x0 /* MMC1_CLK */
+ >;
+ pinctrl-single,slew-rate = <0x1800 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ mmc1_pmx_func2: pinmux_mmc1_pins at 1 {
+ pinctrl-single,pins = <
+ 0x0ac 0x0 /* MMC1_CD */
+ 0x0b0 0x0 /* MMC1_WP */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ mmc2_pmx_func: pinmux_mmc2_pins at 0 {
+ pinctrl-single,pins = <
+ 0x180 0x1 /* MMC2_CMD */
+ 0x184 0x1 /* MMC2_CLK */
+ 0x17c 0x1 /* MMC2_DATA0 */
+ 0x178 0x1 /* MMC2_DATA1 */
+ 0x174 0x1 /* MMC2_DATA2 */
+ 0x170 0x1 /* MMC2_DATA3 */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ ssp1_pmx_func: pinmux_ssp1_pins at 0 {
+ pinctrl-single,pins = <
+ 0x130 0x1 /* GPIO21_SSP1_SCLK */
+ 0x134 0x1 /* GPIO22_SSP1_FRM */
+ 0x138 0x1 /* GPIO23_SSP1_TXD */
+ 0x13c 0x1 /* GPIO24_SSP1_RXD */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ keypad_pmx_func: pinmux_keypad_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0dc 0x1 /* GPIO0_MKIN0 */
+ 0x0e0 0x1 /* GPIO1_MKOUT0 */
+ 0x0e4 0x1 /* GPIO2_MKIN1 */
+ 0x0e8 0x1 /* GPIO3_MKOUT1 */
+ 0x0ec 0x1 /* GPIO4_MKIN2 */
+ 0x0f0 0x1 /* GPIO5_MKOUT2 */
+ 0x0f4 0x1 /* GPIO6_MKIN3 */
+ 0x0f8 0x1 /* GPIO7_MKOUT3 */
+ 0x0fc 0x1 /* GPIO8_MKIN4 */
+ 0x100 0x1 /* GPIO9_MKOUT4 */
+ 0x10c 0x1 /* GPIO12_MKIN6 */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x8000 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x2000 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ nfc_pmx_func: pinmux_nfc_pins at 0 {
+ pinctrl-single,pins = <
+ 0x120 0x0 /* GPIO17 */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ wlan_pmx_func: pinmux_wlan_pins at 0 {
+ pinctrl-single,pins = <
+ 0x114 0x0 /* GPIO14 */
+ 0x12c 0x0 /* GPIO20 */
+ 0x160 0x0 /* GPIO33 */
+ 0x164 0x0 /* GPIO34 */
+ 0x168 0x0 /* GPIO35 */
+ 0x16c 0x0 /* GPIO36 */
+ >;
+ pinctrl-single,slew-rate = <0x1000 0x1800>;
+ pinctrl-single,bias-disable = <0x0 0x0 0x8000>;
+ pinctrl-single,bias-pullup = <0x0 0x4000 0x4000>;
+ pinctrl-single,bias-pulldown = <0x0 0x2000 0x2000>;
+ pinctrl-single,input-schmitt = <0x40 0x70>;
+ pinctrl-single,input-schmitt-disable = <0x40 0x40 0x70>;
+ };
+ };
};
};
};
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 825aaca..20a3418 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -93,28 +93,37 @@
#address-cells = <1>;
#size-cells = <1>;
reg = <0xd4019000 0x1000>;
- gpio-controller;
- #gpio-cells = <2>;
+ marvell,gpio-ed-mask = <1>;
+ marvell,nr-gpios = <128>;
interrupts = <49>;
interrupt-names = "gpio_mux";
interrupt-controller;
#interrupt-cells = <1>;
+ status = "disabled";
ranges;
gcb0: gpio at d4019000 {
reg = <0xd4019000 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
gcb1: gpio at d4019004 {
reg = <0xd4019004 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
gcb2: gpio at d4019008 {
reg = <0xd4019008 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
gcb3: gpio at d4019100 {
reg = <0xd4019100 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
};
@@ -144,6 +153,22 @@
interrupt-names = "rtc 1Hz", "rtc alarm";
status = "disabled";
};
+
+ pmx: pinmux at d401e000 {
+ compatible = "pinconf-single";
+ reg = <0xd401e000 0x330>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #gpio-range-cells = <3>;
+ ranges;
+
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <7>;
+
+ range: gpio-range {
+ #pinctrl-single,gpio-range-cells = <3>;
+ };
+ };
};
};
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH] sunxi: a10-cubieboard: Add user LEDs to the device tree
From: Maxime Ripard @ 2013-02-03 10:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359372464-5811-1-git-send-email-emilio@elopez.com.ar>
Le 28/01/2013 12:27, Emilio L?pez a ?crit :
> Cubieboard has two LEDs available for use, a blue one (labeled LED1)
> and a green one (labeled LED2).
Applied, thanks.
Maxime
--
Maxime Ripard, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH] rtc: rtc-mv: Add support for clk to avoid lockups
From: Andrew Lunn @ 2013-02-03 10:30 UTC (permalink / raw)
To: linux-arm-kernel
The Marvell RTC on Kirkwood makes use of the runit clock. Ensure the
driver clk_prepare_enable() this clock, otherwise there is a danger
the SoC will lockup when accessing RTC registers with the clock
disabled.
Reported-by: Simon Baatz gmbnomis at gmail.com
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
arch/arm/boot/dts/kirkwood.dtsi | 1 +
drivers/rtc/rtc-mv.c | 15 ++++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index 6c5d75f..c57b9c6 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -77,6 +77,7 @@
compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
reg = <0x10300 0x20>;
interrupts = <53>;
+ clocks = <&gate_clk 7>;
};
spi at 10600 {
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index 57233c8..365bc83 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/delay.h>
+#include <linux/clk.h>
#include <linux/gfp.h>
#include <linux/module.h>
@@ -41,6 +42,7 @@ struct rtc_plat_data {
struct rtc_device *rtc;
void __iomem *ioaddr;
int irq;
+ struct clk *clk;
};
static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -260,6 +262,11 @@ static int mv_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pdata);
+ pdata->clk = devm_clk_get(&pdev->dev, NULL);
+ /* Not all SoCs require a clock.*/
+ if (!IS_ERR(pdata->clk))
+ clk_prepare_enable(pdata->clk);
+
if (pdata->irq >= 0) {
device_init_wakeup(&pdev->dev, 1);
pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
@@ -268,8 +275,11 @@ static int mv_rtc_probe(struct platform_device *pdev)
} else
pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
&mv_rtc_ops, THIS_MODULE);
- if (IS_ERR(pdata->rtc))
+ if (IS_ERR(pdata->rtc)) {
+ if (!IS_ERR(pdata->clk))
+ clk_disable_unprepare(pdata->clk);
return PTR_ERR(pdata->rtc);
+ }
if (pdata->irq >= 0) {
writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
@@ -292,6 +302,9 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 0);
rtc_device_unregister(pdata->rtc);
+ if (!IS_ERR(pdata->clk))
+ clk_disable_unprepare(pdata->clk);
+
return 0;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2] gpio: mvebu: Add clk support to prevent lockup
From: Andrew Lunn @ 2013-02-03 10:34 UTC (permalink / raw)
To: linux-arm-kernel
The kirkwood SoC GPIO cores use the runit clock. Add code to
clk_prepare_enable() runit, otherwise there is a danger of locking up
the SoC by accessing the GPIO registers when runit clock is not
ticking.
Reported-by: Simon Baatz <gmbnomis@gmail.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
Since v1:
ChangeLog: tclk->runit clock
arch/arm/boot/dts/kirkwood.dtsi | 2 ++
drivers/gpio/gpio-mvebu.c | 7 +++++++
2 files changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index d6ab442..6c5d75f 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -38,6 +38,7 @@
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <35>, <36>, <37>, <38>;
+ clocks = <&gate_clk 7>;
};
gpio1: gpio at 10140 {
@@ -49,6 +50,7 @@
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <39>, <40>, <41>;
+ clocks = <&gate_clk 7>;
};
serial at 12000 {
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 6819d63..456663c 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -41,6 +41,7 @@
#include <linux/io.h>
#include <linux/of_irq.h>
#include <linux/of_device.h>
+#include <linux/clk.h>
#include <linux/pinctrl/consumer.h>
/*
@@ -495,6 +496,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
struct resource *res;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
+ struct clk *clk;
unsigned int ngpios;
int soc_variant;
int i, cpu, id;
@@ -528,6 +530,11 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
return id;
}
+ clk = devm_clk_get(&pdev->dev, NULL);
+ /* Not all SoCs require a clock.*/
+ if (!IS_ERR(clk))
+ clk_prepare_enable(clk);
+
mvchip->soc_variant = soc_variant;
mvchip->chip.label = dev_name(&pdev->dev);
mvchip->chip.dev = &pdev->dev;
--
1.7.10.4
^ permalink raw reply related
* [PATCH] ARM: mxs: Enable cpuidle
From: Shawn Guo @ 2013-02-03 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359733797-19538-1-git-send-email-festevam@gmail.com>
On Fri, Feb 01, 2013 at 01:49:57PM -0200, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
>
> Enable CONFIG_CPU_IDLE, so that suspend/resume can be tested on mxs platforms.
>
I do not think suspend depends on CONFIG_CPU_IDLE to work. Can you
investigate the root cause why suspend does not work without enabling
CONFIG_CPU_IDLE?
Shawn
^ permalink raw reply
* [PATCH 2/2] ARM: imx: set CKO1 parent clock source in imx6q sabresd
From: Shawn Guo @ 2013-02-03 10:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359701217-23931-1-git-send-email-b13634@freescale.com>
On Fri, Feb 01, 2013 at 02:46:57PM +0800, Gary Zhang wrote:
> in imx6q sabresd board, set ahb as CKO1 parent clock sourrce
>
> Signed-off-by: Gary Zhang <b13634@freescale.com>
> ---
> arch/arm/mach-imx/mach-imx6q.c | 15 ++++++++++++---
> 1 files changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
> index 4eb1b3a..860e272 100644
> --- a/arch/arm/mach-imx/mach-imx6q.c
> +++ b/arch/arm/mach-imx/mach-imx6q.c
> @@ -119,7 +119,7 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
> return 0;
> }
>
> -static void __init imx6q_sabrelite_cko1_setup(void)
> +static void __init cko1_setup(unsigned long freq)
> {
> struct clk *cko1_sel, *ahb, *cko1;
> unsigned long rate;
> @@ -132,8 +132,10 @@ static void __init imx6q_sabrelite_cko1_setup(void)
> goto put_clk;
> }
> clk_set_parent(cko1_sel, ahb);
> - rate = clk_round_rate(cko1, 16000000);
> + rate = clk_round_rate(cko1, freq);
> clk_set_rate(cko1, rate);
> +
> + return;
Why does this "return" needs to be added here?
Shawn
> put_clk:
> if (!IS_ERR(cko1_sel))
> clk_put(cko1_sel);
> @@ -148,7 +150,12 @@ static void __init imx6q_sabrelite_init(void)
> if (IS_BUILTIN(CONFIG_PHYLIB))
> phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
> ksz9021rn_phy_fixup);
> - imx6q_sabrelite_cko1_setup();
> + cko1_setup(16000000);
> +}
> +
> +static void __init imx6q_sabresd_init(void)
> +{
> + cko1_setup(24000000);
> }
>
> static void __init imx6q_1588_init(void)
> @@ -193,6 +200,8 @@ static void __init imx6q_init_machine(void)
> {
> if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
> imx6q_sabrelite_init();
> + else if (of_machine_is_compatible("fsl,imx6q-sabresd"))
> + imx6q_sabresd_init();
>
> of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
>
> --
> 1.7.0.4
>
>
^ permalink raw reply
* [PATCH 1/2] ARM: dts: add support for some modules in imx6q sabresd
From: Shawn Guo @ 2013-02-03 10:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359701198-23900-1-git-send-email-b13634@freescale.com>
On Fri, Feb 01, 2013 at 02:46:38PM +0800, Gary Zhang wrote:
> add I2C/I2S/clk/fixed regulator/sound card and
> other related supports in imx6q sabresd
>
> Signed-off-by: Gary Zhang <b13634@freescale.com>
> ---
> arch/arm/boot/dts/imx6q-sabresd.dts | 76 +++++++++++++++++++++++++++++++++++
> arch/arm/boot/dts/imx6q.dtsi | 23 ++++++++++
> 2 files changed, 99 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts
> index a424025..383fcf0 100644
> --- a/arch/arm/boot/dts/imx6q-sabresd.dts
> +++ b/arch/arm/boot/dts/imx6q-sabresd.dts
> @@ -29,6 +29,10 @@
> pinctrl-0 = <&pinctrl_uart1_1>;
> status = "okay";
> };
> + ssi2: ssi at 0202c000 {
We generally have a blank line between nodes, so please follow the
pattern.
> + fsl,mode = "i2s-slave";
> + status = "okay";
> + };
> };
>
> iomuxc at 020e0000 {
> @@ -73,6 +77,33 @@
> wp-gpios = <&gpio2 1 0>;
> status = "okay";
> };
> +
> + audmux at 021d8000 {
> + status = "okay";
Nit: we usually have "status" be the last one in the property list.
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_audmux_2>;
> + };
> +
> + i2c at 021a0000 { /* I2C1 */
> + status = "okay";
> + clock-frequency = <100000>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_i2c1_2>;
> +
> + codec: wm8962 at 1a {
> + compatible = "fsl,wm8962";
This does not seem right, as wm8962 is not a codec produced by FSL.
I suspect you can have your driver work even without this compatible
since it's a I2C device. If so, you can choose to simply drop it.
Shawn
> + reg = <0x1a>;
> + clocks = <&clks 169>;
> + DCVDD-supply = <®_1p8v>;
> + DBVDD-supply = <®_1p8v>;
> + AVDD-supply = <®_1p8v>;
> + CPVDD-supply = <®_1p8v>;
> + MICVDD-supply = <®_3p3v>;
> + PLLVDD-supply = <®_1p8v>;
> + SPKVDD1-supply = <®_4p2v>;
> + SPKVDD2-supply = <®_4p2v>;
> + };
> + };
> };
> };
>
> @@ -91,4 +122,49 @@
> linux,code = <114>; /* KEY_VOLUMEDOWN */
> };
> };
> + regulators {
> + compatible = "simple-bus";
> +
> + reg_1p8v: 1p8v {
> + compatible = "regulator-fixed";
> + regulator-name = "1P8V";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-always-on;
> + enable-active-high;
> + };
> + reg_3p3v: 3p3v {
> + compatible = "regulator-fixed";
> + regulator-name = "3P3V";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + enable-active-high;
> + };
> + reg_4p2v: 4p2v {
> + compatible = "regulator-fixed";
> + regulator-name = "4P2V";
> + regulator-min-microvolt = <4200000>;
> + regulator-max-microvolt = <4200000>;
> + gpio = <&gpio4 10 0>;
> + regulator-always-on;
> + regulator-boot-on;
> + enable-active-high;
> + };
> + };
> +
> + sound {
> + compatible = "fsl,imx6q-sabresd-wm8962",
> + "fsl,imx-audio-wm8962";
> + model = "imx6q-sabresd-wm8962";
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_clko_1>;
> + ssi-controller = <&ssi2>;
> + audio-codec = <&codec>;
> + audio-routing =
> + "Headphone Jack", "HPOUTL",
> + "Headphone Jack", "HPOUTR";
> + mux-int-port = <2>;
> + mux-ext-port = <3>;
> + };
> };
> diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
> index d6265ca..b612269 100644
> --- a/arch/arm/boot/dts/imx6q.dtsi
> +++ b/arch/arm/boot/dts/imx6q.dtsi
> @@ -582,6 +582,23 @@
> 3 0x80000000 /* MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */
> >;
> };
> +
> + pinctrl_audmux_2: audmux-2 {
> + fsl,pins = <
> + 1117 0x80000000 /* MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD */
> + 1093 0x80000000 /* MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC */
> + 1101 0x80000000 /* MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD */
> + 1109 0x80000000 /* MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS */
> + >;
> + };
> + };
> +
> + clko {
> + pinctrl_clko_1: clkogrp-1 {
> + fsl,pins = <
> + 953 0x130b0 /* MX6Q_PAD_GPIO_0__CCM_CLKO */
> + >;
> + };
> };
>
> ecspi1 {
> @@ -670,6 +687,12 @@
> 196 0x4001b8b1 /* MX6Q_PAD_EIM_D28__I2C1_SDA */
> >;
> };
> + pinctrl_i2c1_2: i2c1grp-2 {
> + fsl,pins = <
> + 1125 0x4001b8b1 /* MX6Q_PAD_CSI0_DAT8__I2C1_SDA */
> + 1133 0x4001b8b1 /* MX6Q_PAD_CSI0_DAT9__I2C1_SCL */
> + >;
> + };
> };
>
> uart1 {
> --
> 1.7.0.4
>
>
^ permalink raw reply
* [PATCHv2 0/3] Add support for user LED on the A13-Olinuxino
From: Maxime Ripard @ 2013-02-03 11:10 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This patchset adds the user LED of the Olinuxino to the device tree.
To do so, we also add a custom of_xlate function to the PIO driver so that
we can use a more convenient format for the gpios from the device tree.
Linus, since you took the dt changes for the pinctrl driver in your tree, maybe you could merge the two first patches, the second patch depending on patches in
your tree.
Thanks,
Maxime
Changes:
- Rebased on top of linus walleij allwinner-pinctrl branch
Maxime Ripard (3):
pinctrl: sunxi: Add of_xlate function
sunxi: dts: Report the pinctrl nodes as gpio-controllers
sunxi: a13-olinuxino: Add user LED to the device tree
arch/arm/boot/dts/sun4i-a10.dtsi | 4 +++-
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 20 ++++++++++++++++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 4 +++-
drivers/pinctrl/pinctrl-sunxi.c | 20 ++++++++++++++++++++
4 files changed, 46 insertions(+), 2 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [PATCH 1/3] pinctrl: sunxi: Add of_xlate function
From: Maxime Ripard @ 2013-02-03 11:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359889813-10029-1-git-send-email-maxime.ripard@free-electrons.com>
Since the pin controller of sunxi chips is represented as a single bank
in the driver.
Since this is neither convenient nor represented that way in the
datasheets, define a custom of_xlate function with the layout <bank pin
flag>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/pinctrl/pinctrl-sunxi.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c
index e4d32c6..80b11e3 100644
--- a/drivers/pinctrl/pinctrl-sunxi.c
+++ b/drivers/pinctrl/pinctrl-sunxi.c
@@ -1261,6 +1261,24 @@ static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
writel((value & DATA_PINS_MASK) << index, pctl->membase + reg);
}
+static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
+ const struct of_phandle_args *gpiospec,
+ u32 *flags)
+{
+ int pin, base;
+
+ base = PINS_PER_BANK * gpiospec->args[0];
+ pin = base + gpiospec->args[1];
+
+ if (pin > (gc->base + gc->ngpio))
+ return -EINVAL;
+
+ if (flags)
+ *flags = gpiospec->args[2];
+
+ return pin;
+}
+
static struct gpio_chip sunxi_pinctrl_gpio_chip = {
.owner = THIS_MODULE,
.request = sunxi_pinctrl_gpio_request,
@@ -1269,6 +1287,8 @@ static struct gpio_chip sunxi_pinctrl_gpio_chip = {
.direction_output = sunxi_pinctrl_gpio_direction_output,
.get = sunxi_pinctrl_gpio_get,
.set = sunxi_pinctrl_gpio_set,
+ .of_xlate = sunxi_pinctrl_gpio_of_xlate,
+ .of_gpio_n_cells = 3,
.can_sleep = 0,
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH] rtc: rtc-mv: Add support for clk to avoid lockups
From: Simon Baatz @ 2013-02-03 11:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359887453-17189-1-git-send-email-andrew@lunn.ch>
Hi Andrew,
On Sun, Feb 03, 2013 at 11:30:53AM +0100, Andrew Lunn wrote:
> The Marvell RTC on Kirkwood makes use of the runit clock. Ensure the
> driver clk_prepare_enable() this clock, otherwise there is a danger
> the SoC will lockup when accessing RTC registers with the clock
> disabled.
>
> Reported-by: Simon Baatz gmbnomis at gmail.com
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> arch/arm/boot/dts/kirkwood.dtsi | 1 +
> drivers/rtc/rtc-mv.c | 15 ++++++++++++++-
> 2 files changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
> index 6c5d75f..c57b9c6 100644
> --- a/arch/arm/boot/dts/kirkwood.dtsi
> +++ b/arch/arm/boot/dts/kirkwood.dtsi
> @@ -77,6 +77,7 @@
> compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
> reg = <0x10300 0x20>;
> interrupts = <53>;
> + clocks = <&gate_clk 7>;
> };
>
> spi at 10600 {
> diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
> index 57233c8..365bc83 100644
> --- a/drivers/rtc/rtc-mv.c
> +++ b/drivers/rtc/rtc-mv.c
> @@ -14,6 +14,7 @@
> #include <linux/platform_device.h>
> #include <linux/of.h>
> #include <linux/delay.h>
> +#include <linux/clk.h>
> #include <linux/gfp.h>
> #include <linux/module.h>
>
> @@ -41,6 +42,7 @@ struct rtc_plat_data {
> struct rtc_device *rtc;
> void __iomem *ioaddr;
> int irq;
> + struct clk *clk;
> };
>
> static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
> @@ -260,6 +262,11 @@ static int mv_rtc_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, pdata);
>
> + pdata->clk = devm_clk_get(&pdev->dev, NULL);
> + /* Not all SoCs require a clock.*/
> + if (!IS_ERR(pdata->clk))
> + clk_prepare_enable(pdata->clk);
> +
There are already I/O accesses to the RTC above this. Thus, you
probably need to move this up.
- Simon
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox