Re: [PATCH v2 1/3] pinctrl: Add Qualcomm TLMM driver

2014-11-26 Thread Bjorn Andersson
On Tue, Nov 25, 2014 at 11:55 AM, Timur Tabi  wrote:
> On Thu, Dec 5, 2013 at 8:10 PM, Bjorn Andersson
>  wrote:
>>
>> +static int msm_gpio_init(struct msm_pinctrl *pctrl)
>> +{
>> +   struct gpio_chip *chip;
>> +   int irq;
>> +   int ret;
>> +   int i;
>> +   int r;
>> +
>> +   chip = &pctrl->chip;
>> +   chip->base = 0;
>> +   chip->ngpio = pctrl->soc->ngpios;
>
> I know this patch is a year old, but I'm wondering if this line is correct.
>

Hi Timur,

It's always good to review old code, so don't worry about its age of
the patch or code.

> The original version of your patch from 11/23/13 said this:
>
> +   chip->ngpio = pctrl->soc->gpio_range->npins;
>

If you look in patchset 2 (the addition of 8974) you can see that I
passed a pinctrl_gpio_range from the 8974 driver to the common driver;
but I only use this to pass the number of gpios (NUM_GPIO_PINGROUPS).

> and today, the line is this:
>
> unsigned ngpio = pctrl->soc->ngpios;
>

Most likely based on some review comments this was replaced with just
an unsigned 'ngpios'.

> I'm wondering if this line should be instead:
>
> unsigned ngpio = pctrl->soc->npins;
>
> I'm confused about the difference between msm_pinctrl_soc_data.npins
> and msm_pinctrl_soc_data.ngpios.  Variable "ngpio" is used by
> gpiochip_add(), so I think it's not concerned with pin control.
> msm_pinctrl_soc_data.npins appears to be the number of GPIOs, whereas
> msm_pinctrl_soc_data.ngpios appears to be the number of pin groups.
>

The 'ngpio' specifies how many gpio pins/groups (they are 1:1 in the
qcom case) the tlmm block sports, while 'npins' specifies how many
pingroups can be controlled by pinctrl/pinconf/pinmux.

So 'npins' will be 'ngpio' plus the other things that can be
controlled, e.g. sdcc.


The original patch assigns ngpio to be "the number of pinctrl pins in
the gpio range", i.e. a subset of all pins.

Regards,
Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/3] pinctrl: Add Qualcomm TLMM driver

2014-11-25 Thread Timur Tabi
On Thu, Dec 5, 2013 at 8:10 PM, Bjorn Andersson
 wrote:
>
> +static int msm_gpio_init(struct msm_pinctrl *pctrl)
> +{
> +   struct gpio_chip *chip;
> +   int irq;
> +   int ret;
> +   int i;
> +   int r;
> +
> +   chip = &pctrl->chip;
> +   chip->base = 0;
> +   chip->ngpio = pctrl->soc->ngpios;

I know this patch is a year old, but I'm wondering if this line is correct.

The original version of your patch from 11/23/13 said this:

+   chip->ngpio = pctrl->soc->gpio_range->npins;

and today, the line is this:

unsigned ngpio = pctrl->soc->ngpios;

I'm wondering if this line should be instead:

unsigned ngpio = pctrl->soc->npins;

I'm confused about the difference between msm_pinctrl_soc_data.npins
and msm_pinctrl_soc_data.ngpios.  Variable "ngpio" is used by
gpiochip_add(), so I think it's not concerned with pin control.
msm_pinctrl_soc_data.npins appears to be the number of GPIOs, whereas
msm_pinctrl_soc_data.ngpios appears to be the number of pin groups.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/3] pinctrl: Add Qualcomm TLMM driver

2013-12-12 Thread Linus Walleij
On Wed, Dec 11, 2013 at 2:42 AM, Stephen Boyd  wrote:
> On 12/10/13 00:10, Bjorn Andersson wrote:
>> On Fri 06 Dec 13:40 PST 2013, Stephen Boyd wrote:
 +config PINCTRL_MSM
 + bool
>>> Why not tristate?
>>>
>> I have a hard time seeing an situation where you would like to build a system
>> with this driver as a module; it would force almost the entire system to be
>> loaded at a later time...
>
> We're going to need to build everything but the essentials as modules
> for the multi-platform kernel because we're going to run into the
> problem where the kernel can't link anymore. Data heavy drivers such as
> this are  targets for that because they waste more space being built-in
> and they're not absolutely necessary to boot into an initrd that holds
> the modules for a particular device.

This is a quite generic problem rather than a pin control problem.

We're actually going to have to compile quite a few drivers into the
kernel as well, like all irqchips and all clock sources...

I think we have toyed with the idea of tagging code and data so
that it will be discarded on non-matched platforms, I have no
idea how that would look in practice :-(

There are quite a few pin control drivers compiled into any
present multiplatform kernels, so I wouldn't say that one
more or less hurts us today.

 +#include 
 +#include 
 +#include 
 +#include 
>>> Are any of these includes actually necessary? Can't we just forward
>>> declare struct pinctrl_pin_desc?
>>>
>> None of them are needed in the current set of patches, as these are already
>> included in the c-files before including this.
>>
>> But the right set should be: platform_device.h and pinctrl.h.
>
> We should be able to get away with forward declaring the structs we care
> about. C files that include this header should be including the
> pinctrl.h header file anyway, no?

Patches accepted...

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/3] pinctrl: Add Qualcomm TLMM driver

2013-12-10 Thread Stephen Boyd
On 12/10/13 00:10, Bjorn Andersson wrote:
> On Fri 06 Dec 13:40 PST 2013, Stephen Boyd wrote:
>>> +config PINCTRL_MSM
>>> + bool
>> Why not tristate?
>>
> I have a hard time seeing an situation where you would like to build a system
> with this driver as a module; it would force almost the entire system to be
> loaded at a later time...

We're going to need to build everything but the essentials as modules
for the multi-platform kernel because we're going to run into the
problem where the kernel can't link anymore. Data heavy drivers such as
this are  targets for that because they waste more space being built-in
and they're not absolutely necessary to boot into an initrd that holds
the modules for a particular device.

>
>
>>> + val = readl(pctrl->regs + g->intr_cfg_reg);
>>> + val |= BIT(g->intr_raw_status_bit);
>>> + if (g->intr_detection_width == 2) {
>>> + val &= ~(3 << g->intr_detection_bit);
>>> + val &= ~(1 << g->intr_polarity_bit);
>>> + switch (type) {
>>> + case IRQ_TYPE_EDGE_RISING:
>>> + val |= 1 << g->intr_detection_bit;
>>> + val |= BIT(g->intr_polarity_bit);
>>> + break;
>>> + case IRQ_TYPE_EDGE_FALLING:
>>> + val |= 2 << g->intr_detection_bit;
>>> + val |= BIT(g->intr_polarity_bit);
>>> + break;
>>> + case IRQ_TYPE_EDGE_BOTH:
>>> + val |= 3 << g->intr_detection_bit;
>>> + val |= BIT(g->intr_polarity_bit);
>>> + break;
>>> + case IRQ_TYPE_LEVEL_LOW:
>>> + break;
>>> + case IRQ_TYPE_LEVEL_HIGH:
>>> + val |= BIT(g->intr_polarity_bit);
>>> + break;
>>> + }
>>> + } else if (g->intr_detection_width == 1) {
>>> + val &= ~(1 << g->intr_detection_bit);
>>> + val &= ~(1 << g->intr_polarity_bit);
>>> + switch (type) {
>>> + case IRQ_TYPE_EDGE_RISING:
>>> + val |= BIT(g->intr_detection_bit);
>>> + val |= BIT(g->intr_polarity_bit);
>>> + break;
>>> + case IRQ_TYPE_EDGE_FALLING:
>>> + val |= BIT(g->intr_detection_bit);
>>> + break;
>>> + case IRQ_TYPE_EDGE_BOTH:
>>> + val |= BIT(g->intr_detection_bit);
>>> + break;
>>> + case IRQ_TYPE_LEVEL_LOW:
>>> + break;
>>> + case IRQ_TYPE_LEVEL_HIGH:
>>> + val |= BIT(g->intr_polarity_bit);
>>> + break;
>>> + }
>>> + } else {
>>> + BUG();
>>> + }
>> This would be better written as a collection of ifs so that
>> IRQ_TYPE_EDGE_BOTH doesn't have to be tested and we duplicate less code.
>>
> I've rewritten this numerous times and this is the cleanest way I can find
> to do this in. Yes, there's some duplication but it has a cleaner structure
> and easier to follow than the nested if/elseif/else statements.
>
> So I would like to keep it as is.

Isn't this the same?

+ val = readl(pctrl->regs + g->intr_cfg_reg);
+ val |= BIT(g->intr_raw_status_bit);
+
+ detection_mask = BIT(g->intr_detection_width) - 1;
+ val &= ~(detection_mask << g->intr_detection_bit);
+ val &= ~BIT(g->intr_polarity_bit);
+
+ if (type & IRQ_TYPE_EDGE_RISING)
+ val |= BIT(g->intr_detection_bit);
+
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ val |= g->intr_detection_width << g->intr_detection_bit;
+
+ if (!(type & IRQ_TYPE_LEVEL_LOW))
+ val |= BIT(g->intr_polarity_bit);
+

>
>
>
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>> Are any of these includes actually necessary? Can't we just forward
>> declare struct pinctrl_pin_desc?
>>
> None of them are needed in the current set of patches, as these are already
> included in the c-files before including this.
>
> But the right set should be: platform_device.h and pinctrl.h.

We should be able to get away with forward declaring the structs we care
about. C files that include this header should be including the
pinctrl.h header file anyway, no?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/3] pinctrl: Add Qualcomm TLMM driver

2013-12-09 Thread Bjorn Andersson
On Fri 06 Dec 13:40 PST 2013, Stephen Boyd wrote:

> General nitpick: There seems to be a lot of checks for invalid input in
> the op functions. I hope that they're all unnecessary debugging that can
> be removed.
> 

Most of them checks that a gpio number is not larger than the number of 
pingroups.
This would be much cleaner to just replace with a validation in probe().

...
> >
> > +config PINCTRL_MSM
> > + bool
> 
> Why not tristate?
> 

I have a hard time seeing an situation where you would like to build a system
with this driver as a module; it would force almost the entire system to be
loaded at a later time...

> > +/**
> > + * struct msm_pinctrl - state for a pinctrl-msm device
> > + * @dev:device handle.
> > + * @pctrl:  pinctrl handle.
> > + * @domain: irqdomain handle.
> > + * @chip:   gpiochip handle.
> > + * @irq:parent irq for the TLMM irq_chip.
> > + * @lock:   Spinlock to protect register resources as well
> > + *  as msm_pinctrl data structures.
> > + * @enabled_irqs:   Bitmap of currently enabled irqs.
> > + * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
> > + *  detection.
> > + * @wake_irqs:  Bitmap of irqs with requested as wakeup source.
> > + * @soc;Reference to soc_data of platform specific data.
> > + * @regs:   Base address for the TLMM register map.
> > + */
> > +struct msm_pinctrl {
> > + struct device *dev;
> > + struct pinctrl_dev *pctrl;
> > + struct irq_domain *domain;
> > + struct gpio_chip chip;
> > + unsigned irq;
> > +
> > + spinlock_t lock;
> > +
> > + unsigned long *enabled_irqs;
> > + unsigned long *dual_edge_irqs;
> > + unsigned long *wake_irqs;
> 
> In the gpio driver we went with a static upper limit on the bitmap. That
> allowed us to avoid small allocations fragmenting the heap. Please do
> the same here (look at gpio-msm-v2.c).
> 

Sounds reasonable.

> > +static struct pinctrl_ops msm_pinctrl_ops = {
> 
> const?
> 

Of course.

> > +static struct pinmux_ops msm_pinmux_ops = {
> 
> const?
> 

Of course.

> > +static struct pinconf_ops msm_pinconf_ops = {
> 
> const?
> 

Of course.

> > +static int msm_gpio_direction_output(struct gpio_chip *chip, unsigned 
> > offset, int value)
> > +{
> > + const struct msm_pingroup *g;
> > + struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, 
> > chip);
> > + unsigned long flags;
> > + u32 val;
> > +
> > + if (WARN_ON(offset >= pctrl->soc->ngroups))
> > + return -EINVAL;
> 
> How is this possible?
> 

If the soc specific ngpios is greater than ngroups this would happen. But it's 
much better
to catch that earlier!

> > +static void msm_gpio_dbg_show_one(struct seq_file *s,
> > +   struct pinctrl_dev *pctldev,
> > +   struct gpio_chip *chip,
> > +   unsigned offset,
> > +   unsigned gpio)
> > +{
> > + const struct msm_pingroup *g;
> > + struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, 
> > chip);
> > + unsigned func;
> > + int is_out;
> > + int drive;
> > + int pull;
> > + u32 ctl_reg;
> > +
> > + const char *pulls[] = {
> 
> static const char * const ?
> 

Makes sense.
> > + "no pull",
> > + "pull down",
> > + "keeper",
> > + "pull up"
> > + };
> > +
> > + g = &pctrl->soc->groups[offset];
> > + ctl_reg = readl(pctrl->regs + g->ctl_reg);
> > +
> > + is_out = !!(ctl_reg & BIT(g->oe_bit));
> > + func = (ctl_reg >> g->mux_bit) & 7;
> > + drive = (ctl_reg >> g->drv_bit) & 7;
> > + pull = (ctl_reg >> g->pull_bit) & 3;
> > +
> > + seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
> > + seq_printf(s, " %dmA", msm_regval_to_drive[drive]);
> > + seq_printf(s, " %s", pulls[pull]);
> > +}
> > +
> > +static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
> > +{
> > + unsigned gpio = chip->base;
> > + unsigned i;
> > +
> > + for (i = 0; i < chip->ngpio; i++, gpio++) {
> > + msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);
> > + seq_printf(s, "\n");
> 
> seq_puts()?
> 

OK.

> > +static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> > +{
> > + const struct msm_pingroup *g;
> > + struct msm_pinctrl *pctrl;
> > + unsigned long flags;
> > + u32 val;
> > +
> > + pctrl = irq_data_get_irq_chip_data(d);
> > + if (!pctrl)
> > + return -EINVAL;
> 
> How is this possible?
> 

As long as probe() is single threaded this should never be an issue, so I think
it makes sense to drop it.

> > + val = readl(pctrl->regs + g->intr_cfg_reg);
> > + val |= BIT(g->intr_raw_status_bit);
> > + if (g->intr_detection_width == 2) {
> > + val &= ~(3 << g->int

Re: [PATCH v2 1/3] pinctrl: Add Qualcomm TLMM driver

2013-12-06 Thread Stephen Boyd
General nitpick: There seems to be a lot of checks for invalid input in
the op functions. I hope that they're all unnecessary debugging that can
be removed.

On 12/05/13 18:10, Bjorn Andersson wrote:
> This adds a pinctrl, pinmux, pinconf and gpiolib driver for the
> Qualcomm TLMM block.
>
> Signed-off-by: Bjorn Andersson 
> ---
>  drivers/pinctrl/Kconfig   |6 +
>  drivers/pinctrl/Makefile  |1 +
>  drivers/pinctrl/pinctrl-msm.c | 1028 
> +
>  drivers/pinctrl/pinctrl-msm.h |  123 +
>  4 files changed, 1158 insertions(+)
>  create mode 100644 drivers/pinctrl/pinctrl-msm.c
>  create mode 100644 drivers/pinctrl/pinctrl-msm.h
>
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 33f9dc1..d0b6846 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -202,6 +202,12 @@ config PINCTRL_IMX28
>   bool
>   select PINCTRL_MXS
>  
> +config PINCTRL_MSM
> + bool

Why not tristate?

> + select PINMUX
> + select PINCONF
> + select GENERIC_PINCONF
> +
>  config PINCTRL_NOMADIK
>   bool "Nomadik pin controller driver"
>   depends on ARCH_U8500 || ARCH_NOMADIK
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index 4f7be29..a525f8b 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_PINCTRL_FALCON)+= pinctrl-falcon.o
>  obj-$(CONFIG_PINCTRL_MXS)+= pinctrl-mxs.o
>  obj-$(CONFIG_PINCTRL_IMX23)  += pinctrl-imx23.o
>  obj-$(CONFIG_PINCTRL_IMX28)  += pinctrl-imx28.o
> +obj-$(CONFIG_PINCTRL_MSM)+= pinctrl-msm.o
>  obj-$(CONFIG_PINCTRL_NOMADIK)+= pinctrl-nomadik.o
>  obj-$(CONFIG_PINCTRL_STN8815)+= pinctrl-nomadik-stn8815.o
>  obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
> diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
> new file mode 100644
> index 000..28b90ab
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-msm.c
> @@ -0,0 +1,1028 @@
> +/*
> + * Copyright (c) 2013, Sony Mobile Communications AB.
> + * Copyright (c) 2013, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * 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.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "core.h"
> +#include "pinconf.h"
> +#include "pinctrl-msm.h"
> +#include "pinctrl-utils.h"
> +
> +/**
> + * struct msm_pinctrl - state for a pinctrl-msm device
> + * @dev:device handle.
> + * @pctrl:  pinctrl handle.
> + * @domain: irqdomain handle.
> + * @chip:   gpiochip handle.
> + * @irq:parent irq for the TLMM irq_chip.
> + * @lock:   Spinlock to protect register resources as well
> + *  as msm_pinctrl data structures.
> + * @enabled_irqs:   Bitmap of currently enabled irqs.
> + * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
> + *  detection.
> + * @wake_irqs:  Bitmap of irqs with requested as wakeup source.
> + * @soc;Reference to soc_data of platform specific data.
> + * @regs:   Base address for the TLMM register map.
> + */
> +struct msm_pinctrl {
> + struct device *dev;
> + struct pinctrl_dev *pctrl;
> + struct irq_domain *domain;
> + struct gpio_chip chip;
> + unsigned irq;
> +
> + spinlock_t lock;
> +
> + unsigned long *enabled_irqs;
> + unsigned long *dual_edge_irqs;
> + unsigned long *wake_irqs;

In the gpio driver we went with a static upper limit on the bitmap. That
allowed us to avoid small allocations fragmenting the heap. Please do
the same here (look at gpio-msm-v2.c).

> +
> + const struct msm_pinctrl_soc_data *soc;
> + void __iomem *regs;
> +};
> +
> +static int msm_get_groups_count(struct pinctrl_dev *pctldev)
> +{
> + struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
> +
> + return pctrl->soc->ngroups;
> +}
> +
> +static const char *msm_get_group_name(struct pinctrl_dev *pctldev,
> +   unsigned group)
> +{
> + struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
> +
> + return pctrl->soc->groups[group].name;
> +}
> +
> +static int msm_get_group_pins(struct pinctrl_dev *pctldev,
> +   unsigned group,
> +   const unsigned **pins,
> + 

[PATCH v2 1/3] pinctrl: Add Qualcomm TLMM driver

2013-12-05 Thread Bjorn Andersson
This adds a pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block.

Signed-off-by: Bjorn Andersson 
---
 drivers/pinctrl/Kconfig   |6 +
 drivers/pinctrl/Makefile  |1 +
 drivers/pinctrl/pinctrl-msm.c | 1028 +
 drivers/pinctrl/pinctrl-msm.h |  123 +
 4 files changed, 1158 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-msm.c
 create mode 100644 drivers/pinctrl/pinctrl-msm.h

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 33f9dc1..d0b6846 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -202,6 +202,12 @@ config PINCTRL_IMX28
bool
select PINCTRL_MXS
 
+config PINCTRL_MSM
+   bool
+   select PINMUX
+   select PINCONF
+   select GENERIC_PINCONF
+
 config PINCTRL_NOMADIK
bool "Nomadik pin controller driver"
depends on ARCH_U8500 || ARCH_NOMADIK
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 4f7be29..a525f8b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_PINCTRL_FALCON)  += pinctrl-falcon.o
 obj-$(CONFIG_PINCTRL_MXS)  += pinctrl-mxs.o
 obj-$(CONFIG_PINCTRL_IMX23)+= pinctrl-imx23.o
 obj-$(CONFIG_PINCTRL_IMX28)+= pinctrl-imx28.o
+obj-$(CONFIG_PINCTRL_MSM)  += pinctrl-msm.o
 obj-$(CONFIG_PINCTRL_NOMADIK)  += pinctrl-nomadik.o
 obj-$(CONFIG_PINCTRL_STN8815)  += pinctrl-nomadik-stn8815.o
 obj-$(CONFIG_PINCTRL_DB8500)   += pinctrl-nomadik-db8500.o
diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
new file mode 100644
index 000..28b90ab
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-msm.c
@@ -0,0 +1,1028 @@
+/*
+ * Copyright (c) 2013, Sony Mobile Communications AB.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "core.h"
+#include "pinconf.h"
+#include "pinctrl-msm.h"
+#include "pinctrl-utils.h"
+
+/**
+ * struct msm_pinctrl - state for a pinctrl-msm device
+ * @dev:device handle.
+ * @pctrl:  pinctrl handle.
+ * @domain: irqdomain handle.
+ * @chip:   gpiochip handle.
+ * @irq:parent irq for the TLMM irq_chip.
+ * @lock:   Spinlock to protect register resources as well
+ *  as msm_pinctrl data structures.
+ * @enabled_irqs:   Bitmap of currently enabled irqs.
+ * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
+ *  detection.
+ * @wake_irqs:  Bitmap of irqs with requested as wakeup source.
+ * @soc;Reference to soc_data of platform specific data.
+ * @regs:   Base address for the TLMM register map.
+ */
+struct msm_pinctrl {
+   struct device *dev;
+   struct pinctrl_dev *pctrl;
+   struct irq_domain *domain;
+   struct gpio_chip chip;
+   unsigned irq;
+
+   spinlock_t lock;
+
+   unsigned long *enabled_irqs;
+   unsigned long *dual_edge_irqs;
+   unsigned long *wake_irqs;
+
+   const struct msm_pinctrl_soc_data *soc;
+   void __iomem *regs;
+};
+
+static int msm_get_groups_count(struct pinctrl_dev *pctldev)
+{
+   struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+   return pctrl->soc->ngroups;
+}
+
+static const char *msm_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned group)
+{
+   struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+   return pctrl->soc->groups[group].name;
+}
+
+static int msm_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned group,
+ const unsigned **pins,
+ unsigned *num_pins)
+{
+   struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+   *pins = pctrl->soc->groups[group].pins;
+   *num_pins = pctrl->soc->groups[group].npins;
+   return 0;
+}
+
+static struct pinctrl_ops msm_pinctrl_ops = {
+   .get_groups_count   = msm_get_groups_count,
+   .get_group_name = msm_get_group_name,
+   .get_group_pins = msm_get_group_pins,
+   .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
+   .dt_free_map= pinctrl_utils_dt_free_map,
+};
+
+static int msm_get_functions_count(struct pinctrl_dev *pctl