* [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator
@ 2013-04-24 22:00 Laurent Pinchart
2013-04-25 11:07 ` Mark Brown
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Laurent Pinchart @ 2013-04-24 22:00 UTC (permalink / raw)
To: linux-sh
The sh73a0 has an internal power gate on the VCCQ power supply for the
SDHI0 device that is controlled (for some strange reason) by a bit in a
PFC register. This feature should be exposed as a regulator.
As the same register is also used for pin control purposes there is no
way to achieve atomic read/write sequences with a separate regulator
driver. We thus need to implement the regulator here.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
drivers/pinctrl/sh-pfc/Kconfig | 1 +
drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 134 ++++++++++++++++++++++++++++++++++++
2 files changed, 135 insertions(+)
diff --git a/drivers/pinctrl/sh-pfc/Kconfig b/drivers/pinctrl/sh-pfc/Kconfig
index 103e8bf..4ff2b50 100644
--- a/drivers/pinctrl/sh-pfc/Kconfig
+++ b/drivers/pinctrl/sh-pfc/Kconfig
@@ -72,6 +72,7 @@ config PINCTRL_PFC_SH73A0
def_bool y
depends on ARCH_SH73A0
select PINCTRL_SH_PFC
+ select REGULATOR
config PINCTRL_PFC_SH7720
def_bool y
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
index 587f777..e189146 100644
--- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
+++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
@@ -20,7 +20,11 @@
*/
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/slab.h>
#include <mach/sh73a0.h>
#include <mach/irqs.h>
@@ -3888,6 +3892,92 @@ static const struct pinmux_irq pinmux_irqs[] = {
PINMUX_IRQ(EXT_IRQ16L(9), 308),
};
+/* -----------------------------------------------------------------------------
+ * VCCQ MC0 regulator
+ */
+
+static void sh73a0_vccq_mc0_endisable(struct regulator_dev *reg, bool enable)
+{
+ struct sh_pfc *pfc = reg->reg_data;
+ void __iomem *addr = pfc->window[1].virt + 4;
+ unsigned long flags;
+ u32 value;
+
+ spin_lock_irqsave(&pfc->lock, flags);
+
+ value = ioread32(addr);
+
+ if (enable)
+ value |= BIT(28);
+ else
+ value &= ~BIT(28);
+
+ iowrite32(value, addr);
+
+ spin_unlock_irqrestore(&pfc->lock, flags);
+}
+
+static int sh73a0_vccq_mc0_enable(struct regulator_dev *reg)
+{
+ sh73a0_vccq_mc0_endisable(reg, true);
+ return 0;
+}
+
+static int sh73a0_vccq_mc0_disable(struct regulator_dev *reg)
+{
+ sh73a0_vccq_mc0_endisable(reg, false);
+ return 0;
+}
+
+static int sh73a0_vccq_mc0_is_enabled(struct regulator_dev *reg)
+{
+ struct sh_pfc *pfc = reg->reg_data;
+ void __iomem *addr = pfc->window[1].virt + 4;
+ unsigned long flags;
+ u32 value;
+
+ spin_lock_irqsave(&pfc->lock, flags);
+ value = ioread32(addr);
+ spin_unlock_irqrestore(&pfc->lock, flags);
+
+ return !!(value & BIT(28));
+}
+
+static int sh73a0_vccq_mc0_get_voltage(struct regulator_dev *reg)
+{
+ return 3300000;
+}
+
+static struct regulator_ops sh73a0_vccq_mc0_ops = {
+ .enable = sh73a0_vccq_mc0_enable,
+ .disable = sh73a0_vccq_mc0_disable,
+ .is_enabled = sh73a0_vccq_mc0_is_enabled,
+ .get_voltage = sh73a0_vccq_mc0_get_voltage,
+};
+
+static const struct regulator_desc sh73a0_vccq_mc0_desc = {
+ .owner = THIS_MODULE,
+ .name = "vccq_mc0",
+ .type = REGULATOR_VOLTAGE,
+ .ops = &sh73a0_vccq_mc0_ops,
+};
+
+static struct regulator_consumer_supply sh73a0_vccq_mc0_consumers[] = {
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+};
+
+static const struct regulator_init_data sh73a0_vccq_mc0_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sh73a0_vccq_mc0_consumers),
+ .consumer_supplies = sh73a0_vccq_mc0_consumers,
+};
+
+/* -----------------------------------------------------------------------------
+ * Pin bias
+ */
+
#define PORTnCR_PULMD_OFF (0 << 6)
#define PORTnCR_PULMD_DOWN (2 << 6)
#define PORTnCR_PULMD_UP (3 << 6)
@@ -3934,7 +4024,51 @@ static void sh73a0_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
iowrite8(value, addr);
}
+/* -----------------------------------------------------------------------------
+ * SoC information
+ */
+
+struct sh73a0_pinmux_data {
+ struct regulator_dev *vccq_mc0;
+};
+
+static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
+{
+ struct sh73a0_pinmux_data *data;
+ struct regulator_config cfg = { };
+ int ret;
+
+ data = devm_kzalloc(pfc->dev, sizeof(*data), GFP_KERNEL);
+ if (data = NULL)
+ return -ENOMEM;
+
+ cfg.dev = pfc->dev;
+ cfg.init_data = &sh73a0_vccq_mc0_init_data;
+ cfg.driver_data = pfc;
+
+ data->vccq_mc0 = regulator_register(&sh73a0_vccq_mc0_desc, &cfg);
+ if (IS_ERR(data->vccq_mc0)) {
+ ret = PTR_ERR(data->vccq_mc0);
+ dev_err(pfc->dev, "Failed to register VCCQ MC0 regulator: %d\n",
+ ret);
+ return ret;
+ }
+
+ pfc->soc_data = data;
+
+ return 0;
+}
+
+static void sh73a0_pinmux_soc_cleanup(struct sh_pfc *pfc)
+{
+ struct sh73a0_pinmux_data *data = pfc->soc_data;
+
+ regulator_unregister(data->vccq_mc0);
+}
+
static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = {
+ .init = sh73a0_pinmux_soc_init,
+ .cleanup = sh73a0_pinmux_soc_cleanup,
.get_bias = sh73a0_pinmux_get_bias,
.set_bias = sh73a0_pinmux_set_bias,
};
--
1.8.1.5
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator
2013-04-24 22:00 [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator Laurent Pinchart
@ 2013-04-25 11:07 ` Mark Brown
2013-04-25 11:18 ` Laurent Pinchart
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2013-04-25 11:07 UTC (permalink / raw)
To: linux-sh
[-- Attachment #1: Type: text/plain, Size: 499 bytes --]
On Thu, Apr 25, 2013 at 12:00:26AM +0200, Laurent Pinchart wrote:
> As the same register is also used for pin control purposes there is no
> way to achieve atomic read/write sequences with a separate regulator
> driver. We thus need to implement the regulator here.
You could use an MMIO regmap providing the performance isn't critical
enough for that to cause problems.
But this looks basically OK if we can't do that for some reason.
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator
2013-04-24 22:00 [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator Laurent Pinchart
2013-04-25 11:07 ` Mark Brown
@ 2013-04-25 11:18 ` Laurent Pinchart
2013-04-25 12:16 ` Mark Brown
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Laurent Pinchart @ 2013-04-25 11:18 UTC (permalink / raw)
To: linux-sh
[-- Attachment #1: Type: text/plain, Size: 722 bytes --]
Hi Mark,
On Thursday 25 April 2013 12:07:18 Mark Brown wrote:
> On Thu, Apr 25, 2013 at 12:00:26AM +0200, Laurent Pinchart wrote:
> > As the same register is also used for pin control purposes there is no
> > way to achieve atomic read/write sequences with a separate regulator
> > driver. We thus need to implement the regulator here.
>
> You could use an MMIO regmap providing the performance isn't critical
> enough for that to cause problems.
Can you share a regmap object between two separate drivers for two separate
platform devices ?
> But this looks basically OK if we can't do that for some reason.
>
> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Thank you.
--
Regards,
Laurent Pinchart
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator
2013-04-24 22:00 [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator Laurent Pinchart
2013-04-25 11:07 ` Mark Brown
2013-04-25 11:18 ` Laurent Pinchart
@ 2013-04-25 12:16 ` Mark Brown
2013-04-25 12:27 ` Laurent Pinchart
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2013-04-25 12:16 UTC (permalink / raw)
To: linux-sh
[-- Attachment #1: Type: text/plain, Size: 397 bytes --]
On Thu, Apr 25, 2013 at 01:18:39PM +0200, Laurent Pinchart wrote:
> On Thursday 25 April 2013 12:07:18 Mark Brown wrote:
> > You could use an MMIO regmap providing the performance isn't critical
> > enough for that to cause problems.
> Can you share a regmap object between two separate drivers for two separate
> platform devices ?
Yes, this is commonly done with MFDs for example.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator
2013-04-24 22:00 [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator Laurent Pinchart
` (2 preceding siblings ...)
2013-04-25 12:16 ` Mark Brown
@ 2013-04-25 12:27 ` Laurent Pinchart
2013-04-25 12:37 ` Mark Brown
2013-04-25 13:27 ` Linus Walleij
5 siblings, 0 replies; 7+ messages in thread
From: Laurent Pinchart @ 2013-04-25 12:27 UTC (permalink / raw)
To: linux-sh
[-- Attachment #1: Type: text/plain, Size: 817 bytes --]
On Thursday 25 April 2013 13:16:49 Mark Brown wrote:
> On Thu, Apr 25, 2013 at 01:18:39PM +0200, Laurent Pinchart wrote:
> > On Thursday 25 April 2013 12:07:18 Mark Brown wrote:
> > > You could use an MMIO regmap providing the performance isn't critical
> > > enough for that to cause problems.
> >
> > Can you share a regmap object between two separate drivers for two
> > separate
> > platform devices ?
>
> Yes, this is commonly done with MFDs for example.
I've had a quick look at the code, the regmap is passed through platform data
to the subdevices. With such an approach I could even pass the lock down to
the regulator driver (not that it would be a good idea of course).
I'll push the code as-is for now, but I'll this in mind when migrating the PFC
driver to regmap.
--
Regards,
Laurent Pinchart
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator
2013-04-24 22:00 [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator Laurent Pinchart
` (3 preceding siblings ...)
2013-04-25 12:27 ` Laurent Pinchart
@ 2013-04-25 12:37 ` Mark Brown
2013-04-25 13:27 ` Linus Walleij
5 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2013-04-25 12:37 UTC (permalink / raw)
To: linux-sh
[-- Attachment #1: Type: text/plain, Size: 534 bytes --]
On Thu, Apr 25, 2013 at 02:27:32PM +0200, Laurent Pinchart wrote:
> On Thursday 25 April 2013 13:16:49 Mark Brown wrote:
> > Yes, this is commonly done with MFDs for example.
> I've had a quick look at the code, the regmap is passed through platform data
> to the subdevices. With such an approach I could even pass the lock down to
> the regulator driver (not that it would be a good idea of course).
Yes, or if the subdevice knows that its parent will always have a regmap
it can use dev_get_regmap() on the parent.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator
2013-04-24 22:00 [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator Laurent Pinchart
` (4 preceding siblings ...)
2013-04-25 12:37 ` Mark Brown
@ 2013-04-25 13:27 ` Linus Walleij
5 siblings, 0 replies; 7+ messages in thread
From: Linus Walleij @ 2013-04-25 13:27 UTC (permalink / raw)
To: linux-sh
On Thu, Apr 25, 2013 at 12:00 AM, Laurent Pinchart
<laurent.pinchart+renesas@ideasonboard.com> wrote:
> The sh73a0 has an internal power gate on the VCCQ power supply for the
> SDHI0 device that is controlled (for some strange reason) by a bit in a
> PFC register. This feature should be exposed as a regulator.
>
> As the same register is also used for pin control purposes there is no
> way to achieve atomic read/write sequences with a separate regulator
> driver. We thus need to implement the regulator here.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
As Mark is OK with it too:
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-04-25 13:27 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-24 22:00 [PATCH v2 2/4] sh-pfc: sh73a0: Add VCCQ MC0 regulator Laurent Pinchart
2013-04-25 11:07 ` Mark Brown
2013-04-25 11:18 ` Laurent Pinchart
2013-04-25 12:16 ` Mark Brown
2013-04-25 12:27 ` Laurent Pinchart
2013-04-25 12:37 ` Mark Brown
2013-04-25 13:27 ` Linus Walleij
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox