* [PATCH 3/3] ARM: ux500: Add Snowball pin configuration for user LED
From: Linus Walleij @ 2013-01-23 9:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1357725965-27342-3-git-send-email-lee.jones@linaro.org>
On Wed, Jan 9, 2013 at 11:06 AM, Lee Jones <lee.jones@linaro.org> wrote:
> Here we setup the GPIO pin responsible for illuminating the user
> LED on the Snowball low-cost development board.
>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Patch applied to my ux500 tree, branch ux500-pinctrl.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH] ARM: sunxi: gpio: Add Allwinner SoCs GPIO drivers
From: Maxime Ripard @ 2013-01-23 9:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358933646-12681-1-git-send-email-maxime.ripard@free-electrons.com>
The IP responsible for the muxing on the Allwinner SoCs are also
handling the GPIOs on the system. This patch adds the needed driver that
relies on the pinctrl driver for most of its operations.
The number of pins available for GPIOs operations are already declared
in the pinctrl driver, we only need to probe a generic driver to handle
the banks available for each SoC.
This driver has been tested on a A13-Olinuxino.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/pinctrl/pinctrl-sunxi.c | 138 ++++++++++++++++++++++++++++++++++++++-
drivers/pinctrl/pinctrl-sunxi.h | 23 ++++++-
2 files changed, 158 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c
index 6f02e34..bfca9e1 100644
--- a/drivers/pinctrl/pinctrl-sunxi.c
+++ b/drivers/pinctrl/pinctrl-sunxi.c
@@ -11,6 +11,7 @@
*/
#include <linux/io.h>
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -609,11 +610,57 @@ static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
return 0;
}
+static int
+sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset,
+ bool input)
+{
+ struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct sunxi_desc_function *desc;
+ char *func, *pin_name;
+ u8 bank, pin;
+ int ret;
+
+ bank = (offset) / PINS_PER_BANK;
+ pin = (offset) % PINS_PER_BANK;
+
+ pin_name = kzalloc(5, GFP_KERNEL);
+ if (!pin_name)
+ return -ENOMEM;
+
+ ret = sprintf(pin_name, "P%c%d", 'A' + bank, pin);
+ if (!ret)
+ goto error;
+
+ if (input)
+ func = "gpio_in";
+ else
+ func = "gpio_out";
+
+ desc = sunxi_pinctrl_desc_find_function_by_name(pctl,
+ pin_name,
+ func);
+ if (!desc) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ sunxi_pmx_set(pctldev, offset, desc->muxval);
+
+ ret = 0;
+
+error:
+ kfree(pin_name);
+ return ret;
+}
+
static struct pinmux_ops sunxi_pmx_ops = {
.get_functions_count = sunxi_pmx_get_funcs_cnt,
.get_function_name = sunxi_pmx_get_func_name,
.get_function_groups = sunxi_pmx_get_func_groups,
.enable = sunxi_pmx_enable,
+ .gpio_set_direction = sunxi_pmx_gpio_set_direction,
};
static struct pinctrl_desc sunxi_pctrl_desc = {
@@ -622,6 +669,60 @@ static struct pinctrl_desc sunxi_pctrl_desc = {
.pmxops = &sunxi_pmx_ops,
};
+static int sunxi_pinctrl_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void sunxi_pinctrl_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ pinctrl_free_gpio(chip->base + offset);
+}
+
+static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
+
+ u32 reg = sunxi_data_reg(offset);
+ u8 index = sunxi_data_offset(offset);
+ u32 val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK;
+
+ return val;
+}
+
+static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
+ u32 reg = sunxi_data_reg(offset);
+ u8 index = sunxi_data_offset(offset);
+
+ writel((value & DATA_PINS_MASK) << index, pctl->membase + reg);
+}
+
+static struct gpio_chip sunxi_pinctrl_gpio_chip __devinitconst = {
+ .owner = THIS_MODULE,
+ .request = sunxi_pinctrl_gpio_request,
+ .free = sunxi_pinctrl_gpio_free,
+ .direction_input = sunxi_pinctrl_gpio_direction_input,
+ .direction_output = sunxi_pinctrl_gpio_direction_output,
+ .get = sunxi_pinctrl_gpio_get,
+ .set = sunxi_pinctrl_gpio_set,
+ .can_sleep = 0,
+};
+
static struct of_device_id sunxi_pinctrl_match[] = {
{ .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data },
{}
@@ -737,7 +838,7 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
const struct of_device_id *device;
struct pinctrl_pin_desc *pins;
struct sunxi_pinctrl *pctl;
- int i, ret;
+ int i, ret, last_pin;
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
if (!pctl)
@@ -781,9 +882,42 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
return -EINVAL;
}
- dev_info(&pdev->dev, "initialized sunXi pin control driver\n");
+ pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
+ if (!pctl->chip) {
+ ret = -ENOMEM;
+ goto pinctrl_error;
+ }
+
+ last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
+ pctl->chip = &sunxi_pinctrl_gpio_chip;
+ pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK);
+ pctl->chip->label = dev_name(&pdev->dev);
+ pctl->chip->dev = &pdev->dev;
+ pctl->chip->base = 0;
+
+ ret = gpiochip_add(pctl->chip);
+ if (ret)
+ goto pinctrl_error;
+
+ for (i = 0; i < pctl->desc->npins; i++) {
+ const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
+
+ ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
+ pin->pin.number,
+ pin->pin.number, 1);
+ if (ret)
+ goto gpiochip_error;
+ }
+
+ dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
return 0;
+
+gpiochip_error:
+ ret = gpiochip_remove(pctl->chip);
+pinctrl_error:
+ pinctrl_unregister(pctl->pctl_dev);
+ return ret;
}
static struct platform_driver sunxi_pinctrl_driver = {
diff --git a/drivers/pinctrl/pinctrl-sunxi.h b/drivers/pinctrl/pinctrl-sunxi.h
index 0dc3b9d..0416c36 100644
--- a/drivers/pinctrl/pinctrl-sunxi.h
+++ b/drivers/pinctrl/pinctrl-sunxi.h
@@ -256,6 +256,7 @@
#define BANK_MEM_SIZE 0x24
#define MUX_REGS_OFFSET 0x0
+#define DATA_REGS_OFFSET 0x10
#define DLEVEL_REGS_OFFSET 0x14
#define PULL_REGS_OFFSET 0x1c
@@ -263,6 +264,9 @@
#define MUX_PINS_PER_REG 8
#define MUX_PINS_BITS 4
#define MUX_PINS_MASK 0x0f
+#define DATA_PINS_PER_REG 32
+#define DATA_PINS_BITS 1
+#define DATA_PINS_MASK 0x01
#define DLEVEL_PINS_PER_REG 16
#define DLEVEL_PINS_BITS 2
#define DLEVEL_PINS_MASK 0x03
@@ -283,6 +287,8 @@ struct sunxi_desc_pin {
struct sunxi_pinctrl_desc {
const struct sunxi_desc_pin *pins;
int npins;
+ struct pinctrl_gpio_range *ranges;
+ int nranges;
};
struct sunxi_pinctrl_function {
@@ -299,6 +305,7 @@ struct sunxi_pinctrl_group {
struct sunxi_pinctrl {
void __iomem *membase;
+ struct gpio_chip *chip;
struct sunxi_pinctrl_desc *desc;
struct device *dev;
struct sunxi_pinctrl_function *functions;
@@ -321,7 +328,6 @@ struct sunxi_pinctrl {
.muxval = _val, \
}
-
/*
* The sunXi PIO registers are organized as is:
* 0x00 - 0x0c Muxing values.
@@ -354,6 +360,21 @@ static inline u32 sunxi_mux_offset(u16 pin)
return pin_num * MUX_PINS_BITS;
}
+static inline u32 sunxi_data_reg(u16 pin)
+{
+ u8 bank = pin / PINS_PER_BANK;
+ u32 offset = bank * BANK_MEM_SIZE;
+ offset += DATA_REGS_OFFSET;
+ offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04;
+ return round_down(offset, 4);
+}
+
+static inline u32 sunxi_data_offset(u16 pin)
+{
+ u32 pin_num = pin % DATA_PINS_PER_REG;
+ return pin_num * DATA_PINS_BITS;
+}
+
static inline u32 sunxi_dlevel_reg(u16 pin)
{
u8 bank = pin / PINS_PER_BANK;
--
1.7.10.4
^ permalink raw reply related
* [PATCHv2] Add GPIO driver for Allwinner SoCs
From: Maxime Ripard @ 2013-01-23 9:34 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This patch adds support for the GPIOs for the Allwinner SoCs supported so
far.
It comes on top of my previous pinctrl patchset, and has been tested on a
A13-Olinuxino from Olimex.
Thanks,
Maxime
Changes from v1:
- Merged the gpio driver with the pinctrl one
- Now using gpiochip_add_pin_range instead of pinctrl_add_gpio_range
- Removed the hairy range registration function, and register 1pin ranges
instead
Maxime Ripard (1):
ARM: sunxi: gpio: Add Allwinner SoCs GPIO drivers
drivers/pinctrl/pinctrl-sunxi.c | 138 ++++++++++++++++++++++++++++++++++++++-
drivers/pinctrl/pinctrl-sunxi.h | 23 ++++++-
2 files changed, 158 insertions(+), 3 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [v3 2/2] ARM: tegra: Skip scu_enable(scu_base) if not Cortex A9
From: Hiroshi Doyu @ 2013-01-23 9:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130123.080457.171573168772211248.hdoyu@nvidia.com>
Hiroshi Doyu <hdoyu@nvidia.com> wrote @ Wed, 23 Jan 2013 08:04:57 +0200 (EET):
> Stephen Warren <swarren@wwwdotorg.org> wrote @ Tue, 22 Jan 2013 17:57:39 +0100:
>
> > Hiroshi, is this series the only dependency you need for your
> > Tegra114
>
> Basically yes.
>
> > series? So, I could merge your Tegra114 series once this series is applied?
>
> But now "CCF" seems to be in. Then, the HACK(*1) needs to be replaced
> with "Tegra114 CCF". But "Tegra114 CCF" doesn't seem ready yet. I'll check
> if this Tegra114 series would work without "Tegra114 CCF".
>
> *1: http://patchwork.ozlabs.org/patch/212010/
Stephen,
Verified "Tegra114 series" worked with "for-3.9/soc" branch(inc CCF)
with a little tweak.
I can post Tegra114 series again. If you want them rebased onto
another branch, let me know.
^ permalink raw reply
* [PATCH 1/4] arch: arm: gpmc: gpmc migration support
From: Philip Avinash @ 2013-01-23 9:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358933176-12409-1-git-send-email-avinashphilip@ti.com>
With recent GPMC driver conversion, usage of gpmc_save/restore_context
can done from gpmc driver itself. Hence removes the usage from pm34xx.c.
Also removes the conditional compilation primitives ARCH_OMAP3 for
gpmc_save/restore_context.
Signed-off-by: Philip Avinash <avinashphilip@ti.com>
---
arch/arm/mach-omap2/gpmc.c | 2 --
arch/arm/mach-omap2/pm34xx.c | 5 -----
2 files changed, 7 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index cbf4e0d..aed958a 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1426,7 +1426,6 @@ static irqreturn_t gpmc_handle_irq(int irq, void *dev)
return IRQ_HANDLED;
}
-#ifdef CONFIG_ARCH_OMAP3
static struct omap3_gpmc_regs gpmc_context;
void omap3_gpmc_save_context(void)
@@ -1491,4 +1490,3 @@ void omap3_gpmc_restore_context(void)
}
}
}
-#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 60fbf0a..cab4c5d 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -43,7 +43,6 @@
#include "common.h"
#include "cm3xxx.h"
#include "cm-regbits-34xx.h"
-#include "gpmc.h"
#include "prm-regbits-34xx.h"
#include "prm3xxx.h"
#include "pm.h"
@@ -84,8 +83,6 @@ static void omap3_core_save_context(void)
/* Save the Interrupt controller context */
omap_intc_save_context();
- /* Save the GPMC context */
- omap3_gpmc_save_context();
/* Save the system control module context, padconf already save above*/
omap3_control_save_context();
omap_dma_global_context_save();
@@ -95,8 +92,6 @@ static void omap3_core_restore_context(void)
{
/* Restore the control module context, padconf restored by h/w */
omap3_control_restore_context();
- /* Restore the GPMC context */
- omap3_gpmc_restore_context();
/* Restore the interrupt controller context */
omap_intc_restore_context();
omap_dma_global_context_restore();
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/4] LOW power sleep support for OMAP nand driver
From: Philip Avinash @ 2013-01-23 9:26 UTC (permalink / raw)
To: linux-arm-kernel
This patch series adds low power transition support for OMAP NAND driver.
This includes low power transition support of
- GPMC module
- ELM module
- OMAP2 NAND driver
Low power transition support tested on am335x-evm with NAND flash support.
This patch series based on [1] and depends on [2] and is available [2]
1. ARM: OMAP2+: AM33XX: Add suspend-resume support
http://comments.gmane.org/gmane.linux.ports.arm.omap/91405
2. https://github.com/avinashphilip/am335x_linux/commits/NAND_supend_resume_support
Philip Avinash (4):
arch: arm: gpmc: gpmc migration support
mtd: devices: elm: Low power transition support
arm: gpmc: Low power transition support
mtd: nand: omap2: Low power transition support
arch/arm/mach-omap2/gpmc.c | 22 ++++++++++++++++++++--
arch/arm/mach-omap2/pm34xx.c | 5 -----
drivers/mtd/devices/elm.c | 40 ++++++++++++++++++++++++++++++++++++++++
drivers/mtd/nand/omap2.c | 19 +++++++++++++++++++
4 files changed, 79 insertions(+), 7 deletions(-)
--
1.7.9.5
^ permalink raw reply
* arm: Kernel failures when several memory banks are used with starting address above 128MB
From: Russell King - ARM Linux @ 2013-01-23 9:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAHTX3dJZxuoz_0Eaa7QcoK9bF4LdLuWcDcwK3OUKc6qY_0PeuQ@mail.gmail.com>
On Tue, Jan 22, 2013 at 08:18:13PM +0100, Michal Simek wrote:
> I have a question regarding to the case where DTS specify one memory bank
> for example <0x0 0x40000000> with CONFIG_ARM_PATCH_PHYS_VIRT=y
> where the kernel can be loaded at a 16MB boundary.
That's where you're going wrong. We assume that the kernel is loaded
within the 16MB of memory _always_. Can't get around this on a
multiplatform kernel.
^ permalink raw reply
* [GIT PULL][for 3.9] request from pxa git tree on armsoc/board branch
From: Haojian Zhuang @ 2013-01-23 9:15 UTC (permalink / raw)
To: linux-arm-kernel
Hi Arnd & Olof,
Please help to merge armsoc/board branch from pxa git tree.
Regards
Haojian
The following changes since commit 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619:
Linux 3.8-rc4 (2013-01-17 19:25:45 -0800)
are available in the git repository at:
git://github.com/hzhuang1/linux.git armsoc/board
for you to fetch changes up to 495b21dc0e488b784ab1d4007d00db1ca2a95c98:
ARM: pxa: pxa27x.c: add dummy SA1100 rtc clock (2013-01-23 17:05:08 +0800)
----------------------------------------------------------------
Andrea Adami (1):
ARM: pxa: pxa27x.c: add dummy SA1100 rtc clock
Mike Dunn (2):
ARM: palmtreo: add docg4 device initialization
ARM: palmtreo: replace #if defined with IF_ENABLED
arch/arm/mach-pxa/palmtreo.c | 35 +++++++++++++++++++++++++++++++++--
arch/arm/mach-pxa/pxa27x.c | 1 +
2 files changed, 34 insertions(+), 2 deletions(-)
^ permalink raw reply
* [GIT PULL][for 3.8] request from armsoc/fix branch in pxa git tree
From: Haojian Zhuang @ 2013-01-23 9:15 UTC (permalink / raw)
To: linux-arm-kernel
Hi Arnd & Olof,
Please help to pull armsoc/fix branch in pxa git tree.
Regards
Haojian
The following changes since commit 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619:
Linux 3.8-rc4 (2013-01-17 19:25:45 -0800)
are available in the git repository at:
git://github.com/hzhuang1/linux.git armsoc/fix
for you to fetch changes up to eea6e39b916dd282c7fa4629be8934b5ad60e62b:
ARM: pxa: Minor naming fixes in spitz.c (2013-01-23 17:13:07 +0800)
----------------------------------------------------------------
Igor Grinberg (1):
ARM: PXA3xx: program the CSMSADRCFG register
Marko Katic (1):
ARM: pxa: Minor naming fixes in spitz.c
Mike Dunn (2):
ARM: palmtreo: fix lcd initilialization on treo680
ARM: palmtreo: fix #ifdefs for leds-gpio device
arch/arm/mach-pxa/include/mach/palmtreo.h | 5 +++--
arch/arm/mach-pxa/include/mach/smemc.h | 1 +
arch/arm/mach-pxa/palmtreo.c | 70
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
arch/arm/mach-pxa/smemc.c | 15 ++++++++++++++-
arch/arm/mach-pxa/spitz.c | 4 ++--
5 files changed, 80 insertions(+), 15 deletions(-)
^ permalink raw reply
* [PATCH] ARM: pxa: pxa27x.c: add dummy SA1100 rtc clock
From: Haojian Zhuang @ 2013-01-23 9:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87ehjh3man.fsf@free.fr>
On Sun, Nov 25, 2012 at 8:21 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>
Applied.
Thanks
Haojian
^ permalink raw reply
* [PATCH v3 1/2] mtd: Add a common JEDEC flash device table
From: Matthieu CASTET @ 2013-01-23 9:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358928068-12417-2-git-send-email-linux@prisktech.co.nz>
Tony Prisk a ?crit :
> This patch adds a common JEDEC flash device table which can be
> expanded on as more features are required.
>
> A simple match function is also included to query the table for
> a match based on the JEDEC id.
Why don't you use id from include/linux/mtd/cfi.h that is used by flash driver
like drivers/mtd/devices/m25p80.c ?
#define CFI_MFR_AMD 0x0001
#define CFI_MFR_AMIC 0x0037
#define CFI_MFR_ATMEL 0x001F
#define CFI_MFR_EON 0x001C
#define CFI_MFR_FUJITSU 0x0004
#define CFI_MFR_HYUNDAI 0x00AD
#define CFI_MFR_INTEL 0x0089
#define CFI_MFR_MACRONIX 0x00C2
#define CFI_MFR_NEC 0x0010
#define CFI_MFR_PMC 0x009D
#define CFI_MFR_SAMSUNG 0x00EC
#define CFI_MFR_SHARP 0x00B0
#define CFI_MFR_SST 0x00BF
#define CFI_MFR_ST 0x0020 /* STMicroelectronics */
#define CFI_MFR_TOSHIBA 0x0098
#define CFI_MFR_WINBOND 0x00DA
>
> Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
> ---
> drivers/mtd/devices/flash_jedec.c | 96 +++++++++++++++++++++++++++++++++++++
> drivers/mtd/devices/flash_jedec.h | 30 ++++++++++++
> 2 files changed, 126 insertions(+)
> create mode 100644 drivers/mtd/devices/flash_jedec.c
> create mode 100644 drivers/mtd/devices/flash_jedec.h
>
> diff --git a/drivers/mtd/devices/flash_jedec.c b/drivers/mtd/devices/flash_jedec.c
> new file mode 100644
> index 0000000..c0b2272
> --- /dev/null
> +++ b/drivers/mtd/devices/flash_jedec.c
> @@ -0,0 +1,96 @@
> +/*
> + * Copyright Tony Prisk <linux@prisktech.co.nz>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +
> +#include <linux/bug.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/types.h>
> +
> +#include "flash_jedec.h"
> +
> +/*
> + * Device Manufacturer IDs
> + * Please keep sorted by manufacturer ID
> + */
> +#define MFR_SPANSION 0X01
> +#define MFR_EON 0X1C
> +#define MFR_ATMEL 0X1F
> +#define MFR_MICRON 0X20 /* Also Numonyx & STM */
> +#define MFR_INTEL 0x89
> +#define MFR_FUDAN 0XA1
> +#define MFR_SST 0XBF
> +#define MFR_MXIC 0XC2
> +#define MFR_WINBOND 0XEF
> +
> +#define _ID(m, d) ((m << 16) | d)
> +
> +/*
> + * Flash device information
> + * Please keep sorted by manufacturer id, then device id
> + */
> +static struct flash_device_info flash_devices[] = {
> + /* Spansion */
> + { "s25fl016", _ID(MFR_SPANSION, 0x0214), 2048 },
> + { "s25fl064", _ID(MFR_SPANSION, 0x0216), 8192 },
> + /* EON */
> + { "en25p16", _ID(MFR_EON, 0x2015), 2048 },
> + { "en25p64", _ID(MFR_EON, 0x2017), 8192 },
> + { "en25f40", _ID(MFR_EON, 0x3113), 512 },
> + { "en25f16", _ID(MFR_EON, 0x3115), 2048 },
> + /* ATMEL */
> + { "at25df041a", _ID(MFR_ATMEL, 0x4401), 512 },
> + /* Micron, STM & Numonyx */
> + { "stm25p16", _ID(MFR_MICRON, 0x2015), 2048 },
> + { "stm25p64", _ID(MFR_MICRON, 0x2017), 8192 },
> + /* Fudan */
> + { "fm25f04", _ID(MFR_FUDAN, 0x3113), 512 },
> + /* SST */
> + { "sst25vf016b", _ID(MFR_SST, 0x2541), 2048 },
> + /* Macronix - MXIC */
> + { "mx25l512", _ID(MFR_MXIC, 0x2010), 64 },
> + { "mx25l4005", _ID(MFR_MXIC, 0x2013), 512 },
> + { "mx25l1605", _ID(MFR_MXIC, 0x2015), 2048 },
> + { "mx25l3205", _ID(MFR_MXIC, 0x2016), 4096 },
> + { "mx25l6405", _ID(MFR_MXIC, 0x2017), 8192 },
> + { "mx25l12805", _ID(MFR_MXIC, 0x2018), 16384 },
> + { "mx25l1635", _ID(MFR_MXIC, 0x2415), 2048 },
> + { "mx25l3235", _ID(MFR_MXIC, 0x5E16), 4096 },
> + /* Winbond */
> + { "w25x40", _ID(MFR_WINBOND, 0x3013), 512 },
> + { "w25x16", _ID(MFR_WINBOND, 0x3015), 2048 },
> + { "w25x32", _ID(MFR_WINBOND, 0x3016), 4096 },
> + { "w25x64", _ID(MFR_WINBOND, 0x3017), 8192 },
> +};
> +
> +/*
> + * jedec_match_device - match a jedec id against the flash_devices table
> + * @jedecid: JEDEC formatted id to match
> + * bits 16..24: manufacturer id
> + * bits 0..15: device id
> + * Returns a valid flash_device_info* or ERR_PTR(-ENODEV) if an entry is
> + * not found
> + */
> +struct flash_device_info *jedec_match_device(u32 jedec_id)
> +{
> + int i;
> + for (i = 0; i < ARRAY_SIZE(flash_devices); i++)
> + if (flash_devices[i].jedec_id == jedec_id)
> + return &flash_devices[i];
> +
> + return ERR_PTR(-ENODEV);
> +}
> diff --git a/drivers/mtd/devices/flash_jedec.h b/drivers/mtd/devices/flash_jedec.h
> new file mode 100644
> index 0000000..27b978a
> --- /dev/null
> +++ b/drivers/mtd/devices/flash_jedec.h
> @@ -0,0 +1,30 @@
> +/*
> + * Copyright Tony Prisk <linux@prisktech.co.nz>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +
> +#ifndef __MTD_FLASH_JEDEC
> +#define __MTD_FLASH_JEDEC
> +
> +struct flash_device_info {
> + const char *name;
> + u32 jedec_id;
> + u32 size_kb;
> +};
> +
> +extern struct flash_device_info *jedec_match_device(u32 jedec_id);
> +
> +#endif
--
Matthieu Castet
Ing?nieur D?veloppement Logiciel
Parrot SA
174 Quai de Jemmapes
75010 Paris, France
T?l: +33 (0) 1 48 03 74 78
Fax: +33 (0) 1 48 03 06 66
Email: matthieu.castet at parrot.fr
http://www.parrot.biz
^ permalink raw reply
* [PATCH] [ARM] spitz/pxa: Refactor i2c init code in spitz.c
From: Haojian Zhuang @ 2013-01-23 9:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1355257645-27888-1-git-send-email-dromede@gmail.com>
On Wed, Dec 12, 2012 at 4:27 AM, <dromede@gmail.com> wrote:
> From: Marko Katic <dromede.gmail.com>
>
> This patch changes the way i2c devices are defined
> and registered.
>
> I2c devices that are present in all spitz
> variants are always defined and registered while the max7310
> gpio expander specific to the akita variant is defined
> and registered only when building the kernel for akita variants.
>
> spitz_i2c_init() is simplified and is now more readable.
>
> Signed-off-by: Marko Katic <dromede@gmail.com>
> ---
> arch/arm/mach-pxa/spitz.c | 38 ++++++++++++++++++--------------------
> 1 file changed, 18 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
> index 0cc9dc7..1c7dc2b 100644
> --- a/arch/arm/mach-pxa/spitz.c
> +++ b/arch/arm/mach-pxa/spitz.c
> @@ -865,17 +865,6 @@ static struct pca953x_platform_data akita_pca953x_pdata = {
> .gpio_base = AKITA_IOEXP_GPIO_BASE,
> };
>
> -static struct i2c_board_info spitz_i2c_devs[] = {
> - {
> - .type = "wm8750",
> - .addr = 0x1b,
> - }, {
> - .type = "max7310",
> - .addr = 0x18,
> - .platform_data = &akita_pca953x_pdata,
> - },
> -};
> -
> static struct regulator_consumer_supply isl6271a_consumers[] = {
> REGULATOR_SUPPLY("vcc_core", NULL),
> };
> @@ -894,26 +883,35 @@ static struct regulator_init_data isl6271a_info[] = {
> }
> };
>
> -static struct i2c_board_info spitz_pi2c_devs[] = {
> +static struct i2c_board_info spitz_i2c_devs[2] = {
> {
> + .type = "wm8750",
> + .addr = 0x1b,
> + }, {
> .type = "isl6271a",
> .addr = 0x0c,
> .platform_data = &isl6271a_info,
> },
> };
>
spitz_i2c_devs[] are in i2c0 bus. spitz_pi2c_devs[] are in i2c1 bus.
Why do you move wm8750 from i2c0 bus to i2c1 bus?
> +#ifdef CONFIG_MACH_AKITA
> +static struct i2c_board_info akita_i2c_max7310 = {
> + .type = "max7310",
> + .addr = 0x18,
> + .platform_data = &akita_pca953x_pdata,
> +};
> +#endif
> +
> static void __init spitz_i2c_init(void)
> {
> - int size = ARRAY_SIZE(spitz_i2c_devs);
> -
> - /* Only Akita has the max7310 chip */
> - if (!machine_is_akita())
> - size--;
> -
> pxa_set_i2c_info(NULL);
> pxa27x_set_i2c_power_info(NULL);
> - i2c_register_board_info(0, spitz_i2c_devs, size);
> - i2c_register_board_info(1, ARRAY_AND_SIZE(spitz_pi2c_devs));
> +
> + i2c_register_board_info(0, &spitz_i2c_devs[0], 1);
> + i2c_register_board_info(1, &spitz_i2c_devs[1], 1);
> +
> + if (machine_is_akita())
> + i2c_register_board_info(0, &akita_i2c_max7310, 1);
> }
> #else
> static inline void spitz_i2c_init(void) {}
> --
> 1.7.10.4
>
^ permalink raw reply
* [v3 2/2] ARM: tegra: Skip scu_enable(scu_base) if not Cortex A9
From: Santosh Shilimkar @ 2013-01-23 8:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOesGMgtaCkiv285TU_vbAokN5M2MrANQ9piDcyXu5YMmbQq3A@mail.gmail.com>
On Tuesday 22 January 2013 10:34 PM, Olof Johansson wrote:
> On Tue, Jan 22, 2013 at 8:57 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 01/21/2013 11:07 PM, Santosh Shilimkar wrote:
>>> On Tuesday 22 January 2013 11:22 AM, Hiroshi Doyu wrote:
>>>> Skip scu_enable(scu_base) if CPU is not Cortex A9 with SCU.
>>>>
>>>> Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
>>>> ---
>>> Looks fine. I will also update OMAP code with the new
>>> interface. Thanks.
>>
>> OK, so patch 1/2 at least needs to get into a stable arm-soc branch
>> then. Unless there are violent objections, I'll forward patch 1/2 to
>> arm-soc and request it be added into a branch so that Tegra and OMAP can
>> both merge it into their branches as a dependency. I guess patch 2/2
>> could also be included; I don't think it has any complex dependencies
>> that'd prevent that, and would help to show how patch 1/2 gets used.
>>
>> Hiroshi, is this series the only dependency you need for your Tegra114
>> series? So, I could merge your Tegra114 series once this series is applied?
>
> For something like this, it might make more sense for us to just apply
> the patches for OMAP on top, i.e. we'll pull the short branch from
> you, and then we can just apply patches (with maintainer acks) on top,
> instead of doing a bunch of single-patch pulls.
>
In case you decide to apply patches, you can use patch in the end
of the email for OMAP. Attached the same in case mailer damages it.
Btw, I noticed the build error with patch 1/1. Since I wasn't using
the first interface in OMAP code, I just bypassed it for testing.
I might be missing some dependent patch which added
read_cpuid_part_number().
---------------
In file included from arch/arm/kernel/smp_scu.c:15:0:
linux-2.6/arch/arm/include/asm/smp_scu.h: In function 'scu_a9_has_base':
linux-2.6/arch/arm/include/asm/smp_scu.h:14:2: error: implicit
declaration of function 'read_cpuid_part_number'
[-Werror=implicit-function-declaration]
linux-2.6/arch/arm/include/asm/smp_scu.h:14:37: error:
'ARM_CPU_PART_CORTEX_A9' undeclared (first use in this function)
linux-2.6/arch/arm/include/asm/smp_scu.h:14:37: note: each undeclared
identifier is reported only once for each function it appears in
cc1: some warnings being treated as errors
make[1]: *** [arch/arm/kernel/smp_scu.o] Error 1
make: *** [arch/arm/kernel] Error 2
---------------------------------
Regards
Santosh
From 9760cd0ed93b48ec22584e89979cd4a8ec65b938 Mon Sep 17 00:00:00 2001
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
Date: Wed, 23 Jan 2013 13:56:19 +0530
Subject: [PATCH] ARM: OMAP: Make use of available scu_a9_get_base()
interface
Drop the define and make use of scu_a9_get_base() which reads
the physical address of SCU from CP15 register.
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
arch/arm/mach-omap2/omap-smp.c | 2 +-
arch/arm/mach-omap2/omap44xx.h | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index cd42d92..e683d0d 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -215,7 +215,7 @@ static void __init omap4_smp_init_cpus(void)
* Currently we can't call ioremap here because
* SoC detection won't work until after init_early.
*/
- scu_base = OMAP2_L4_IO_ADDRESS(OMAP44XX_SCU_BASE);
+ scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base());
BUG_ON(!scu_base);
ncores = scu_get_core_count(scu_base);
} else if (cpu_id == CPU_CORTEX_A15) {
diff --git a/arch/arm/mach-omap2/omap44xx.h b/arch/arm/mach-omap2/omap44xx.h
index 43b927b..8a515bb 100644
--- a/arch/arm/mach-omap2/omap44xx.h
+++ b/arch/arm/mach-omap2/omap44xx.h
@@ -40,7 +40,6 @@
#define OMAP44XX_GIC_DIST_BASE 0x48241000
#define OMAP44XX_GIC_CPU_BASE 0x48240100
#define OMAP44XX_IRQ_GIC_START 32
-#define OMAP44XX_SCU_BASE 0x48240000
#define OMAP44XX_LOCAL_TWD_BASE 0x48240600
#define OMAP44XX_L2CACHE_BASE 0x48242000
#define OMAP44XX_WKUPGEN_BASE 0x48281000
--
1.7.9.5
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-ARM-OMAP-Make-use-of-available-scu_a9_get_base-inter.patch
Type: text/x-patch
Size: 1627 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130123/2bd872f7/attachment.bin>
^ permalink raw reply related
* [PATCH] [ARM] spitz/pxa: Minor naming fixes in spitz.c
From: Haojian Zhuang @ 2013-01-23 8:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1355254812-14500-1-git-send-email-dromede@gmail.com>
On Wed, Dec 12, 2012 at 3:40 AM, <dromede@gmail.com> wrote:
> From: Marko Katic <dromede.gmail.com>
>
> The NAND init section was erroneously named "Framebuffer".
> Gpio expander section should really be called "I2C devices"
> since it contains all i2c init code.
>
> Signed-off-by: Marko Katic <dromede@gmail.com>
> ---
> arch/arm/mach-pxa/spitz.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
Applied.
Thanks
Haojian
^ permalink raw reply
* [[PATCH v2]] OMAP: omap4-panda: add WiLink shared transport power functions
From: Peter Ujfalusi @ 2013-01-23 8:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130118174910.GF15361@atomide.com>
Hi Tony,
On 01/18/2013 06:49 PM, Tony Lindgren wrote:
> Currently it seems that we need the following working with DT to have panda
> and blaze usable:
>
> 1. MMC (done)
> 2. USB (patches pending for EHCI and MUSB)
> 3. Ethernet (done for blaze, needs USB for panda)
> 4. DSS (various drivers pending, probably still needs some platform init code)
> 5. WLAN (no binding, needs platform init until done)
> 6. Audio (done?)
Yes, audio is ready. We are covering OMAP2/3/4/5 (adding OMAP1 should not be a
big issue either) with SoC IPs in DT support. We have dmaengine for all OMAP
audio stuff. Codec drivers I maintain in upstream are also works with DT. We
have ASoC machine drivers to cover most of the upstream boards (OMAP3/4/5). So
audio is pretty much done in DT context, we are waiting for the DMA bindings
only AFAIK.
--
P?ter
^ permalink raw reply
* [PATCH] ARM: PXA3xx: program the CSMSADRCFG register
From: Haojian Zhuang @ 2013-01-23 8:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMPhdO8LfzvjoE1Re9G44pAZh+-9U7aj5gUWj2xeUyV1ihyRSg@mail.gmail.com>
On Tue, Jan 15, 2013 at 11:01 AM, Eric Miao <eric.y.miao@gmail.com> wrote:
>
> On Sun, Jan 13, 2013 at 7:49 PM, Igor Grinberg <grinberg@compulab.co.il> wrote:
> > The Chip Select Configuration Register must be programmed to 0x2 in
> > order to achieve the correct behavior of the Static Memory Controller.
> >
> > Without this patch devices wired to DFI and accessed through SMC cannot
> > be accessed after resume from S2.
> >
> > Do not rely on the boot loader to program the CSMSADRCFG register by
> > programming it in the kernel smemc module.
> >
>
> Looks good to me. Acked-by: Eric Miao <eric.y.miao@gmail.com>
>
Appled.
Thanks.
Haojian
^ permalink raw reply
* [PATCH V5] drivers/pinctrl: grab default handles from device core
From: Linus Walleij @ 2013-01-23 8:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358877374-1279-1-git-send-email-swarren@wwwdotorg.org>
OK!
This modified version of the patch is way more beautiful, stupid
me for not realizing it could be written like that.
And I can sure live with the removed doc piece ... we can discuss
that separately if need be, I have some argument for it but it's
a separate issue.
I've dubbed this version the v5 variant and applied it, and included
the changelog (so I remember how it came about).
Greg/Mark: are you still confident with your ACK/Reviewed-by
tags being added on this version?
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v2] Dove: activate GPIO interrupts in DT
From: Jean-Francois Moine @ 2013-01-23 8:38 UTC (permalink / raw)
To: linux-arm-kernel
In a DT, the interrupts of an interrupt-controller are not usable when
#interrupt-cells is missing.
This patch activates the interrupts of the GPIOs 0 and 1 for the Marvell
Dove SoC.
Signed-off-by: Jean-Fran?ois Moine <moinejf@free.fr>
---
v2
- gpio-mvebu asks for 2 cells
---
arch/arm/boot/dts/dove.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 42eac1f..740630f 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -93,6 +93,7 @@
reg = <0xd0400 0x20>;
ngpios = <32>;
interrupt-controller;
+ #interrupt-cells = <2>;
interrupts = <12>, <13>, <14>, <60>;
};
@@ -103,6 +104,7 @@
reg = <0xd0420 0x20>;
ngpios = <32>;
interrupt-controller;
+ #interrupt-cells = <2>;
interrupts = <61>;
};
--
Ken ar c'henta? | ** Breizh ha Linux atav! **
Jef | http://moinejf.free.fr/
^ permalink raw reply related
* [PATCH 10/10] gpio: pxa: bind to pinctrl by request
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-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 | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 528f742..d64ec8c 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,17 @@ 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;
+
+ return pinctrl_request_gpio(gpio);
+}
+
static int pxa_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{
struct pxa_gpio_chip *chip = NULL;
@@ -469,6 +481,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 09/10] gpio: pxa: move gpio properties into child node
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-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 | 33 ++++++++-------------------------
1 file changed, 8 insertions(+), 25 deletions(-)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 21cf8fd..528f742 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 const struct irq_domain_ops pxa_irq_domain_ops = {
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);
@@ -432,25 +428,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)
@@ -460,6 +438,7 @@ 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 device_node *next, *np = pdev->dev.of_node;
struct pxa_gpio_chip *chips;
chips = devm_kzalloc(&pdev->dev, nbanks * sizeof(*chips), GFP_KERNEL);
@@ -468,6 +447,7 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
return -ENOMEM;
}
+ next = of_get_next_child(np, NULL);
for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
struct gpio_chip *gc = &chips[i].chip;
@@ -495,7 +475,10 @@ static int pxa_init_gpio_chip(struct platform_device *pdev, int gpio_end,
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_node = next;
+ next = of_get_next_child(np, next);
+ of_node_put(gc->of_node);
+
gc->of_xlate = pxa_gpio_of_xlate;
gc->of_gpio_n_cells = 2;
#endif
--
1.7.10.4
^ permalink raw reply related
* [PATCH 08/10] gpio: pxa: remove arch related macro
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-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 5870944..21cf8fd 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -570,21 +570,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 07/10] gpio: pxa: clean code for compatible name
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-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 67be225..5870944 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 = {
@@ -468,38 +469,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;
@@ -507,10 +507,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;
@@ -549,22 +549,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) {
@@ -606,34 +608,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 06/10] gpio: pxa: define nr gpios in platform data
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-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 ee1fb62..f5aea07 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 = 1,
};
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index 8b4b1ae..2f93f8f 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 = 1,
};
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index 0454488..7f07cc5 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 = 1,
};
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 7ec873c..bf37d97 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 = 1,
};
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index d592041..47808e1 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 = 1,
};
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index a855e69..dd4a22b 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 = 1,
};
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 9f64f37..b3e7bf9 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 = 1,
};
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 74081cd..597268c 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 = 1,
};
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 90415a6..eb82ece 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 = 1,
+ .nr_gpios = 90,
+#else
+ .nr_gpios = 85,
#endif
.gafr = 1,
.gpio_set_wake = gpio_set_wake,
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 91ac5d9..8e6b164 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -423,6 +423,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 = 1,
+ .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 8b3edc7..67be225 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;
-}
-
#ifdef CONFIG_OF
static struct of_device_id pxa_gpio_dt_ids[] = {
{ .compatible = "mrvl,pxa-gpio" },
@@ -433,7 +403,7 @@ static 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;
+ 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 =
@@ -453,6 +423,11 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
ret = of_find_property(np, "marvell,gpio-inverted", NULL);
if (ret)
pdata->inverted = 1;
+ 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;
@@ -470,8 +445,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:
@@ -542,14 +515,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");
@@ -583,6 +550,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 5a9e003..cf17f4c 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -19,6 +19,7 @@ struct pxa_gpio_platform_data {
unsigned ed_mask; /* not 0 means ed_mask reg is available */
unsigned gafr; /* only valid for PXA25x/PXA26x/PXA27x */
unsigned inverted; /* only valid for PXA26x */
+ unsigned nr_gpios;
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 05/10] gpio: pxa: remove gpio_type
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-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 8d77090..90415a6 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 = 1,
#endif
+ .gafr = 1,
.gpio_set_wake = gpio_set_wake,
};
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 257d936..91ac5d9 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -422,6 +422,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 = 1,
.gpio_set_wake = gpio_set_wake,
};
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 6d61a69..8b3edc7 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;
unsigned int inverted;
+ unsigned int 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;
@@ -444,7 +413,7 @@ static int pxa_gpio_nums(void)
#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" },
{}
};
@@ -486,7 +455,6 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
pdata->inverted = 1;
/* set the platform data */
pdev->dev.platform_data = pdata;
- gpio_type = (int)of_id->data;
next = of_get_next_child(np, NULL);
prev = next;
@@ -626,8 +594,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 c8d07be5..5a9e003 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 {
unsigned ed_mask; /* not 0 means ed_mask reg is available */
+ unsigned gafr; /* only valid for PXA25x/PXA26x/PXA27x */
unsigned inverted; /* only valid for PXA26x */
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 04/10] gpio: pxa: use platform data for gpio inverted
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-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 | 41 ++++++++++++++++++++++++++---------------
include/linux/gpio-pxa.h | 1 +
3 files changed, 30 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index f4c293a..8d77090 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 = 1,
+#endif
.gpio_set_wake = gpio_set_wake,
};
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index da6e7fd..6d61a69 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;
+ unsigned int 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);
@@ -475,6 +480,10 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
ret = of_find_property(np, "marvell,gpio-ed-mask", NULL);
if (ret)
pdata->ed_mask = 1;
+ /* It's only valid for PXA26x */
+ ret = of_find_property(np, "marvell,gpio-inverted", NULL);
+ if (ret)
+ pdata->inverted = 1;
/* set the platform data */
pdev->dev.platform_data = pdata;
gpio_type = (int)of_id->data;
@@ -617,6 +626,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 bdee118..c8d07be5 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 {
unsigned ed_mask; /* not 0 means ed_mask reg is available */
+ unsigned inverted; /* only valid for PXA26x */
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
};
--
1.7.10.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox