2017-01-13 05:39:03

by Matt Ranostay

[permalink] [raw]
Subject: [PATCH v3 0/2] mmc: pwrseq: add support for Marvell SD8787 chip

Changes from v1:
* split devictree docs from pwrseq changes
* rebase devicetree documents due to filename change
* rebase pwrseq patchset

Changes from v2:
* fix rookie mistake missing the main source file and docs

Matt Ranostay (2):
devicetree: document new marvell-8xxx and pwrseq-sd8787 options
mmc: pwrseq: add support for Marvell SD8787 chip

.../devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt | 14 +++
.../bindings/net/wireless/marvell-8xxx.txt | 7 +-
drivers/mmc/core/Kconfig | 10 ++
drivers/mmc/core/Makefile | 1 +
drivers/mmc/core/pwrseq_sd8787.c | 117 +++++++++++++++++++++
5 files changed, 148 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt
create mode 100644 drivers/mmc/core/pwrseq_sd8787.c

--
2.10.2


2017-01-13 07:17:17

by Shawn Lin

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

On 2017/1/13 13:29, Matt Ranostay wrote:
> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
> This can be abstracted to other chipsets if needed in the future.
>
> Cc: Tony Lindgren <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Signed-off-by: Matt Ranostay <[email protected]>
> ---
> drivers/mmc/core/Kconfig | 10 ++++
> drivers/mmc/core/Makefile | 1 +
> drivers/mmc/core/pwrseq_sd8787.c | 117 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 128 insertions(+)
> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index cdfa8520a4b1..fc1ecdaaa9ca 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
> This driver can also be built as a module. If so, the module
> will be called pwrseq_emmc.
>
> +config PWRSEQ_SD8787
> + tristate "HW reset support for SD8787 BT + Wifi module"
> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
> + help
> + This selects hardware reset support for the SD8787 BT + Wifi
> + module. By default this option is set to n.
> +
> + This driver can also be built as a module. If so, the module
> + will be called pwrseq_sd8787.
> +

I don't like this way, as we have a chance to list lots
configure options here. wifi A,B,C,D...Z, all of them need a
new section here if needed?

Instead, could you just extent pwrseq_simple.c and add you
.compatible = "mmc-pwrseq-sd8787", "mmc-pwrseq-simple"?


> config PWRSEQ_SIMPLE
> tristate "Simple HW reset support for MMC"
> default y
> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
> index b2a257dc644f..0f81464fa824 100644
> --- a/drivers/mmc/core/Makefile
> +++ b/drivers/mmc/core/Makefile
> @@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
> quirks.o slot-gpio.o
> mmc_core-$(CONFIG_OF) += pwrseq.o
> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
> +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
> obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
> diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c
> new file mode 100644
> index 000000000000..f4080fe6439e
> --- /dev/null
> +++ b/drivers/mmc/core/pwrseq_sd8787.c
> @@ -0,0 +1,117 @@
> +/*
> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi chip
> + *
> + * Copyright (C) 2016 Matt Ranostay <[email protected]>
> + *
> + * Based on the original work pwrseq_simple.c
> + * Copyright (C) 2014 Linaro Ltd
> + * Author: Ulf Hansson <[email protected]>
> + *
> + * 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.
> + *
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/gpio/consumer.h>
> +
> +#include <linux/mmc/host.h>
> +
> +#include "pwrseq.h"
> +
> +struct mmc_pwrseq_sd8787 {
> + struct mmc_pwrseq pwrseq;
> + struct gpio_desc *reset_gpio;
> + struct gpio_desc *pwrdn_gpio;
> +};
> +
> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
> +
> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
> +{
> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
> +
> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
> +
> + msleep(300);
> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
> +}
> +
> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
> +{
> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
> +
> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
> +}
> +
> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
> + .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
> + .power_off = mmc_pwrseq_sd8787_power_off,
> +};
> +
> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
> + { .compatible = "mmc-pwrseq-sd8787",},
> + {/* sentinel */},
> +};
> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
> +
> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
> +{
> + struct mmc_pwrseq_sd8787 *pwrseq;
> + struct device *dev = &pdev->dev;
> +
> + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
> + if (!pwrseq)
> + return -ENOMEM;
> +
> + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
> + if (IS_ERR(pwrseq->pwrdn_gpio))
> + return PTR_ERR(pwrseq->pwrdn_gpio);
> +
> + pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(pwrseq->reset_gpio))
> + return PTR_ERR(pwrseq->reset_gpio);
> +
> + pwrseq->pwrseq.dev = dev;
> + pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
> + pwrseq->pwrseq.owner = THIS_MODULE;
> + platform_set_drvdata(pdev, pwrseq);
> +
> + return mmc_pwrseq_register(&pwrseq->pwrseq);
> +}
> +
> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
> +{
> + struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
> +
> + mmc_pwrseq_unregister(&pwrseq->pwrseq);
> +
> + return 0;
> +}
> +
> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
> + .probe = mmc_pwrseq_sd8787_probe,
> + .remove = mmc_pwrseq_sd8787_remove,
> + .driver = {
> + .name = "pwrseq_sd8787",
> + .of_match_table = mmc_pwrseq_sd8787_of_match,
> + },
> +};
> +
> +module_platform_driver(mmc_pwrseq_sd8787_driver);
> +MODULE_LICENSE("GPL v2");
>


--
Best Regards
Shawn Lin

2017-01-19 20:30:32

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

On 19 January 2017 at 21:10, Kalle Valo <[email protected]> wrote:
> Ulf Hansson <[email protected]> writes:
>
>> Twisting my head around how this could be integrated smoothly into
>> pwrseq simple. No, I just can find a good way forward without messing
>> up pwrseq simple itself.
>>
>> So, for now I decided (once more :-), that let's keep this as separate driver!
>>
>> Perhaps, following device specific mmc pwrseq drivers will needs
>> something similar, but in such case we can look into that then.
>> Thinking about cw1200 for example.
>>
>> Let's get Rob's ack for the DT bindings, seems almost there, then I
>> will queue this.
>
> Just to confirm, you will take the whole set (including the bindings
> patch)?

Yes, correct.

Kind regards
Uffe

2017-01-19 14:22:10

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

+Shawn

On 13 January 2017 at 06:29, Matt Ranostay <[email protected]> wrote:
> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
> This can be abstracted to other chipsets if needed in the future.
>
> Cc: Tony Lindgren <[email protected]>
> Cc: Ulf Hansson <[email protected]>
> Signed-off-by: Matt Ranostay <[email protected]>
> ---
> drivers/mmc/core/Kconfig | 10 ++++
> drivers/mmc/core/Makefile | 1 +
> drivers/mmc/core/pwrseq_sd8787.c | 117 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 128 insertions(+)
> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index cdfa8520a4b1..fc1ecdaaa9ca 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
> This driver can also be built as a module. If so, the module
> will be called pwrseq_emmc.
>
> +config PWRSEQ_SD8787
> + tristate "HW reset support for SD8787 BT + Wifi module"
> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
> + help
> + This selects hardware reset support for the SD8787 BT + Wifi
> + module. By default this option is set to n.
> +
> + This driver can also be built as a module. If so, the module
> + will be called pwrseq_sd8787.
> +
> config PWRSEQ_SIMPLE
> tristate "Simple HW reset support for MMC"
> default y
> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
> index b2a257dc644f..0f81464fa824 100644
> --- a/drivers/mmc/core/Makefile
> +++ b/drivers/mmc/core/Makefile
> @@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
> quirks.o slot-gpio.o
> mmc_core-$(CONFIG_OF) += pwrseq.o
> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
> +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
> obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
> diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c
> new file mode 100644
> index 000000000000..f4080fe6439e
> --- /dev/null
> +++ b/drivers/mmc/core/pwrseq_sd8787.c
> @@ -0,0 +1,117 @@
> +/*
> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi chip
> + *
> + * Copyright (C) 2016 Matt Ranostay <[email protected]>
> + *
> + * Based on the original work pwrseq_simple.c
> + * Copyright (C) 2014 Linaro Ltd
> + * Author: Ulf Hansson <[email protected]>
> + *
> + * 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.
> + *
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/gpio/consumer.h>
> +
> +#include <linux/mmc/host.h>
> +
> +#include "pwrseq.h"
> +
> +struct mmc_pwrseq_sd8787 {
> + struct mmc_pwrseq pwrseq;
> + struct gpio_desc *reset_gpio;
> + struct gpio_desc *pwrdn_gpio;
> +};
> +
> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
> +
> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
> +{
> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
> +
> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
> +
> + msleep(300);
> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
> +}
> +
> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
> +{
> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
> +
> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
> +}
> +
> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
> + .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
> + .power_off = mmc_pwrseq_sd8787_power_off,
> +};
> +
> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
> + { .compatible = "mmc-pwrseq-sd8787",},
> + {/* sentinel */},
> +};
> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
> +
> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
> +{
> + struct mmc_pwrseq_sd8787 *pwrseq;
> + struct device *dev = &pdev->dev;
> +
> + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
> + if (!pwrseq)
> + return -ENOMEM;
> +
> + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
> + if (IS_ERR(pwrseq->pwrdn_gpio))
> + return PTR_ERR(pwrseq->pwrdn_gpio);
> +
> + pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(pwrseq->reset_gpio))
> + return PTR_ERR(pwrseq->reset_gpio);
> +
> + pwrseq->pwrseq.dev = dev;
> + pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
> + pwrseq->pwrseq.owner = THIS_MODULE;
> + platform_set_drvdata(pdev, pwrseq);
> +
> + return mmc_pwrseq_register(&pwrseq->pwrseq);
> +}
> +
> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
> +{
> + struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
> +
> + mmc_pwrseq_unregister(&pwrseq->pwrseq);
> +
> + return 0;
> +}
> +
> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
> + .probe = mmc_pwrseq_sd8787_probe,
> + .remove = mmc_pwrseq_sd8787_remove,
> + .driver = {
> + .name = "pwrseq_sd8787",
> + .of_match_table = mmc_pwrseq_sd8787_of_match,
> + },
> +};
> +
> +module_platform_driver(mmc_pwrseq_sd8787_driver);
> +MODULE_LICENSE("GPL v2");
> --
> 2.10.2
>

Twisting my head around how this could be integrated smoothly into
pwrseq simple. No, I just can find a good way forward without messing
up pwrseq simple itself.

So, for now I decided (once more :-), that let's keep this as separate driver!

Perhaps, following device specific mmc pwrseq drivers will needs
something similar, but in such case we can look into that then.
Thinking about cw1200 for example.

Let's get Rob's ack for the DT bindings, seems almost there, then I
will queue this.

Kind regards
Uffe

2017-01-15 21:41:14

by Matt Ranostay

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

On Thu, Jan 12, 2017 at 11:16 PM, Shawn Lin <[email protected]> wrote:
> On 2017/1/13 13:29, Matt Ranostay wrote:
>>
>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>> This can be abstracted to other chipsets if needed in the future.
>>
>> Cc: Tony Lindgren <[email protected]>
>> Cc: Ulf Hansson <[email protected]>
>> Signed-off-by: Matt Ranostay <[email protected]>
>> ---
>> drivers/mmc/core/Kconfig | 10 ++++
>> drivers/mmc/core/Makefile | 1 +
>> drivers/mmc/core/pwrseq_sd8787.c | 117
>> +++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 128 insertions(+)
>> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>
>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>> --- a/drivers/mmc/core/Kconfig
>> +++ b/drivers/mmc/core/Kconfig
>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>> This driver can also be built as a module. If so, the module
>> will be called pwrseq_emmc.
>>
>> +config PWRSEQ_SD8787
>> + tristate "HW reset support for SD8787 BT + Wifi module"
>> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>> + help
>> + This selects hardware reset support for the SD8787 BT + Wifi
>> + module. By default this option is set to n.
>> +
>> + This driver can also be built as a module. If so, the module
>> + will be called pwrseq_sd8787.
>> +
>
>
> I don't like this way, as we have a chance to list lots
> configure options here. wifi A,B,C,D...Z, all of them need a
> new section here if needed?
>
> Instead, could you just extent pwrseq_simple.c and add you
> .compatible = "mmc-pwrseq-sd8787", "mmc-pwrseq-simple"?

You mean all the chipset pwrseqs linked into the pwrseq-simple module?

Ulf your thoughts on this?

>
>
>
>> config PWRSEQ_SIMPLE
>> tristate "Simple HW reset support for MMC"
>> default y
>> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
>> index b2a257dc644f..0f81464fa824 100644
>> --- a/drivers/mmc/core/Makefile
>> +++ b/drivers/mmc/core/Makefile
>> @@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
>> quirks.o slot-gpio.o
>> mmc_core-$(CONFIG_OF) += pwrseq.o
>> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
>> +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
>> obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
>> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
>> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
>> diff --git a/drivers/mmc/core/pwrseq_sd8787.c
>> b/drivers/mmc/core/pwrseq_sd8787.c
>> new file mode 100644
>> index 000000000000..f4080fe6439e
>> --- /dev/null
>> +++ b/drivers/mmc/core/pwrseq_sd8787.c
>> @@ -0,0 +1,117 @@
>> +/*
>> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi
>> chip
>> + *
>> + * Copyright (C) 2016 Matt Ranostay <[email protected]>
>> + *
>> + * Based on the original work pwrseq_simple.c
>> + * Copyright (C) 2014 Linaro Ltd
>> + * Author: Ulf Hansson <[email protected]>
>> + *
>> + * 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.
>> + *
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
>> +#include <linux/device.h>
>> +#include <linux/err.h>
>> +#include <linux/gpio/consumer.h>
>> +
>> +#include <linux/mmc/host.h>
>> +
>> +#include "pwrseq.h"
>> +
>> +struct mmc_pwrseq_sd8787 {
>> + struct mmc_pwrseq pwrseq;
>> + struct gpio_desc *reset_gpio;
>> + struct gpio_desc *pwrdn_gpio;
>> +};
>> +
>> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787,
>> pwrseq)
>> +
>> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
>> +{
>> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>> +
>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
>> +
>> + msleep(300);
>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
>> +}
>> +
>> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
>> +{
>> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>> +
>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
>> +}
>> +
>> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
>> + .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
>> + .power_off = mmc_pwrseq_sd8787_power_off,
>> +};
>> +
>> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
>> + { .compatible = "mmc-pwrseq-sd8787",},
>> + {/* sentinel */},
>> +};
>> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
>> +
>> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
>> +{
>> + struct mmc_pwrseq_sd8787 *pwrseq;
>> + struct device *dev = &pdev->dev;
>> +
>> + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
>> + if (!pwrseq)
>> + return -ENOMEM;
>> +
>> + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
>> + if (IS_ERR(pwrseq->pwrdn_gpio))
>> + return PTR_ERR(pwrseq->pwrdn_gpio);
>> +
>> + pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
>> + if (IS_ERR(pwrseq->reset_gpio))
>> + return PTR_ERR(pwrseq->reset_gpio);
>> +
>> + pwrseq->pwrseq.dev = dev;
>> + pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
>> + pwrseq->pwrseq.owner = THIS_MODULE;
>> + platform_set_drvdata(pdev, pwrseq);
>> +
>> + return mmc_pwrseq_register(&pwrseq->pwrseq);
>> +}
>> +
>> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
>> +{
>> + struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
>> +
>> + mmc_pwrseq_unregister(&pwrseq->pwrseq);
>> +
>> + return 0;
>> +}
>> +
>> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
>> + .probe = mmc_pwrseq_sd8787_probe,
>> + .remove = mmc_pwrseq_sd8787_remove,
>> + .driver = {
>> + .name = "pwrseq_sd8787",
>> + .of_match_table = mmc_pwrseq_sd8787_of_match,
>> + },
>> +};
>> +
>> +module_platform_driver(mmc_pwrseq_sd8787_driver);
>> +MODULE_LICENSE("GPL v2");
>>
>
>
> --
> Best Regards
> Shawn Lin
>

2017-01-19 12:50:05

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

On 18 January 2017 at 08:50, Matt Ranostay <[email protected]> wrote:
> On Sun, Jan 15, 2017 at 6:35 PM, Shawn Lin <[email protected]> wrote:
>> On 2017/1/16 5:41, Matt Ranostay wrote:
>>>
>>> On Thu, Jan 12, 2017 at 11:16 PM, Shawn Lin <[email protected]>
>>> wrote:
>>>>
>>>> On 2017/1/13 13:29, Matt Ranostay wrote:
>>>>>
>>>>>
>>>>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>>>>> This can be abstracted to other chipsets if needed in the future.
>>>>>
>>>>> Cc: Tony Lindgren <[email protected]>
>>>>> Cc: Ulf Hansson <[email protected]>
>>>>> Signed-off-by: Matt Ranostay <[email protected]>
>>>>> ---
>>>>> drivers/mmc/core/Kconfig | 10 ++++
>>>>> drivers/mmc/core/Makefile | 1 +
>>>>> drivers/mmc/core/pwrseq_sd8787.c | 117
>>>>> +++++++++++++++++++++++++++++++++++++++
>>>>> 3 files changed, 128 insertions(+)
>>>>> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>>>>
>>>>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>>>>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>>>>> --- a/drivers/mmc/core/Kconfig
>>>>> +++ b/drivers/mmc/core/Kconfig
>>>>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>>>>> This driver can also be built as a module. If so, the module
>>>>> will be called pwrseq_emmc.
>>>>>
>>>>> +config PWRSEQ_SD8787
>>>>> + tristate "HW reset support for SD8787 BT + Wifi module"
>>>>> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>>>>> + help
>>>>> + This selects hardware reset support for the SD8787 BT + Wifi
>>>>> + module. By default this option is set to n.
>>>>> +
>>>>> + This driver can also be built as a module. If so, the module
>>>>> + will be called pwrseq_sd8787.
>>>>> +
>>>>
>>>>
>>>>
>>>> I don't like this way, as we have a chance to list lots
>>>> configure options here. wifi A,B,C,D...Z, all of them need a
>>>> new section here if needed?
>>>>
>>>> Instead, could you just extent pwrseq_simple.c and add you
>>>> .compatible = "mmc-pwrseq-sd8787", "mmc-pwrseq-simple"?
>>>
>>>
>>> You mean all the chipset pwrseqs linked into the pwrseq-simple module?
>>
>>
>> What I mean was if you just extent the pwrseq-simple a bit, you could
>> just add your chipset pwrseqs linked into the pwrseq-simple. But if you
>> need a different *pattern* of pwrseqs, you should need a new name, for
>> instance, pwrseq-sdio.c etc... But please don't use the name of
>> sd8787? So if I use a wifi named ABC but using the same pwrseq pattenr,
>> should I include your "mmc-pwrseq- sd8787" for that or I need a new
>> mmc-pwrseq-ABC.c?
>
> Ah so pwrseq-sdio.c seems reasonable and having chipsets functions
> defined in a structure. That could be abstracted out for other
> chipsets that could needed in the future.

I think get the idea and it seems reasonable. With that in mind, I
have looked at the code once more and I got some new ideas on how to
adopt pwrseq-simple for your case.

I post the comments separately.

Kind regards
Uffe

2017-01-20 02:54:34

by Shawn Lin

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

On 2017/1/19 22:13, Ulf Hansson wrote:
> +Shawn
>
> On 13 January 2017 at 06:29, Matt Ranostay <[email protected]> wrote:
>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>> This can be abstracted to other chipsets if needed in the future.
>>
>> Cc: Tony Lindgren <[email protected]>
>> Cc: Ulf Hansson <[email protected]>
>> Signed-off-by: Matt Ranostay <[email protected]>
>> ---
>> drivers/mmc/core/Kconfig | 10 ++++
>> drivers/mmc/core/Makefile | 1 +
>> drivers/mmc/core/pwrseq_sd8787.c | 117 +++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 128 insertions(+)
>> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>
>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>> --- a/drivers/mmc/core/Kconfig
>> +++ b/drivers/mmc/core/Kconfig
>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>> This driver can also be built as a module. If so, the module
>> will be called pwrseq_emmc.
>>
>> +config PWRSEQ_SD8787
>> + tristate "HW reset support for SD8787 BT + Wifi module"
>> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>> + help
>> + This selects hardware reset support for the SD8787 BT + Wifi
>> + module. By default this option is set to n.
>> +
>> + This driver can also be built as a module. If so, the module
>> + will be called pwrseq_sd8787.
>> +
>> config PWRSEQ_SIMPLE
>> tristate "Simple HW reset support for MMC"
>> default y
>> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
>> index b2a257dc644f..0f81464fa824 100644
>> --- a/drivers/mmc/core/Makefile
>> +++ b/drivers/mmc/core/Makefile
>> @@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
>> quirks.o slot-gpio.o
>> mmc_core-$(CONFIG_OF) += pwrseq.o
>> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
>> +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
>> obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
>> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
>> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
>> diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c
>> new file mode 100644
>> index 000000000000..f4080fe6439e
>> --- /dev/null
>> +++ b/drivers/mmc/core/pwrseq_sd8787.c
>> @@ -0,0 +1,117 @@
>> +/*
>> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi chip
>> + *
>> + * Copyright (C) 2016 Matt Ranostay <[email protected]>
>> + *
>> + * Based on the original work pwrseq_simple.c
>> + * Copyright (C) 2014 Linaro Ltd
>> + * Author: Ulf Hansson <[email protected]>
>> + *
>> + * 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.
>> + *
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
>> +#include <linux/device.h>
>> +#include <linux/err.h>
>> +#include <linux/gpio/consumer.h>
>> +
>> +#include <linux/mmc/host.h>
>> +
>> +#include "pwrseq.h"
>> +
>> +struct mmc_pwrseq_sd8787 {
>> + struct mmc_pwrseq pwrseq;
>> + struct gpio_desc *reset_gpio;
>> + struct gpio_desc *pwrdn_gpio;
>> +};
>> +
>> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
>> +
>> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
>> +{
>> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>> +
>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
>> +
>> + msleep(300);
>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
>> +}
>> +
>> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
>> +{
>> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>> +
>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
>> +}
>> +
>> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
>> + .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
>> + .power_off = mmc_pwrseq_sd8787_power_off,
>> +};
>> +
>> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
>> + { .compatible = "mmc-pwrseq-sd8787",},
>> + {/* sentinel */},
>> +};
>> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
>> +
>> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
>> +{
>> + struct mmc_pwrseq_sd8787 *pwrseq;
>> + struct device *dev = &pdev->dev;
>> +
>> + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
>> + if (!pwrseq)
>> + return -ENOMEM;
>> +
>> + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
>> + if (IS_ERR(pwrseq->pwrdn_gpio))
>> + return PTR_ERR(pwrseq->pwrdn_gpio);
>> +
>> + pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
>> + if (IS_ERR(pwrseq->reset_gpio))
>> + return PTR_ERR(pwrseq->reset_gpio);
>> +
>> + pwrseq->pwrseq.dev = dev;
>> + pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
>> + pwrseq->pwrseq.owner = THIS_MODULE;
>> + platform_set_drvdata(pdev, pwrseq);
>> +
>> + return mmc_pwrseq_register(&pwrseq->pwrseq);
>> +}
>> +
>> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
>> +{
>> + struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
>> +
>> + mmc_pwrseq_unregister(&pwrseq->pwrseq);
>> +
>> + return 0;
>> +}
>> +
>> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
>> + .probe = mmc_pwrseq_sd8787_probe,
>> + .remove = mmc_pwrseq_sd8787_remove,
>> + .driver = {
>> + .name = "pwrseq_sd8787",
>> + .of_match_table = mmc_pwrseq_sd8787_of_match,
>> + },
>> +};
>> +
>> +module_platform_driver(mmc_pwrseq_sd8787_driver);
>> +MODULE_LICENSE("GPL v2");
>> --
>> 2.10.2
>>
>
> Twisting my head around how this could be integrated smoothly into
> pwrseq simple. No, I just can find a good way forward without messing
> up pwrseq simple itself.
>
> So, for now I decided (once more :-), that let's keep this as separate driver!

I still worry about if there will be more and more seperate drivers. :)

IIRC Peter Chen was trying to move pwrseq out of mmc and use it
for USB stuff. It seems there is no follow-up plan there but should
we invent a new directory to fold in all the pweseq stuff there,
for instance, drivers/mmc/pweseqs/.

>
> Perhaps, following device specific mmc pwrseq drivers will needs
> something similar, but in such case we can look into that then.
> Thinking about cw1200 for example.
>
> Let's get Rob's ack for the DT bindings, seems almost there, then I
> will queue this.
>
> Kind regards
> Uffe
>
>
>


--
Best Regards
Shawn Lin

2017-01-20 07:32:01

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

On 20 January 2017 at 03:42, Shawn Lin <[email protected]> wrote:
> On 2017/1/19 22:13, Ulf Hansson wrote:
>>
>> +Shawn
>>
>> On 13 January 2017 at 06:29, Matt Ranostay <[email protected]>
>> wrote:
>>>
>>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>>> This can be abstracted to other chipsets if needed in the future.
>>>
>>> Cc: Tony Lindgren <[email protected]>
>>> Cc: Ulf Hansson <[email protected]>
>>> Signed-off-by: Matt Ranostay <[email protected]>
>>> ---
>>> drivers/mmc/core/Kconfig | 10 ++++
>>> drivers/mmc/core/Makefile | 1 +
>>> drivers/mmc/core/pwrseq_sd8787.c | 117
>>> +++++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 128 insertions(+)
>>> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>>
>>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>>> --- a/drivers/mmc/core/Kconfig
>>> +++ b/drivers/mmc/core/Kconfig
>>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>>> This driver can also be built as a module. If so, the module
>>> will be called pwrseq_emmc.
>>>
>>> +config PWRSEQ_SD8787
>>> + tristate "HW reset support for SD8787 BT + Wifi module"
>>> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>>> + help
>>> + This selects hardware reset support for the SD8787 BT + Wifi
>>> + module. By default this option is set to n.
>>> +
>>> + This driver can also be built as a module. If so, the module
>>> + will be called pwrseq_sd8787.
>>> +
>>> config PWRSEQ_SIMPLE
>>> tristate "Simple HW reset support for MMC"
>>> default y
>>> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
>>> index b2a257dc644f..0f81464fa824 100644
>>> --- a/drivers/mmc/core/Makefile
>>> +++ b/drivers/mmc/core/Makefile
>>> @@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
>>> quirks.o slot-gpio.o
>>> mmc_core-$(CONFIG_OF) += pwrseq.o
>>> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
>>> +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
>>> obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
>>> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
>>> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
>>> diff --git a/drivers/mmc/core/pwrseq_sd8787.c
>>> b/drivers/mmc/core/pwrseq_sd8787.c
>>> new file mode 100644
>>> index 000000000000..f4080fe6439e
>>> --- /dev/null
>>> +++ b/drivers/mmc/core/pwrseq_sd8787.c
>>> @@ -0,0 +1,117 @@
>>> +/*
>>> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi
>>> chip
>>> + *
>>> + * Copyright (C) 2016 Matt Ranostay <[email protected]>
>>> + *
>>> + * Based on the original work pwrseq_simple.c
>>> + * Copyright (C) 2014 Linaro Ltd
>>> + * Author: Ulf Hansson <[email protected]>
>>> + *
>>> + * 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.
>>> + *
>>> + */
>>> +
>>> +#include <linux/delay.h>
>>> +#include <linux/init.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/module.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/device.h>
>>> +#include <linux/err.h>
>>> +#include <linux/gpio/consumer.h>
>>> +
>>> +#include <linux/mmc/host.h>
>>> +
>>> +#include "pwrseq.h"
>>> +
>>> +struct mmc_pwrseq_sd8787 {
>>> + struct mmc_pwrseq pwrseq;
>>> + struct gpio_desc *reset_gpio;
>>> + struct gpio_desc *pwrdn_gpio;
>>> +};
>>> +
>>> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787,
>>> pwrseq)
>>> +
>>> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq =
>>> to_pwrseq_sd8787(host->pwrseq);
>>> +
>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
>>> +
>>> + msleep(300);
>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
>>> +}
>>> +
>>> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq =
>>> to_pwrseq_sd8787(host->pwrseq);
>>> +
>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
>>> +}
>>> +
>>> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
>>> + .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
>>> + .power_off = mmc_pwrseq_sd8787_power_off,
>>> +};
>>> +
>>> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
>>> + { .compatible = "mmc-pwrseq-sd8787",},
>>> + {/* sentinel */},
>>> +};
>>> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
>>> +
>>> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq;
>>> + struct device *dev = &pdev->dev;
>>> +
>>> + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
>>> + if (!pwrseq)
>>> + return -ENOMEM;
>>> +
>>> + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
>>> + if (IS_ERR(pwrseq->pwrdn_gpio))
>>> + return PTR_ERR(pwrseq->pwrdn_gpio);
>>> +
>>> + pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
>>> + if (IS_ERR(pwrseq->reset_gpio))
>>> + return PTR_ERR(pwrseq->reset_gpio);
>>> +
>>> + pwrseq->pwrseq.dev = dev;
>>> + pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
>>> + pwrseq->pwrseq.owner = THIS_MODULE;
>>> + platform_set_drvdata(pdev, pwrseq);
>>> +
>>> + return mmc_pwrseq_register(&pwrseq->pwrseq);
>>> +}
>>> +
>>> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
>>> +
>>> + mmc_pwrseq_unregister(&pwrseq->pwrseq);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
>>> + .probe = mmc_pwrseq_sd8787_probe,
>>> + .remove = mmc_pwrseq_sd8787_remove,
>>> + .driver = {
>>> + .name = "pwrseq_sd8787",
>>> + .of_match_table = mmc_pwrseq_sd8787_of_match,
>>> + },
>>> +};
>>> +
>>> +module_platform_driver(mmc_pwrseq_sd8787_driver);
>>> +MODULE_LICENSE("GPL v2");
>>> --
>>> 2.10.2
>>>
>>
>> Twisting my head around how this could be integrated smoothly into
>> pwrseq simple. No, I just can find a good way forward without messing
>> up pwrseq simple itself.
>>
>> So, for now I decided (once more :-), that let's keep this as separate
>> driver!
>
>
> I still worry about if there will be more and more seperate drivers. :)

Yes, me to. However, in some cases it's just going to be too device
specific to make a generic pwrseq driver to deal with it.

Also, if we do see that the new Marvell driver can be used together
with some other devices, we can always consider to make it more
generic in a second step.

>
> IIRC Peter Chen was trying to move pwrseq out of mmc and use it
> for USB stuff. It seems there is no follow-up plan there but should
> we invent a new directory to fold in all the pweseq stuff there,
> for instance, drivers/mmc/pweseqs/.

The problem with a new directory is that we need to export the mmc
pwseq interface via a public mmc header. I would rather try to keep as
close as possible to the mmc core.

Although, I also think it's a good idea to look into how to convert
existing mmc pwrseq into using the generic pwrseq instead. Although,
we still need to keep the existing mmc DT bindings, even if we can
mark them as deprecated.

[...]

Kind regards
Uffe

2017-01-13 05:36:23

by Matt Ranostay

[permalink] [raw]
Subject: [PATCH v3 1/2] devicetree: document new marvell-8xxx and pwrseq-sd8787 options

Cc: [email protected]
Signed-off-by: Matt Ranostay <[email protected]>
---
.../devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt | 14 ++++++++++++++
.../devicetree/bindings/net/wireless/marvell-8xxx.txt | 7 ++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt

diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt
new file mode 100644
index 000000000000..1b658351629b
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt
@@ -0,0 +1,14 @@
+* Marvell SD8787 power sequence provider
+
+Required properties:
+- compatible: must be "mmc-pwrseq-sd8787".
+- pwndn-gpio: contains a power down GPIO specifier.
+- reset-gpio: contains a reset GPIO specifier.
+
+Example:
+
+ wifi_pwrseq: wifi_pwrseq {
+ compatible = "mmc-pwrseq-sd8787";
+ pwrdn-gpio = <&twl_gpio 0 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&twl_gpio 1 GPIO_ACTIVE_LOW>;
+ }
diff --git a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt
index 980b16df74c3..0854451ff91d 100644
--- a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt
+++ b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt
@@ -1,4 +1,4 @@
-Marvell 8897/8997 (sd8897/sd8997/pcie8997) SDIO/PCIE devices
+Marvell 8787/8897/8997 (sd8787/sd8897/sd8997/pcie8997) SDIO/PCIE devices
------

This node provides properties for controlling the Marvell SDIO/PCIE wireless device.
@@ -8,6 +8,7 @@ connects the device to the system.
Required properties:

- compatible : should be one of the following:
+ * "marvell,sd8787"
* "marvell,sd8897"
* "marvell,sd8997"
* "pci11ab,2b42"
@@ -34,6 +35,9 @@ Optional properties:
so that the wifi chip can wakeup host platform under certain condition.
during system resume, the irq will be disabled to make sure
unnecessary interrupt is not received.
+ - vmmc-supply: a phandle of a regulator, supplying VCC to the card
+ - mmc-pwrseq: phandle to the MMC power sequence node. See "mmc-pwrseq-*"
+ for documentation of MMC power sequence bindings.

Example:

@@ -46,6 +50,7 @@ so that firmware can wakeup host using this device side pin.
&mmc3 {
status = "okay";
vmmc-supply = <&wlan_en_reg>;
+ mmc-pwrseq = <&wifi_pwrseq>;
bus-width = <4>;
cap-power-off-card;
keep-power-in-suspend;
--
2.10.2

2017-01-18 07:58:19

by Matt Ranostay

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

On Sun, Jan 15, 2017 at 6:35 PM, Shawn Lin <[email protected]> wrote:
> On 2017/1/16 5:41, Matt Ranostay wrote:
>>
>> On Thu, Jan 12, 2017 at 11:16 PM, Shawn Lin <[email protected]>
>> wrote:
>>>
>>> On 2017/1/13 13:29, Matt Ranostay wrote:
>>>>
>>>>
>>>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>>>> This can be abstracted to other chipsets if needed in the future.
>>>>
>>>> Cc: Tony Lindgren <[email protected]>
>>>> Cc: Ulf Hansson <[email protected]>
>>>> Signed-off-by: Matt Ranostay <[email protected]>
>>>> ---
>>>> drivers/mmc/core/Kconfig | 10 ++++
>>>> drivers/mmc/core/Makefile | 1 +
>>>> drivers/mmc/core/pwrseq_sd8787.c | 117
>>>> +++++++++++++++++++++++++++++++++++++++
>>>> 3 files changed, 128 insertions(+)
>>>> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>>>
>>>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>>>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>>>> --- a/drivers/mmc/core/Kconfig
>>>> +++ b/drivers/mmc/core/Kconfig
>>>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>>>> This driver can also be built as a module. If so, the module
>>>> will be called pwrseq_emmc.
>>>>
>>>> +config PWRSEQ_SD8787
>>>> + tristate "HW reset support for SD8787 BT + Wifi module"
>>>> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>>>> + help
>>>> + This selects hardware reset support for the SD8787 BT + Wifi
>>>> + module. By default this option is set to n.
>>>> +
>>>> + This driver can also be built as a module. If so, the module
>>>> + will be called pwrseq_sd8787.
>>>> +
>>>
>>>
>>>
>>> I don't like this way, as we have a chance to list lots
>>> configure options here. wifi A,B,C,D...Z, all of them need a
>>> new section here if needed?
>>>
>>> Instead, could you just extent pwrseq_simple.c and add you
>>> .compatible = "mmc-pwrseq-sd8787", "mmc-pwrseq-simple"?
>>
>>
>> You mean all the chipset pwrseqs linked into the pwrseq-simple module?
>
>
> What I mean was if you just extent the pwrseq-simple a bit, you could
> just add your chipset pwrseqs linked into the pwrseq-simple. But if you
> need a different *pattern* of pwrseqs, you should need a new name, for
> instance, pwrseq-sdio.c etc... But please don't use the name of
> sd8787? So if I use a wifi named ABC but using the same pwrseq pattenr,
> should I include your "mmc-pwrseq- sd8787" for that or I need a new
> mmc-pwrseq-ABC.c?

Ah so pwrseq-sdio.c seems reasonable and having chipsets functions
defined in a structure. That could be abstracted out for other
chipsets that could needed in the future.

- Matt

>
>
>>
>> Ulf your thoughts on this?
>>
>>>
>>>
>>>
>>>> config PWRSEQ_SIMPLE
>>>> tristate "Simple HW reset support for MMC"
>>>> default y
>>>> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
>>>> index b2a257dc644f..0f81464fa824 100644
>>>> --- a/drivers/mmc/core/Makefile
>>>> +++ b/drivers/mmc/core/Makefile
>>>> @@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
>>>> quirks.o slot-gpio.o
>>>> mmc_core-$(CONFIG_OF) += pwrseq.o
>>>> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
>>>> +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
>>>> obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
>>>> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
>>>> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
>>>> diff --git a/drivers/mmc/core/pwrseq_sd8787.c
>>>> b/drivers/mmc/core/pwrseq_sd8787.c
>>>> new file mode 100644
>>>> index 000000000000..f4080fe6439e
>>>> --- /dev/null
>>>> +++ b/drivers/mmc/core/pwrseq_sd8787.c
>>>> @@ -0,0 +1,117 @@
>>>> +/*
>>>> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT +
>>>> Wifi
>>>> chip
>>>> + *
>>>> + * Copyright (C) 2016 Matt Ranostay <[email protected]>
>>>> + *
>>>> + * Based on the original work pwrseq_simple.c
>>>> + * Copyright (C) 2014 Linaro Ltd
>>>> + * Author: Ulf Hansson <[email protected]>
>>>> + *
>>>> + * 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.
>>>> + *
>>>> + */
>>>> +
>>>> +#include <linux/delay.h>
>>>> +#include <linux/init.h>
>>>> +#include <linux/kernel.h>
>>>> +#include <linux/platform_device.h>
>>>> +#include <linux/module.h>
>>>> +#include <linux/slab.h>
>>>> +#include <linux/device.h>
>>>> +#include <linux/err.h>
>>>> +#include <linux/gpio/consumer.h>
>>>> +
>>>> +#include <linux/mmc/host.h>
>>>> +
>>>> +#include "pwrseq.h"
>>>> +
>>>> +struct mmc_pwrseq_sd8787 {
>>>> + struct mmc_pwrseq pwrseq;
>>>> + struct gpio_desc *reset_gpio;
>>>> + struct gpio_desc *pwrdn_gpio;
>>>> +};
>>>> +
>>>> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787,
>>>> pwrseq)
>>>> +
>>>> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
>>>> +{
>>>> + struct mmc_pwrseq_sd8787 *pwrseq =
>>>> to_pwrseq_sd8787(host->pwrseq);
>>>> +
>>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
>>>> +
>>>> + msleep(300);
>>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
>>>> +}
>>>> +
>>>> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
>>>> +{
>>>> + struct mmc_pwrseq_sd8787 *pwrseq =
>>>> to_pwrseq_sd8787(host->pwrseq);
>>>> +
>>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
>>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
>>>> +}
>>>> +
>>>> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
>>>> + .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
>>>> + .power_off = mmc_pwrseq_sd8787_power_off,
>>>> +};
>>>> +
>>>> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
>>>> + { .compatible = "mmc-pwrseq-sd8787",},
>>>> + {/* sentinel */},
>>>> +};
>>>> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
>>>> +
>>>> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
>>>> +{
>>>> + struct mmc_pwrseq_sd8787 *pwrseq;
>>>> + struct device *dev = &pdev->dev;
>>>> +
>>>> + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
>>>> + if (!pwrseq)
>>>> + return -ENOMEM;
>>>> +
>>>> + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn",
>>>> GPIOD_OUT_LOW);
>>>> + if (IS_ERR(pwrseq->pwrdn_gpio))
>>>> + return PTR_ERR(pwrseq->pwrdn_gpio);
>>>> +
>>>> + pwrseq->reset_gpio = devm_gpiod_get(dev, "reset",
>>>> GPIOD_OUT_LOW);
>>>> + if (IS_ERR(pwrseq->reset_gpio))
>>>> + return PTR_ERR(pwrseq->reset_gpio);
>>>> +
>>>> + pwrseq->pwrseq.dev = dev;
>>>> + pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
>>>> + pwrseq->pwrseq.owner = THIS_MODULE;
>>>> + platform_set_drvdata(pdev, pwrseq);
>>>> +
>>>> + return mmc_pwrseq_register(&pwrseq->pwrseq);
>>>> +}
>>>> +
>>>> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
>>>> +{
>>>> + struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
>>>> +
>>>> + mmc_pwrseq_unregister(&pwrseq->pwrseq);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
>>>> + .probe = mmc_pwrseq_sd8787_probe,
>>>> + .remove = mmc_pwrseq_sd8787_remove,
>>>> + .driver = {
>>>> + .name = "pwrseq_sd8787",
>>>> + .of_match_table = mmc_pwrseq_sd8787_of_match,
>>>> + },
>>>> +};
>>>> +
>>>> +module_platform_driver(mmc_pwrseq_sd8787_driver);
>>>> +MODULE_LICENSE("GPL v2");
>>>>
>>>
>>>
>>> --
>>> Best Regards
>>> Shawn Lin
>>>
>>
>>
>>
>
>
> --
> Best Regards
> Shawn Lin
>

2017-01-13 05:36:51

by Matt Ranostay

[permalink] [raw]
Subject: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
This can be abstracted to other chipsets if needed in the future.

Cc: Tony Lindgren <[email protected]>
Cc: Ulf Hansson <[email protected]>
Signed-off-by: Matt Ranostay <[email protected]>
---
drivers/mmc/core/Kconfig | 10 ++++
drivers/mmc/core/Makefile | 1 +
drivers/mmc/core/pwrseq_sd8787.c | 117 +++++++++++++++++++++++++++++++++++++++
3 files changed, 128 insertions(+)
create mode 100644 drivers/mmc/core/pwrseq_sd8787.c

diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index cdfa8520a4b1..fc1ecdaaa9ca 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -12,6 +12,16 @@ config PWRSEQ_EMMC
This driver can also be built as a module. If so, the module
will be called pwrseq_emmc.

+config PWRSEQ_SD8787
+ tristate "HW reset support for SD8787 BT + Wifi module"
+ depends on OF && (MWIFIEX || BT_MRVL_SDIO)
+ help
+ This selects hardware reset support for the SD8787 BT + Wifi
+ module. By default this option is set to n.
+
+ This driver can also be built as a module. If so, the module
+ will be called pwrseq_sd8787.
+
config PWRSEQ_SIMPLE
tristate "Simple HW reset support for MMC"
default y
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index b2a257dc644f..0f81464fa824 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
quirks.o slot-gpio.o
mmc_core-$(CONFIG_OF) += pwrseq.o
obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
+obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c
new file mode 100644
index 000000000000..f4080fe6439e
--- /dev/null
+++ b/drivers/mmc/core/pwrseq_sd8787.c
@@ -0,0 +1,117 @@
+/*
+ * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi chip
+ *
+ * Copyright (C) 2016 Matt Ranostay <[email protected]>
+ *
+ * Based on the original work pwrseq_simple.c
+ * Copyright (C) 2014 Linaro Ltd
+ * Author: Ulf Hansson <[email protected]>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+
+#include <linux/mmc/host.h>
+
+#include "pwrseq.h"
+
+struct mmc_pwrseq_sd8787 {
+ struct mmc_pwrseq pwrseq;
+ struct gpio_desc *reset_gpio;
+ struct gpio_desc *pwrdn_gpio;
+};
+
+#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
+
+static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
+{
+ struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
+
+ gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
+
+ msleep(300);
+ gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
+}
+
+static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
+{
+ struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
+
+ gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
+ gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
+}
+
+static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
+ .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
+ .power_off = mmc_pwrseq_sd8787_power_off,
+};
+
+static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
+ { .compatible = "mmc-pwrseq-sd8787",},
+ {/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
+
+static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
+{
+ struct mmc_pwrseq_sd8787 *pwrseq;
+ struct device *dev = &pdev->dev;
+
+ pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
+ if (!pwrseq)
+ return -ENOMEM;
+
+ pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
+ if (IS_ERR(pwrseq->pwrdn_gpio))
+ return PTR_ERR(pwrseq->pwrdn_gpio);
+
+ pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(pwrseq->reset_gpio))
+ return PTR_ERR(pwrseq->reset_gpio);
+
+ pwrseq->pwrseq.dev = dev;
+ pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
+ pwrseq->pwrseq.owner = THIS_MODULE;
+ platform_set_drvdata(pdev, pwrseq);
+
+ return mmc_pwrseq_register(&pwrseq->pwrseq);
+}
+
+static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
+{
+ struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
+
+ mmc_pwrseq_unregister(&pwrseq->pwrseq);
+
+ return 0;
+}
+
+static struct platform_driver mmc_pwrseq_sd8787_driver = {
+ .probe = mmc_pwrseq_sd8787_probe,
+ .remove = mmc_pwrseq_sd8787_remove,
+ .driver = {
+ .name = "pwrseq_sd8787",
+ .of_match_table = mmc_pwrseq_sd8787_of_match,
+ },
+};
+
+module_platform_driver(mmc_pwrseq_sd8787_driver);
+MODULE_LICENSE("GPL v2");
--
2.10.2

2017-01-18 22:02:10

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] devicetree: document new marvell-8xxx and pwrseq-sd8787 options

On Thu, Jan 12, 2017 at 09:29:36PM -0800, Matt Ranostay wrote:

Changelog?

> Cc: [email protected]
> Signed-off-by: Matt Ranostay <[email protected]>
> ---
> .../devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt | 14 ++++++++++++++
> .../devicetree/bindings/net/wireless/marvell-8xxx.txt | 7 ++++++-
> 2 files changed, 20 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt
>
> diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt
> new file mode 100644
> index 000000000000..1b658351629b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt
> @@ -0,0 +1,14 @@
> +* Marvell SD8787 power sequence provider
> +
> +Required properties:
> +- compatible: must be "mmc-pwrseq-sd8787".
> +- pwndn-gpio: contains a power down GPIO specifier.

powerdown-gpios

> +- reset-gpio: contains a reset GPIO specifier.

reset-gpios

And state the active state for both.

> +
> +Example:
> +
> + wifi_pwrseq: wifi_pwrseq {
> + compatible = "mmc-pwrseq-sd8787";
> + pwrdn-gpio = <&twl_gpio 0 GPIO_ACTIVE_LOW>;
> + reset-gpio = <&twl_gpio 1 GPIO_ACTIVE_LOW>;
> + }
> diff --git a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt
> index 980b16df74c3..0854451ff91d 100644
> --- a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt
> +++ b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt
> @@ -1,4 +1,4 @@
> -Marvell 8897/8997 (sd8897/sd8997/pcie8997) SDIO/PCIE devices
> +Marvell 8787/8897/8997 (sd8787/sd8897/sd8997/pcie8997) SDIO/PCIE devices
> ------
>
> This node provides properties for controlling the Marvell SDIO/PCIE wireless device.
> @@ -8,6 +8,7 @@ connects the device to the system.
> Required properties:
>
> - compatible : should be one of the following:
> + * "marvell,sd8787"
> * "marvell,sd8897"
> * "marvell,sd8997"
> * "pci11ab,2b42"
> @@ -34,6 +35,9 @@ Optional properties:
> so that the wifi chip can wakeup host platform under certain condition.
> during system resume, the irq will be disabled to make sure
> unnecessary interrupt is not received.
> + - vmmc-supply: a phandle of a regulator, supplying VCC to the card
> + - mmc-pwrseq: phandle to the MMC power sequence node. See "mmc-pwrseq-*"
> + for documentation of MMC power sequence bindings.
>
> Example:
>
> @@ -46,6 +50,7 @@ so that firmware can wakeup host using this device side pin.
> &mmc3 {
> status = "okay";
> vmmc-supply = <&wlan_en_reg>;
> + mmc-pwrseq = <&wifi_pwrseq>;
> bus-width = <4>;
> cap-power-off-card;
> keep-power-in-suspend;
> --
> 2.10.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2017-01-16 02:36:24

by Shawn Lin

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

On 2017/1/16 5:41, Matt Ranostay wrote:
> On Thu, Jan 12, 2017 at 11:16 PM, Shawn Lin <[email protected]> wrote:
>> On 2017/1/13 13:29, Matt Ranostay wrote:
>>>
>>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>>> This can be abstracted to other chipsets if needed in the future.
>>>
>>> Cc: Tony Lindgren <[email protected]>
>>> Cc: Ulf Hansson <[email protected]>
>>> Signed-off-by: Matt Ranostay <[email protected]>
>>> ---
>>> drivers/mmc/core/Kconfig | 10 ++++
>>> drivers/mmc/core/Makefile | 1 +
>>> drivers/mmc/core/pwrseq_sd8787.c | 117
>>> +++++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 128 insertions(+)
>>> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>>
>>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>>> --- a/drivers/mmc/core/Kconfig
>>> +++ b/drivers/mmc/core/Kconfig
>>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>>> This driver can also be built as a module. If so, the module
>>> will be called pwrseq_emmc.
>>>
>>> +config PWRSEQ_SD8787
>>> + tristate "HW reset support for SD8787 BT + Wifi module"
>>> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>>> + help
>>> + This selects hardware reset support for the SD8787 BT + Wifi
>>> + module. By default this option is set to n.
>>> +
>>> + This driver can also be built as a module. If so, the module
>>> + will be called pwrseq_sd8787.
>>> +
>>
>>
>> I don't like this way, as we have a chance to list lots
>> configure options here. wifi A,B,C,D...Z, all of them need a
>> new section here if needed?
>>
>> Instead, could you just extent pwrseq_simple.c and add you
>> .compatible = "mmc-pwrseq-sd8787", "mmc-pwrseq-simple"?
>
> You mean all the chipset pwrseqs linked into the pwrseq-simple module?

What I mean was if you just extent the pwrseq-simple a bit, you could
just add your chipset pwrseqs linked into the pwrseq-simple. But if you
need a different *pattern* of pwrseqs, you should need a new name, for
instance, pwrseq-sdio.c etc... But please don't use the name of
sd8787? So if I use a wifi named ABC but using the same pwrseq pattenr,
should I include your "mmc-pwrseq- sd8787" for that or I need a new
mmc-pwrseq-ABC.c?

>
> Ulf your thoughts on this?
>
>>
>>
>>
>>> config PWRSEQ_SIMPLE
>>> tristate "Simple HW reset support for MMC"
>>> default y
>>> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
>>> index b2a257dc644f..0f81464fa824 100644
>>> --- a/drivers/mmc/core/Makefile
>>> +++ b/drivers/mmc/core/Makefile
>>> @@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
>>> quirks.o slot-gpio.o
>>> mmc_core-$(CONFIG_OF) += pwrseq.o
>>> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
>>> +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
>>> obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
>>> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
>>> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
>>> diff --git a/drivers/mmc/core/pwrseq_sd8787.c
>>> b/drivers/mmc/core/pwrseq_sd8787.c
>>> new file mode 100644
>>> index 000000000000..f4080fe6439e
>>> --- /dev/null
>>> +++ b/drivers/mmc/core/pwrseq_sd8787.c
>>> @@ -0,0 +1,117 @@
>>> +/*
>>> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi
>>> chip
>>> + *
>>> + * Copyright (C) 2016 Matt Ranostay <[email protected]>
>>> + *
>>> + * Based on the original work pwrseq_simple.c
>>> + * Copyright (C) 2014 Linaro Ltd
>>> + * Author: Ulf Hansson <[email protected]>
>>> + *
>>> + * 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.
>>> + *
>>> + */
>>> +
>>> +#include <linux/delay.h>
>>> +#include <linux/init.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/module.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/device.h>
>>> +#include <linux/err.h>
>>> +#include <linux/gpio/consumer.h>
>>> +
>>> +#include <linux/mmc/host.h>
>>> +
>>> +#include "pwrseq.h"
>>> +
>>> +struct mmc_pwrseq_sd8787 {
>>> + struct mmc_pwrseq pwrseq;
>>> + struct gpio_desc *reset_gpio;
>>> + struct gpio_desc *pwrdn_gpio;
>>> +};
>>> +
>>> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787,
>>> pwrseq)
>>> +
>>> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>>> +
>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
>>> +
>>> + msleep(300);
>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
>>> +}
>>> +
>>> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>>> +
>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
>>> +}
>>> +
>>> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
>>> + .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
>>> + .power_off = mmc_pwrseq_sd8787_power_off,
>>> +};
>>> +
>>> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
>>> + { .compatible = "mmc-pwrseq-sd8787",},
>>> + {/* sentinel */},
>>> +};
>>> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
>>> +
>>> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq;
>>> + struct device *dev = &pdev->dev;
>>> +
>>> + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
>>> + if (!pwrseq)
>>> + return -ENOMEM;
>>> +
>>> + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
>>> + if (IS_ERR(pwrseq->pwrdn_gpio))
>>> + return PTR_ERR(pwrseq->pwrdn_gpio);
>>> +
>>> + pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
>>> + if (IS_ERR(pwrseq->reset_gpio))
>>> + return PTR_ERR(pwrseq->reset_gpio);
>>> +
>>> + pwrseq->pwrseq.dev = dev;
>>> + pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
>>> + pwrseq->pwrseq.owner = THIS_MODULE;
>>> + platform_set_drvdata(pdev, pwrseq);
>>> +
>>> + return mmc_pwrseq_register(&pwrseq->pwrseq);
>>> +}
>>> +
>>> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
>>> +{
>>> + struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
>>> +
>>> + mmc_pwrseq_unregister(&pwrseq->pwrseq);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
>>> + .probe = mmc_pwrseq_sd8787_probe,
>>> + .remove = mmc_pwrseq_sd8787_remove,
>>> + .driver = {
>>> + .name = "pwrseq_sd8787",
>>> + .of_match_table = mmc_pwrseq_sd8787_of_match,
>>> + },
>>> +};
>>> +
>>> +module_platform_driver(mmc_pwrseq_sd8787_driver);
>>> +MODULE_LICENSE("GPL v2");
>>>
>>
>>
>> --
>> Best Regards
>> Shawn Lin
>>
>
>
>


--
Best Regards
Shawn Lin

2017-01-19 20:10:27

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip

Ulf Hansson <[email protected]> writes:

> Twisting my head around how this could be integrated smoothly into
> pwrseq simple. No, I just can find a good way forward without messing
> up pwrseq simple itself.
>
> So, for now I decided (once more :-), that let's keep this as separate driver!
>
> Perhaps, following device specific mmc pwrseq drivers will needs
> something similar, but in such case we can look into that then.
> Thinking about cw1200 for example.
>
> Let's get Rob's ack for the DT bindings, seems almost there, then I
> will queue this.

Just to confirm, you will take the whole set (including the bindings
patch)?

--
Kalle Valo