Devicetree
 help / color / mirror / Atom feed
* [PATCH v6 2/2] mmc: host: s3cmci: allow probing from device tree
From: Sergio Prado @ 2017-03-31 23:50 UTC (permalink / raw)
  To: ulf.hansson, robh+dt, mark.rutland, linux-mmc, devicetree,
	linux-kernel, ben-linux, linux-arm-kernel
  Cc: Sergio Prado
In-Reply-To: <1491004256-13969-1-git-send-email-sergio.prado@e-labworks.com>

Allows configuring Samsung S3C24XX MMC/SD/SDIO controller using a device
tree.

Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
 drivers/mmc/host/s3cmci.c | 257 +++++++++++++++++++++++-----------------------
 1 file changed, 126 insertions(+), 131 deletions(-)

diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 7a173f8c455b..c101f7e178f7 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -24,6 +24,10 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/mmc/slot-gpio.h>
 
 #include <plat/gpio-cfg.h>
 #include <mach/dma.h>
@@ -807,21 +811,6 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
 
 }
 
-/*
- * ISR for the CardDetect Pin
-*/
-
-static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id)
-{
-	struct s3cmci_host *host = (struct s3cmci_host *)dev_id;
-
-	dbg(host, dbg_irq, "card detect\n");
-
-	mmc_detect_change(host->mmc, msecs_to_jiffies(500));
-
-	return IRQ_HANDLED;
-}
-
 static void s3cmci_dma_done_callback(void *arg)
 {
 	struct s3cmci_host *host = arg;
@@ -1177,19 +1166,6 @@ static void s3cmci_send_request(struct mmc_host *mmc)
 	s3cmci_enable_irq(host, true);
 }
 
-static int s3cmci_card_present(struct mmc_host *mmc)
-{
-	struct s3cmci_host *host = mmc_priv(mmc);
-	struct s3c24xx_mci_pdata *pdata = host->pdata;
-	int ret;
-
-	if (pdata->no_detect)
-		return -ENOSYS;
-
-	ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
-	return ret ^ pdata->detect_invert;
-}
-
 static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct s3cmci_host *host = mmc_priv(mmc);
@@ -1198,7 +1174,7 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	host->cmd_is_stop = 0;
 	host->mrq = mrq;
 
-	if (s3cmci_card_present(mmc) == 0) {
+	if (mmc_gpio_get_cd(mmc) == 0) {
 		dbg(host, dbg_err, "%s: no medium present\n", __func__);
 		host->mrq->cmd->error = -ENOMEDIUM;
 		mmc_request_done(mmc, mrq);
@@ -1242,8 +1218,9 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	case MMC_POWER_ON:
 	case MMC_POWER_UP:
 		/* Configure GPE5...GPE10 pins in SD mode */
-		s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
-				      S3C_GPIO_PULL_NONE);
+		if (!host->pdev->dev.of_node)
+			s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
+					      S3C_GPIO_PULL_NONE);
 
 		if (host->pdata->set_power)
 			host->pdata->set_power(ios->power_mode, ios->vdd);
@@ -1255,7 +1232,8 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
 	case MMC_POWER_OFF:
 	default:
-		gpio_direction_output(S3C2410_GPE(5), 0);
+		if (!host->pdev->dev.of_node)
+			gpio_direction_output(S3C2410_GPE(5), 0);
 
 		if (host->is2440)
 			mci_con |= S3C2440_SDICON_SDRESET;
@@ -1295,21 +1273,6 @@ static void s3cmci_reset(struct s3cmci_host *host)
 	writel(con, host->base + S3C2410_SDICON);
 }
 
-static int s3cmci_get_ro(struct mmc_host *mmc)
-{
-	struct s3cmci_host *host = mmc_priv(mmc);
-	struct s3c24xx_mci_pdata *pdata = host->pdata;
-	int ret;
-
-	if (pdata->no_wprotect)
-		return 0;
-
-	ret = gpio_get_value(pdata->gpio_wprotect) ? 1 : 0;
-	ret ^= pdata->wprotect_invert;
-
-	return ret;
-}
-
 static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
 	struct s3cmci_host *host = mmc_priv(mmc);
@@ -1353,8 +1316,8 @@ static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
 static struct mmc_host_ops s3cmci_ops = {
 	.request	= s3cmci_request,
 	.set_ios	= s3cmci_set_ios,
-	.get_ro		= s3cmci_get_ro,
-	.get_cd		= s3cmci_card_present,
+	.get_ro		= mmc_gpio_get_ro,
+	.get_cd		= mmc_gpio_get_cd,
 	.enable_sdio_irq = s3cmci_enable_sdio_irq,
 };
 
@@ -1545,21 +1508,14 @@ static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
 
 #endif /* CONFIG_DEBUG_FS */
 
-static int s3cmci_probe(struct platform_device *pdev)
+static int s3cmci_probe_pdata(struct s3cmci_host *host)
 {
-	struct s3cmci_host *host;
-	struct mmc_host	*mmc;
-	int ret;
-	int is2440;
-	int i;
+	struct platform_device *pdev = host->pdev;
+	struct mmc_host *mmc = host->mmc;
+	struct s3c24xx_mci_pdata *pdata;
+	int i, ret;
 
-	is2440 = platform_get_device_id(pdev)->driver_data;
-
-	mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
-	if (!mmc) {
-		ret = -ENOMEM;
-		goto probe_out;
-	}
+	host->is2440 = platform_get_device_id(pdev)->driver_data;
 
 	for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
 		ret = gpio_request(i, dev_name(&pdev->dev));
@@ -1569,25 +1525,101 @@ static int s3cmci_probe(struct platform_device *pdev)
 			for (i--; i >= S3C2410_GPE(5); i--)
 				gpio_free(i);
 
-			goto probe_free_host;
+			return ret;
+		}
+	}
+
+	if (!pdev->dev.platform_data)
+		pdev->dev.platform_data = &s3cmci_def_pdata;
+
+	pdata = pdev->dev.platform_data;
+
+	if (pdata->no_wprotect)
+		mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
+
+	if (pdata->no_detect)
+		mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+	if (pdata->wprotect_invert);
+		mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+
+	if (pdata->detect_invert)
+		 mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+
+	if (gpio_is_valid(pdata->gpio_detect)) {
+		ret = mmc_gpio_request_cd(mmc, pdata->gpio_detect, 0);
+		if (ret) {
+			dev_err(&pdev->dev, "error requesting GPIO for CD %d\n",
+				ret);
+			return ret;
 		}
 	}
 
+	if (gpio_is_valid(pdata->gpio_wprotect)) {
+		ret = mmc_gpio_request_ro(mmc, pdata->gpio_wprotect);
+		if (ret) {
+			dev_err(&pdev->dev, "error requesting GPIO for WP %d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int s3cmci_probe_dt(struct s3cmci_host *host)
+{
+	struct platform_device *pdev = host->pdev;
+	struct s3c24xx_mci_pdata *pdata;
+	struct mmc_host *mmc = host->mmc;
+	int ret;
+
+	host->is2440 = (int) of_device_get_match_data(&pdev->dev);
+
+	ret = mmc_of_parse(mmc);
+	if (ret)
+		return ret;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	pdev->dev.platform_data = pdata;
+
+	return 0;
+}
+
+static int s3cmci_probe(struct platform_device *pdev)
+{
+	struct s3cmci_host *host;
+	struct mmc_host	*mmc;
+	int ret;
+	int i;
+
+	mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto probe_out;
+	}
+
 	host = mmc_priv(mmc);
 	host->mmc 	= mmc;
 	host->pdev	= pdev;
-	host->is2440	= is2440;
+
+	if (pdev->dev.of_node)
+		ret = s3cmci_probe_dt(host);
+	else
+		ret = s3cmci_probe_pdata(host);
+
+	if (ret)
+		goto probe_free_host;
 
 	host->pdata = pdev->dev.platform_data;
-	if (!host->pdata) {
-		pdev->dev.platform_data = &s3cmci_def_pdata;
-		host->pdata = &s3cmci_def_pdata;
-	}
 
 	spin_lock_init(&host->complete_lock);
 	tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
 
-	if (is2440) {
+	if (host->is2440) {
 		host->sdiimsk	= S3C2440_SDIIMSK;
 		host->sdidata	= S3C2440_SDIDATA;
 		host->clk_div	= 1;
@@ -1645,43 +1677,6 @@ static int s3cmci_probe(struct platform_device *pdev)
 	disable_irq(host->irq);
 	host->irq_state = false;
 
-	if (!host->pdata->no_detect) {
-		ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");
-		if (ret) {
-			dev_err(&pdev->dev, "failed to get detect gpio\n");
-			goto probe_free_irq;
-		}
-
-		host->irq_cd = gpio_to_irq(host->pdata->gpio_detect);
-
-		if (host->irq_cd >= 0) {
-			if (request_irq(host->irq_cd, s3cmci_irq_cd,
-					IRQF_TRIGGER_RISING |
-					IRQF_TRIGGER_FALLING,
-					DRIVER_NAME, host)) {
-				dev_err(&pdev->dev,
-					"can't get card detect irq.\n");
-				ret = -ENOENT;
-				goto probe_free_gpio_cd;
-			}
-		} else {
-			dev_warn(&pdev->dev,
-				 "host detect has no irq available\n");
-			gpio_direction_input(host->pdata->gpio_detect);
-		}
-	} else
-		host->irq_cd = -1;
-
-	if (!host->pdata->no_wprotect) {
-		ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");
-		if (ret) {
-			dev_err(&pdev->dev, "failed to get writeprotect\n");
-			goto probe_free_irq_cd;
-		}
-
-		gpio_direction_input(host->pdata->gpio_wprotect);
-	}
-
 	/* Depending on the dma state, get a DMA channel to use. */
 
 	if (s3cmci_host_usedma(host)) {
@@ -1689,7 +1684,7 @@ static int s3cmci_probe(struct platform_device *pdev)
 		ret = PTR_ERR_OR_ZERO(host->dma);
 		if (ret) {
 			dev_err(&pdev->dev, "cannot get DMA channel.\n");
-			goto probe_free_gpio_wp;
+			goto probe_free_irq;
 		}
 	}
 
@@ -1768,18 +1763,6 @@ static int s3cmci_probe(struct platform_device *pdev)
 	if (s3cmci_host_usedma(host))
 		dma_release_channel(host->dma);
 
- probe_free_gpio_wp:
-	if (!host->pdata->no_wprotect)
-		gpio_free(host->pdata->gpio_wprotect);
-
- probe_free_gpio_cd:
-	if (!host->pdata->no_detect)
-		gpio_free(host->pdata->gpio_detect);
-
- probe_free_irq_cd:
-	if (host->irq_cd >= 0)
-		free_irq(host->irq_cd, host);
-
  probe_free_irq:
 	free_irq(host->irq, host);
 
@@ -1790,8 +1773,9 @@ static int s3cmci_probe(struct platform_device *pdev)
 	release_mem_region(host->mem->start, resource_size(host->mem));
 
  probe_free_gpio:
-	for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
-		gpio_free(i);
+	if (!pdev->dev.of_node)
+		for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+			gpio_free(i);
 
  probe_free_host:
 	mmc_free_host(mmc);
@@ -1818,7 +1802,6 @@ static int s3cmci_remove(struct platform_device *pdev)
 {
 	struct mmc_host		*mmc  = platform_get_drvdata(pdev);
 	struct s3cmci_host	*host = mmc_priv(mmc);
-	struct s3c24xx_mci_pdata *pd = host->pdata;
 	int i;
 
 	s3cmci_shutdown(pdev);
@@ -1832,15 +1815,9 @@ static int s3cmci_remove(struct platform_device *pdev)
 
 	free_irq(host->irq, host);
 
-	if (!pd->no_wprotect)
-		gpio_free(pd->gpio_wprotect);
-
-	if (!pd->no_detect)
-		gpio_free(pd->gpio_detect);
-
-	for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
-		gpio_free(i);
-
+	if (!pdev->dev.of_node)
+		for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+			gpio_free(i);
 
 	iounmap(host->base);
 	release_mem_region(host->mem->start, resource_size(host->mem));
@@ -1849,6 +1826,23 @@ static int s3cmci_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id s3cmci_dt_match[] = {
+	{
+		.compatible = "samsung,s3c2410-sdi",
+		.data = (void *)0,
+	},
+	{
+		.compatible = "samsung,s3c2412-sdi",
+		.data = (void *)1,
+	},
+	{
+		.compatible = "samsung,s3c2440-sdi",
+		.data = (void *)1,
+	},
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, s3cmci_dt_match);
+
 static const struct platform_device_id s3cmci_driver_ids[] = {
 	{
 		.name	= "s3c2410-sdi",
@@ -1868,6 +1862,7 @@ static int s3cmci_remove(struct platform_device *pdev)
 static struct platform_driver s3cmci_driver = {
 	.driver	= {
 		.name	= "s3c-sdi",
+		.of_match_table = s3cmci_dt_match,
 	},
 	.id_table	= s3cmci_driver_ids,
 	.probe		= s3cmci_probe,
-- 
1.9.1

^ permalink raw reply related

* [PATCH v6 1/2] dt-bindings: mmc: add DT binding for S3C24XX MMC/SD/SDIO controller
From: Sergio Prado @ 2017-03-31 23:50 UTC (permalink / raw)
  To: ulf.hansson, robh+dt, mark.rutland, linux-mmc, devicetree,
	linux-kernel, ben-linux, linux-arm-kernel
  Cc: Sergio Prado
In-Reply-To: <1491004256-13969-1-git-send-email-sergio.prado@e-labworks.com>

Adds the device tree bindings description for Samsung S3C24XX
MMC/SD/SDIO controller, used as a connectivity interface with external
MMC, SD and SDIO storage mediums.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
 .../devicetree/bindings/mmc/samsung,s3cmci.txt     | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt

diff --git a/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
new file mode 100644
index 000000000000..5f68feb9f9d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
@@ -0,0 +1,42 @@
+* Samsung's S3C24XX MMC/SD/SDIO controller device tree bindings
+
+Samsung's S3C24XX MMC/SD/SDIO controller is used as a connectivity interface
+with external MMC, SD and SDIO storage mediums.
+
+This file documents differences between the core mmc properties described by
+mmc.txt and the properties used by the Samsung S3C24XX MMC/SD/SDIO controller
+implementation.
+
+Required SoC Specific Properties:
+- compatible: should be one of the following
+  - "samsung,s3c2410-sdi": for controllers compatible with s3c2410
+  - "samsung,s3c2412-sdi": for controllers compatible with s3c2412
+  - "samsung,s3c2440-sdi": for controllers compatible with s3c2440
+- reg: register location and length
+- interrupts: mmc controller interrupt
+- clocks: Should reference the controller clock
+- clock-names: Should contain "sdi"
+
+Required Board Specific Properties:
+- pinctrl-0: Should specify pin control groups used for this controller.
+- pinctrl-names: Should contain only one value - "default".
+
+Optional Properties:
+- bus-width: number of data lines (see mmc.txt)
+- cd-gpios: gpio for card detection (see mmc.txt)
+- wp-gpios: gpio for write protection (see mmc.txt)
+
+Example:
+
+	mmc0: mmc@5a000000 {
+		compatible = "samsung,s3c2440-sdi";
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdi_pins>;
+		reg = <0x5a000000 0x100000>;
+		interrupts = <0 0 21 3>;
+		clocks = <&clocks PCLK_SDI>;
+		clock-names = "sdi";
+		bus-width = <4>;
+		cd-gpios = <&gpg 8 GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gph 8 GPIO_ACTIVE_LOW>;
+	};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v6 0/2] mmc: host: s3cmci: add device tree support
From: Sergio Prado @ 2017-03-31 23:50 UTC (permalink / raw)
  To: ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Sergio Prado

This series adds support for configuring Samsung's S3C24XX MMC/SD/SDIO
controller via device tree.

Tested on FriendlyARM mini2440, based on s3c2440 SoC.

Changes since v5 (as reported by Arnd Bergmann)
- fix module device table name that was causing an error when building
  the driver as a module

Changes since v4 (as suggested by Jaehoon Chung):
- using just a flag as a data structure for the driver to check for
  s3c2400 compatibility

Changes since v3 (as suggested by Rob Herring):
- describing properties that wasn't documented and removing unnecessary
  comment in the device tree binding

Changes since v2:
- struct "s3cmci_drv_data" and flag "is2440" renamed
- copying the whole driver data struct instead of only its member so
  it will be easier to extend the information in the future
- using mmc_of_parse() to read "cd-gpios" and "wp-gpios" properties
  from device tree

Changes since v1:
- pinctrl description removed from DT binding
- unit and label on DT binding renamed to mmc

Sergio Prado (2):
  dt-bindings: mmc: add DT binding for S3C24XX MMC/SD/SDIO controller
  mmc: host: s3cmci: allow probing from device tree

 .../devicetree/bindings/mmc/samsung,s3cmci.txt     |  42 ++++
 drivers/mmc/host/s3cmci.c                          | 257 ++++++++++-----------
 2 files changed, 168 insertions(+), 131 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH V8 5/6] ACPI: Support the probing on the devices which apply indirect-IO
From: Rafael J. Wysocki @ 2017-03-31 23:02 UTC (permalink / raw)
  To: zhichang.yuan
  Cc: Rafael J. Wysocki, Catalin Marinas, Will Deacon, Rob Herring,
	Frank Rowand, Bjorn Helgaas, Rafael J. Wysocki, Arnd Bergmann,
	linux-arm-kernel@lists.infradead.org, Mark Rutland, Brian Starkey,
	Olof Johansson, Lorenzo Pieralisi, Benjamin Herrenschmidt,
	Linux Kernel Mailing List, ACPI Devel Maling List, linuxarm
In-Reply-To: <58DDFCBE.1030705@hisilicon.com>

On Fri, Mar 31, 2017 at 8:52 AM, zhichang.yuan
<yuanzhichang@hisilicon.com> wrote:
> Hi, Rafael,
>
> Thanks for reviewing this!
>
> On 2017/3/31 4:31, Rafael J. Wysocki wrote:
>> On Thursday, March 30, 2017 11:26:58 PM zhichang.yuan wrote:
>>> On some platforms(such as Hip06/Hip07), the legacy ISA/LPC devices access I/O
>>> with some special host-local I/O ports known on x86. To access the I/O
>>> peripherals, an indirect-IO mechanism is introduced to mapped the host-local
>>> I/O to system logical/fake PIO similar the PCI MMIO on architectures where no
>>> separate I/O space exists. Just as PCI MMIO, the host I/O range should be
>>> registered before probing the downstream devices and set up the I/O mapping.
>>> But current ACPI bus probing doesn't support these indirect-IO hosts/devices.
>>>
>>> This patch introdueces a new ACPI handler for this device category. Through the
>>> handler attach callback, the indirect-IO hosts I/O registration is done and
>>> all peripherals' I/O resources are translated into logic/fake PIO before
>>> starting the enumeration.
>>
>> Can you explain to me briefly what exactly this code is expected to be doing?
>
> As you know currently for ARM architecture IO space is memory mapped and
> is only used by pci devices. The port number is dynamically allocated
> converting the device IO address into a PIO token: i.e.
> http://lxr.free-electrons.com/source/drivers/acpi/pci_root.c#L745
> This patch is meant to support a new class of IO host controller
> that are not PCI based and that still require to have the IO addresses
> be translated in the same PIO token space as the PCI controller

IOW, this is ARM-specific, right?

Thanks,
Rafael

^ permalink raw reply

* Re: Device Tree Binding for Intel FPGA Video and Image Processing Suite
From: Rob Herring @ 2017-03-31 22:48 UTC (permalink / raw)
  To: Ong, Hean Loong; +Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1490949905.21575.8.camel-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

On Fri, Mar 31, 2017 at 3:50 AM, Ong, Hean Loong
<hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> wrote:
> Hi Rob,
>
> I would like to upstream the attached device tree binding patch to the
> community. This is required for the support of framebuffer drivers of
> the Intel FPGA Video and Image Processing Suite intended for the
> Arria10 devkit.
>
> The device tree information includes the maximum width and height
> supported by the framebuffer display. These are fixed parameters
> determined by the use who the Quartus design system to program the
> FPGA in the Arria10 devkit and its variants.

Please read Documentation/devicetree/bindings/submitting-patches.txt.

The first problem is sending the patch as an attachment.

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v5 2/2] mmc: host: s3cmci: allow probing from device tree
From: Sergio Prado @ 2017-03-31 22:46 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Arnd Bergmann, Rob Herring, Mark Rutland,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Linux Kernel Mailing List,
	ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, Linux ARM
In-Reply-To: <CAPDyKFquGSgK7tkYDpkJM7C7JChZMqvmHoJyiLE9_ZG4CGBOSw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Fri, Mar 31, 2017 at 01:11:59PM +0200, Ulf Hansson wrote:
> On 31 March 2017 at 09:25, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> > On Sat, Mar 18, 2017 at 2:13 AM, Sergio Prado
> > <sergio.prado-1e4yhPs3/ABSwrhanM7KvQ@public.gmane.org> wrote:
> >
> >>
> >> +static const struct of_device_id s3cmci_dt_match[] = {
> >> +       {
> >> +               .compatible = "samsung,s3c2410-sdi",
> >> +               .data = (void *)0,
> >> +       },
> >> +       {
> >> +               .compatible = "samsung,s3c2412-sdi",
> >> +               .data = (void *)1,
> >> +       },
> >> +       {
> >> +               .compatible = "samsung,s3c2440-sdi",
> >> +               .data = (void *)1,
> >> +       },
> >> +       { /* sentinel */ },
> >> +};
> >> +MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
> >> +
> >
> > The names don't match:
> >
> > In file included from /git/arm-soc/drivers/mmc/host/s3cmci.c:14:0:
> > /git/arm-soc/drivers/mmc/host/s3cmci.c:1844:25: error:
> > 'sdhci_s3c_dt_match' undeclared here (not in a function); did you mean
> > 's3cmci_dt_match'?
> >  MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
> >                          ^
> > /git/arm-soc/include/linux/module.h:212:21: note: in definition of
> > macro 'MODULE_DEVICE_TABLE'
> >  extern const typeof(name) __mod_##type##__##name##_device_table  \
> >                      ^~~~
> > /git/arm-soc/include/linux/module.h:212:27: error:
> > '__mod_of__sdhci_s3c_dt_match_device_table' aliased to undefined
> > symbol 'sdhci_s3c_dt_match'
> >  extern const typeof(name) __mod_##type##__##name##_device_table  \
> >                            ^
> > /git/arm-soc/drivers/mmc/host/s3cmci.c:1844:1: note: in expansion of
> > macro 'MODULE_DEVICE_TABLE'
> >  MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
> >  ^~~~~~~~~~~~~~~~~~~
> > /git/arm-soc/scripts/Makefile.build:314: recipe for target
> > 'drivers/mmc/host/s3cmci.o' failed
> >
> > Can you send a fix?
> 
> Never mind, I am dropping the patches from my next branch as those
> clearly haven't been built/tested by Sergio properly. It's better that
> he re-spins them.
> 
> Arnd, thanks for reporting and even fixing some of the problems!
> 
> Kind regards
> Uffe

Arnd, thanks for reporting the error.

I have built/tested the patches, but only as a built-in feature, and
this error occurs when enabled as a module.

I will re-spins them and send v6.

Best regards,

Sergio Prado
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 2/2] drivers/serial: Add driver for Aspeed virtual UART
From: Benjamin Herrenschmidt @ 2017-03-31 21:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joel Stanley
  Cc: Jiri Slaby, Mark Rutland, Rob Herring, Jeremy Kerr, linux-serial,
	linux-kernel, openbmc, devicetree
In-Reply-To: <20170331133120.GA26078@kroah.com>

On Fri, 2017-03-31 at 15:31 +0200, Greg Kroah-Hartman wrote:
> DEVICE_ATTR_RW()?
> 
> And why random sysfs files for a uart?  Where have you documented
> these?

We should stick a file somewhere in Documentation I suppose or
at least put that in a comment blob at the head of the file.

FYI:

The VUART is basically two UART 'front ends' connected by their FIFO
(no actual serial line in between). One is on the BMC side (management
controller) and one is on the host CPU side.

It allows the BMC to provide to the host a "UART" that pipes into
the BMC itself and can then be turned by the BMC into a network console
of some sort for example.

This driver is for the BMC side. The sysfs files allow the BMC
userspace which owns the system configuration policy, to specify
at what IO port and interrupt number the host side will appear
to the host on the Host <-> BMC LPC bus. It could be different on a
different system (though most of them use 3f8/4).

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH V12 4/4] thermal: bcm2835: add thermal driver for bcm2835 SoC
From: Rafał Miłecki @ 2017-03-31 21:22 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Eduardo Valentin, Zhang Rui, kernel, Eric Anholt, Rob Herring,
	Frank Rowand, Florian Fainelli, linux-rpi-kernel, devicetree,
	linux-pm
In-Reply-To: <1490990586-30898-5-git-send-email-stefan.wahren@i2se.com>

On 2017-03-31 22:03, Stefan Wahren wrote:
> Add basic thermal driver for bcm2835 SoC.
> 
> This driver currently make sure that tsense HW block is set up
> correctly.
> 
> Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> Acked-by: Eric Anholt <eric@anholt.net>
> Acked-by: Eduardo Valentin <edubezval@gmail.com>

It works great on Raspberry Pi Zero W!

Tested-by: Rafał Miłecki <rafal@milecki.pl>

Sorry for the earlier false failure report. I guess I was missing 
something,
maybe some DT change? Anyway, it works now! :)

^ permalink raw reply

* [PATCH v3] regulator: Add driver for voltage controlled regulators
From: Matthias Kaehlcke @ 2017-03-31 20:50 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Douglas Anderson, Brian Norris,
	Matthias Kaehlcke

The output voltage of a voltage controlled regulator can be controlled
through the voltage of another regulator. The current version of this
driver assumes that the output voltage is a linear function of the control
voltage.

Signed-off-by: Matthias Kaehlcke <mka-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---
Changes in v3:
- Pre-calculate limits for OVP-safe downward transitions with a discrete
  control regulator
- Use regulator_get_linear_step() and regulator_count_voltages() to
  determine if the control regulator is continuous or discrete
- Changed some log messages to start with lowercase character for
  consistency
- Misc formatting fixes

Changes in v2:
- Don't configure control regulator as supply
- Added enable/disable ops to turn control regulator on/off
- Use regulator_has_continuous_voltage_range() to determine if control
  regulator is continuous or discrete
- Use regulator-min/max-microvolt as output voltage range
- Updated and fixed example in DT bindings
- Updated commit message

 .../devicetree/bindings/regulator/vctrl.txt        |  50 ++
 drivers/regulator/Kconfig                          |   7 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/vctrl-regulator.c                | 553 +++++++++++++++++++++
 4 files changed, 611 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/vctrl.txt
 create mode 100644 drivers/regulator/vctrl-regulator.c

diff --git a/Documentation/devicetree/bindings/regulator/vctrl.txt b/Documentation/devicetree/bindings/regulator/vctrl.txt
new file mode 100644
index 000000000000..c7ee9956d62d
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/vctrl.txt
@@ -0,0 +1,50 @@
+Bindings for Voltage controlled regulators
+==========================================
+
+Required properties:
+--------------------
+- compatible		  : must be "vctrl-regulator".
+- regulator-min-microvolt : smallest voltage consumers may set
+- regulator-max-microvolt : largest voltage consumers may set
+- ctrl-regulator:	  : the name of the regulator supplying the control
+			    voltage.
+- ctrl-voltage-range	  : an array of two integer values describing the range
+			    (min/max) of the control voltage. The values specify
+			    the control voltage needed to generate the corresponding
+			    regulator-min/max-microvolt output voltage.
+
+Optional properties:
+--------------------
+- ovp-threshold-percent	: overvoltage protection (OVP) threshold of the
+			  regulator in percent. Some regulators have an OVP
+			  circuitry which shuts down the regulator when the
+			  actual output voltage deviates beyond a certain
+			  margin from the expected value for a given control
+			  voltage. On larger voltage decreases this can occur
+			  undesiredly since the output voltage does not adjust
+			  inmediately to changes in the control voltage. To
+			  avoid this situation the vctrl driver breaks down
+			  larger voltage decreases into multiple steps, where
+			  each step is within the OVP threshold.
+- min-slew-down-rate	: Describes how slowly the regulator voltage will decay
+			  down in the worst case (lightest expected load).
+			  Specified in uV / us (like main regulator ramp rate).
+			  This value is required when ovp-threshold-percent is
+			  specified.
+
+Example:
+
+	vctrl-reg {
+		compatible = "vctrl-regulator";
+		regulator-name = "vctrl_reg";
+
+		ctrl-regulator = "ctrl_reg";
+
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1500000>;
+
+		ctrl-voltage-range = <200000 500000>;
+
+		min-slew-down-rate = <225>;
+		ovp-threshold-percent = <16>;
+	};
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index be06eb29c681..9a090e338a19 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -850,6 +850,13 @@ config REGULATOR_TWL4030
 	  This driver supports the voltage regulators provided by
 	  this family of companion chips.
 
+config REGULATOR_VCTRL
+	tristate "Voltage controlled regulators"
+	depends on OF
+	help
+	  This driver provides support for voltage regulators whose output
+	  voltage is controlled by the voltage of another regulator.
+
 config REGULATOR_VEXPRESS
 	tristate "Versatile Express regulators"
 	depends on VEXPRESS_CONFIG
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index ef7725e2592a..891dd287f26b 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
 obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
+obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o
 obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
diff --git a/drivers/regulator/vctrl-regulator.c b/drivers/regulator/vctrl-regulator.c
new file mode 100644
index 000000000000..d327ed65bb65
--- /dev/null
+++ b/drivers/regulator/vctrl-regulator.c
@@ -0,0 +1,553 @@
+/*
+ * Driver for voltage controller regulators
+ *
+ * Copyright (C) 2017 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/sort.h>
+
+struct vctrl_voltage_range {
+	int min_uV;
+	int max_uV;
+};
+
+struct vctrl_voltage_ranges {
+	struct vctrl_voltage_range ctrl;
+	struct vctrl_voltage_range out;
+};
+
+struct vctrl_voltage_table {
+	int ctrl;
+	int out;
+	int ovp_min_sel;
+};
+
+struct vctrl_data {
+	struct regulator_dev *rdev;
+	struct regulator_desc desc;
+	struct regulator *ctrl_reg;
+	bool enabled;
+	unsigned int min_slew_down_rate;
+	unsigned int ovp_threshold;
+	struct vctrl_voltage_ranges vrange;
+	struct vctrl_voltage_table *vtable;
+	unsigned int sel;
+};
+
+static int vctrl_calc_ctrl_voltage(struct vctrl_data *vctrl, int out_uV)
+{
+	struct vctrl_voltage_range *ctrl = &vctrl->vrange.ctrl;
+	struct vctrl_voltage_range *out = &vctrl->vrange.out;
+
+	return ctrl->min_uV +
+		DIV_ROUND_CLOSEST_ULL((s64)(out_uV - out->min_uV) *
+				      (ctrl->max_uV - ctrl->min_uV),
+				      out->max_uV - out->min_uV);
+}
+
+static int vctrl_calc_output_voltage(struct vctrl_data *vctrl, int ctrl_uV)
+{
+	struct vctrl_voltage_range *ctrl = &vctrl->vrange.ctrl;
+	struct vctrl_voltage_range *out = &vctrl->vrange.out;
+
+	if (ctrl_uV < 0) {
+		pr_err("vctrl: failed to get control voltage\n");
+		return ctrl_uV;
+	}
+
+	if (ctrl_uV < ctrl->min_uV)
+		return out->min_uV;
+
+	if (ctrl_uV > ctrl->max_uV)
+		return out->max_uV;
+
+	return out->min_uV +
+		DIV_ROUND_CLOSEST_ULL((s64)(ctrl_uV - ctrl->min_uV) *
+				      (out->max_uV - out->min_uV),
+				      ctrl->max_uV - ctrl->min_uV);
+}
+
+static int vctrl_get_voltage(struct regulator_dev *rdev)
+{
+	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
+	int ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
+
+	return vctrl_calc_output_voltage(vctrl, ctrl_uV);
+}
+
+static int vctrl_set_voltage(struct regulator_dev *rdev,
+			     int req_min_uV, int req_max_uV,
+			     unsigned int *selector)
+{
+	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
+	struct regulator *ctrl_reg = vctrl->ctrl_reg;
+	int orig_ctrl_uV = regulator_get_voltage(ctrl_reg);
+	int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV);
+	int ret;
+
+	if (req_min_uV >= uV || !vctrl->ovp_threshold)
+		/* voltage rising or no OVP */
+		return regulator_set_voltage(
+			ctrl_reg,
+			vctrl_calc_ctrl_voltage(vctrl, req_min_uV),
+			vctrl_calc_ctrl_voltage(vctrl, req_max_uV));
+
+	while (uV > req_min_uV) {
+		int max_drop_uV = (uV * vctrl->ovp_threshold) / 100;
+		int next_uV;
+		int next_ctrl_uV;
+		int delay;
+
+		/* Make sure no infinite loop even in crazy cases */
+		if (max_drop_uV == 0)
+			max_drop_uV = 1;
+
+		next_uV = max_t(int, req_min_uV, uV - max_drop_uV);
+		next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV);
+
+		ret = regulator_set_voltage(ctrl_reg,
+					    next_ctrl_uV,
+					    next_ctrl_uV);
+		if (ret)
+			goto err;
+
+		delay = DIV_ROUND_UP(uV - next_uV, vctrl->min_slew_down_rate);
+		usleep_range(delay, delay + DIV_ROUND_UP(delay, 10));
+
+		uV = next_uV;
+	}
+
+	return 0;
+
+err:
+	/* Try to go back to original voltage */
+	regulator_set_voltage(ctrl_reg, orig_ctrl_uV, orig_ctrl_uV);
+
+	return ret;
+}
+
+static int vctrl_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
+
+	return vctrl->sel;
+}
+
+static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
+				 unsigned int selector)
+{
+	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
+	struct regulator *ctrl_reg = vctrl->ctrl_reg;
+	unsigned int orig_sel = vctrl->sel;
+	int ret;
+
+	if (selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+
+	if (selector >= vctrl->sel || !vctrl->ovp_threshold) {
+		/* voltage rising or no OVP */
+		ret = regulator_set_voltage(ctrl_reg,
+					    vctrl->vtable[selector].ctrl,
+					    vctrl->vtable[selector].ctrl);
+		if (!ret)
+			vctrl->sel = selector;
+
+		return ret;
+	}
+
+	while (vctrl->sel != selector) {
+		unsigned int next_sel;
+		int delay;
+
+		if (selector >= vctrl->vtable[vctrl->sel].ovp_min_sel)
+			next_sel = selector;
+		else
+			next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel;
+
+		ret = regulator_set_voltage(ctrl_reg,
+					    vctrl->vtable[next_sel].ctrl,
+					    vctrl->vtable[next_sel].ctrl);
+		if (ret) {
+			dev_err(&rdev->dev,
+				"failed to set control voltage to %duV\n",
+				vctrl->vtable[next_sel].ctrl);
+			goto err;
+		}
+		vctrl->sel = next_sel;
+
+		delay = DIV_ROUND_UP(vctrl->vtable[vctrl->sel].out -
+				     vctrl->vtable[next_sel].out,
+				     vctrl->min_slew_down_rate);
+		usleep_range(delay, delay + DIV_ROUND_UP(delay, 10));
+	}
+
+	return 0;
+
+err:
+	if (vctrl->sel != orig_sel) {
+		/* Try to go back to original voltage */
+		if (!regulator_set_voltage(ctrl_reg,
+					   vctrl->vtable[orig_sel].ctrl,
+					   vctrl->vtable[orig_sel].ctrl))
+			vctrl->sel = orig_sel;
+		else
+			dev_warn(&rdev->dev,
+				 "failed to restore original voltage\n");
+	}
+
+	return ret;
+}
+
+static int vctrl_list_voltage(struct regulator_dev *rdev,
+			      unsigned int selector)
+{
+	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
+
+	if (selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+
+	return vctrl->vtable[selector].out;
+}
+
+static int vctrl_parse_dt(struct platform_device *pdev,
+			  struct vctrl_data *vctrl)
+{
+	int ret;
+	struct device_node *np = pdev->dev.of_node;
+	const char *ctrl_reg;
+	u32 pval;
+	u32 vrange_ctrl[2];
+
+	ret = of_property_read_string(np, "ctrl-regulator", &ctrl_reg);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to read ctrl-regulator: %d\n", ret);
+		return ret;
+	}
+
+	vctrl->ctrl_reg = devm_regulator_get(&pdev->dev, ctrl_reg);
+	if (IS_ERR(vctrl->ctrl_reg))
+		return PTR_ERR(vctrl->ctrl_reg);
+
+	ret = of_property_read_u32(np, "ovp-threshold-percent", &pval);
+	if (!ret) {
+		vctrl->ovp_threshold = pval;
+		if (vctrl->ovp_threshold > 100) {
+			dev_err(&pdev->dev,
+				"ovp-threshold-percent (%u) > 100\n",
+				vctrl->ovp_threshold);
+			return -EINVAL;
+		}
+	}
+
+	ret = of_property_read_u32(np, "min-slew-down-rate", &pval);
+	if (!ret) {
+		vctrl->min_slew_down_rate = pval;
+
+		/* We use the value as int and as divider; sanity check */
+		if (vctrl->min_slew_down_rate == 0) {
+			dev_err(&pdev->dev,
+				"min-slew-down-rate must not be 0\n");
+			return -EINVAL;
+		} else if (vctrl->min_slew_down_rate > INT_MAX) {
+			dev_err(&pdev->dev, "min-slew-down-rate (%u) too big\n",
+				vctrl->min_slew_down_rate);
+			return -EINVAL;
+		}
+	}
+
+	if (vctrl->ovp_threshold && !vctrl->min_slew_down_rate) {
+		dev_err(&pdev->dev,
+			"ovp-threshold-percent requires min-slew-down-rate\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(np, "regulator-min-microvolt", &pval);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"failed to read regulator-min-microvolt: %d\n", ret);
+		return ret;
+	}
+	vctrl->vrange.out.min_uV = pval;
+
+	ret = of_property_read_u32(np, "regulator-max-microvolt", &pval);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"failed to read regulator-max-microvolt: %d\n", ret);
+		return ret;
+	}
+	vctrl->vrange.out.max_uV = pval;
+
+	ret = of_property_read_u32_array(np, "ctrl-voltage-range", vrange_ctrl,
+					 2);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to read ctrl-voltage-range: %d\n",
+			ret);
+		return ret;
+	}
+
+	if (vrange_ctrl[0] >= vrange_ctrl[1]) {
+		dev_err(&pdev->dev, "ctrl-voltage-range is invalid: %d-%d\n",
+			vrange_ctrl[0], vrange_ctrl[1]);
+		return -EINVAL;
+	}
+
+	vctrl->vrange.ctrl.min_uV = vrange_ctrl[0];
+	vctrl->vrange.ctrl.max_uV = vrange_ctrl[1];
+
+	return 0;
+}
+
+static int vctrl_cmp_ctrl_uV(const void *a, const void *b)
+{
+	const struct vctrl_voltage_table *at = a;
+	const struct vctrl_voltage_table *bt = b;
+
+	return at->ctrl - bt->ctrl;
+}
+
+static int vctrl_init_vtable(struct platform_device *pdev)
+{
+	struct vctrl_data *vctrl = platform_get_drvdata(pdev);
+	struct regulator_desc *rdesc = &vctrl->desc;
+	struct regulator *ctrl_reg = vctrl->ctrl_reg;
+	struct vctrl_voltage_range *vrange_ctrl = &vctrl->vrange.ctrl;
+	int n_voltages;
+	int ctrl_uV;
+	int i, idx_vt;
+
+	n_voltages = regulator_count_voltages(ctrl_reg);
+
+	rdesc->n_voltages = n_voltages;
+
+	/* determine number of steps within the range of the vctrl regulator */
+	for (i = 0; i < n_voltages; i++) {
+		ctrl_uV = regulator_list_voltage(ctrl_reg, i);
+
+		if (ctrl_uV < vrange_ctrl->min_uV ||
+		    ctrl_uV > vrange_ctrl->max_uV) {
+			rdesc->n_voltages--;
+			continue;
+		}
+	}
+
+	if (rdesc->n_voltages == 0) {
+		dev_err(&pdev->dev, "invalid configuration\n");
+		return -EINVAL;
+	}
+
+	vctrl->vtable = devm_kmalloc_array(
+		&pdev->dev, sizeof(struct vctrl_voltage_table),
+		rdesc->n_voltages, GFP_KERNEL | __GFP_ZERO);
+	if (!vctrl->vtable)
+		return -ENOMEM;
+
+	/* create mapping control <=> output voltage */
+	for (i = 0, idx_vt = 0; i < n_voltages; i++) {
+		ctrl_uV = regulator_list_voltage(ctrl_reg, i);
+
+		if (ctrl_uV < vrange_ctrl->min_uV ||
+		    ctrl_uV > vrange_ctrl->max_uV)
+			continue;
+
+		vctrl->vtable[idx_vt].ctrl = ctrl_uV;
+		vctrl->vtable[idx_vt].out =
+			vctrl_calc_output_voltage(vctrl, ctrl_uV);
+		idx_vt++;
+	}
+
+	/* we rely on the table to be ordered by ascending voltage */
+	sort(vctrl->vtable, rdesc->n_voltages,
+	     sizeof(struct vctrl_voltage_table), vctrl_cmp_ctrl_uV,
+	     NULL);
+
+	/* pre-calculate OVP-safe downward transitions */
+	for (i = n_voltages - 1; i > 0; i--) {
+		int j;
+		int ovp_min_uV = (vctrl->vtable[i].out *
+				  (100 - vctrl->ovp_threshold)) / 100;
+
+		for (j = 0; j < i; j++) {
+			if (vctrl->vtable[j].out >= ovp_min_uV) {
+				vctrl->vtable[i].ovp_min_sel = j;
+				break;
+			}
+		}
+
+		if (j == i) {
+			dev_warn(&pdev->dev, "switching down from %duV may cause OVP shutdown\n",
+				vctrl->vtable[i].out);
+			/* use next lowest voltage */
+			vctrl->vtable[i].ovp_min_sel = i - 1;
+		}
+	}
+
+	return 0;
+}
+
+static int vctrl_enable(struct regulator_dev *rdev)
+{
+	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
+	int ret = regulator_enable(vctrl->ctrl_reg);
+
+	if (!ret)
+		vctrl->enabled = true;
+
+	return ret;
+}
+
+static int vctrl_disable(struct regulator_dev *rdev)
+{
+	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
+	int ret = regulator_disable(vctrl->ctrl_reg);
+
+	if (!ret)
+		vctrl->enabled = false;
+
+	return ret;
+}
+
+static int vctrl_is_enabled(struct regulator_dev *rdev)
+{
+	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
+
+	return vctrl->enabled;
+}
+
+static const struct regulator_ops vctrl_ops_cont = {
+	.enable		  = vctrl_enable,
+	.disable	  = vctrl_disable,
+	.is_enabled	  = vctrl_is_enabled,
+	.get_voltage	  = vctrl_get_voltage,
+	.set_voltage	  = vctrl_set_voltage,
+};
+
+static const struct regulator_ops vctrl_ops_non_cont = {
+	.enable		  = vctrl_enable,
+	.disable	  = vctrl_disable,
+	.is_enabled	  = vctrl_is_enabled,
+	.set_voltage_sel = vctrl_set_voltage_sel,
+	.get_voltage_sel = vctrl_get_voltage_sel,
+	.list_voltage    = vctrl_list_voltage,
+	.map_voltage     = regulator_map_voltage_iterate,
+};
+
+static int vctrl_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct vctrl_data *vctrl;
+	const struct regulator_init_data *init_data;
+	struct regulator_desc *rdesc;
+	struct regulator_config cfg = { };
+	struct vctrl_voltage_range *vrange_ctrl;
+	int ctrl_uV;
+	int ret;
+
+	vctrl = devm_kzalloc(&pdev->dev, sizeof(struct vctrl_data),
+			     GFP_KERNEL);
+	if (!vctrl)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, vctrl);
+
+	ret = vctrl_parse_dt(pdev, vctrl);
+	if (ret)
+		return ret;
+
+	vrange_ctrl = &vctrl->vrange.ctrl;
+
+	rdesc = &vctrl->desc;
+	rdesc->name = "vctrl";
+	rdesc->type = REGULATOR_VOLTAGE;
+	rdesc->owner = THIS_MODULE;
+
+	if ((regulator_get_linear_step(vctrl->ctrl_reg) == 1) ||
+	    (regulator_count_voltages(vctrl->ctrl_reg) == -EINVAL)) {
+		rdesc->continuous_voltage_range = true;
+		rdesc->ops = &vctrl_ops_cont;
+	} else {
+		rdesc->ops = &vctrl_ops_non_cont;
+	}
+
+	init_data = of_get_regulator_init_data(&pdev->dev, np, rdesc);
+	if (!init_data)
+		return -ENOMEM;
+
+	cfg.of_node = np;
+	cfg.dev = &pdev->dev;
+	cfg.driver_data = vctrl;
+	cfg.init_data = init_data;
+
+	if (!rdesc->continuous_voltage_range) {
+		ret = vctrl_init_vtable(pdev);
+		if (ret)
+			return ret;
+
+		ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
+		if (ctrl_uV < 0) {
+			dev_err(&pdev->dev, "failed to get control voltage\n");
+			return ctrl_uV;
+		}
+
+		/* determine current voltage selector from control voltage */
+		if (ctrl_uV < vrange_ctrl->min_uV) {
+			vctrl->sel = 0;
+		} else if (ctrl_uV > vrange_ctrl->max_uV) {
+			vctrl->sel = rdesc->n_voltages - 1;
+		} else {
+			int i;
+
+			for (i = 0; i < rdesc->n_voltages; i++) {
+				if (ctrl_uV == vctrl->vtable[i].ctrl) {
+					vctrl->sel = i;
+					break;
+				}
+			}
+		}
+	}
+
+	vctrl->rdev = devm_regulator_register(&pdev->dev, rdesc, &cfg);
+	if (IS_ERR(vctrl->rdev)) {
+		ret = PTR_ERR(vctrl->rdev);
+		dev_err(&pdev->dev, "failed to register regulator: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id vctrl_of_match[] = {
+	{ .compatible = "vctrl-regulator", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, vctrl_of_match);
+
+static struct platform_driver vctrl_driver = {
+	.probe		= vctrl_probe,
+	.driver		= {
+		.name		= "vctrl-regulator",
+		.of_match_table = of_match_ptr(vctrl_of_match),
+	},
+};
+
+module_platform_driver(vctrl_driver);
+
+MODULE_DESCRIPTION("Voltage Controlled Regulator Driver");
+MODULE_AUTHOR("Matthias Kaehlcke <mka-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.12.2.564.g063fe858b8-goog

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH V4 2/2] thermal: broadcom: add Northstar thermal driver
From: Rafał Miłecki @ 2017-03-31 20:11 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin
  Cc: Rob Herring, Mark Rutland, Stephen Warren, Lee Jones, Eric Anholt,
	Florian Fainelli, Ray Jui, Scott Branden,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Rafał Miłecki, Jon Mason
In-Reply-To: <20170331201124.656-1-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>

Northstar is a SoC family commonly used in home routers. This commit
adds a driver for checking CPU temperature. As Northstar Plus seems to
also have this IP block this new symbol gets ARCH_BCM_IPROC dependency.

Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Signed-off-by: Jon Mason <jon.mason-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
---
V2: Make it iProc specific as NSP can also use this driver
    Select proper symbols in config ARCH_BCM_IPROC
    Define PVTMON register bits
    Update code selecting temperature monitor mode
    Thank you Jon!
V3: More details in help message for BCM_NS_THERMAL
    Use slope & offset
    Drop arch code change (I'll be submitted using a proper tree)
    Thank you Eduardo!
V4: Comment operations on PVTMON_CONTROL0 register
---
 drivers/thermal/Kconfig               |   5 ++
 drivers/thermal/Makefile              |   1 +
 drivers/thermal/broadcom/Kconfig      |   8 +++
 drivers/thermal/broadcom/Makefile     |   1 +
 drivers/thermal/broadcom/ns-thermal.c | 105 ++++++++++++++++++++++++++++++++++
 5 files changed, 120 insertions(+)
 create mode 100644 drivers/thermal/broadcom/Kconfig
 create mode 100644 drivers/thermal/broadcom/Makefile
 create mode 100644 drivers/thermal/broadcom/ns-thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 776b34396144..008e173ec825 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -392,6 +392,11 @@ config MTK_THERMAL
 	  Enable this option if you want to have support for thermal management
 	  controller present in Mediatek SoCs
 
+menu "Broadcom thermal drivers"
+depends on ARCH_BCM || COMPILE_TEST
+source "drivers/thermal/broadcom/Kconfig"
+endmenu
+
 menu "Texas Instruments thermal drivers"
 depends on ARCH_HAS_BANDGAP || COMPILE_TEST
 depends on HAS_IOMEM
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 7adae2029355..549d81b6363c 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -27,6 +27,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL)	+= clock_cooling.o
 thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
 
 # platform thermal drivers
+obj-y				+= broadcom/
 obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM)	+= qcom-spmi-temp-alarm.o
 obj-$(CONFIG_SPEAR_THERMAL)	+= spear_thermal.o
 obj-$(CONFIG_ROCKCHIP_THERMAL)	+= rockchip_thermal.o
diff --git a/drivers/thermal/broadcom/Kconfig b/drivers/thermal/broadcom/Kconfig
new file mode 100644
index 000000000000..f0dea8a8e002
--- /dev/null
+++ b/drivers/thermal/broadcom/Kconfig
@@ -0,0 +1,8 @@
+config BCM_NS_THERMAL
+	tristate "Northstar thermal driver"
+	depends on ARCH_BCM_IPROC || COMPILE_TEST
+	help
+	  Northstar is a family of SoCs that includes e.g. BCM4708, BCM47081,
+	  BCM4709 and BCM47094. It contains DMU (Device Management Unit) block
+	  with a thermal sensor that allows checking CPU temperature. This
+	  driver provides support for it.
diff --git a/drivers/thermal/broadcom/Makefile b/drivers/thermal/broadcom/Makefile
new file mode 100644
index 000000000000..059df9a0ed69
--- /dev/null
+++ b/drivers/thermal/broadcom/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_BCM_NS_THERMAL)		+= ns-thermal.o
diff --git a/drivers/thermal/broadcom/ns-thermal.c b/drivers/thermal/broadcom/ns-thermal.c
new file mode 100644
index 000000000000..eab96b3572b9
--- /dev/null
+++ b/drivers/thermal/broadcom/ns-thermal.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/thermal.h>
+
+#define PVTMON_CONTROL0					0x00
+#define PVTMON_CONTROL0_SEL_MASK			0x0000000e
+#define PVTMON_CONTROL0_SEL_TEMP_MONITOR		0x00000000
+#define PVTMON_CONTROL0_SEL_TEST_MODE			0x0000000e
+#define PVTMON_STATUS					0x08
+
+struct ns_thermal {
+	struct thermal_zone_device *tz;
+	void __iomem *pvtmon;
+};
+
+static int ns_thermal_get_temp(void *data, int *temp)
+{
+	struct ns_thermal *ns_thermal = data;
+	int offset = thermal_zone_get_offset(ns_thermal->tz);
+	int slope = thermal_zone_get_slope(ns_thermal->tz);
+	u32 val;
+
+	val = readl(ns_thermal->pvtmon + PVTMON_CONTROL0);
+	if ((val & PVTMON_CONTROL0_SEL_MASK) != PVTMON_CONTROL0_SEL_TEMP_MONITOR) {
+		/* Clear current mode selection */
+		val &= ~PVTMON_CONTROL0_SEL_MASK;
+
+		/* Set temp monitor mode (it's the default actually) */
+		val |= PVTMON_CONTROL0_SEL_TEMP_MONITOR;
+
+		writel(val, ns_thermal->pvtmon + PVTMON_CONTROL0);
+	}
+
+	val = readl(ns_thermal->pvtmon + PVTMON_STATUS);
+	*temp = slope * val + offset;
+
+	return 0;
+}
+
+const struct thermal_zone_of_device_ops ns_thermal_ops = {
+	.get_temp = ns_thermal_get_temp,
+};
+
+static int ns_thermal_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ns_thermal *ns_thermal;
+
+	ns_thermal = devm_kzalloc(dev, sizeof(*ns_thermal), GFP_KERNEL);
+	if (!ns_thermal)
+		return -ENOMEM;
+
+	ns_thermal->pvtmon = of_iomap(dev_of_node(dev), 0);
+	if (WARN_ON(!ns_thermal->pvtmon))
+		return -ENOENT;
+
+	ns_thermal->tz = devm_thermal_zone_of_sensor_register(dev, 0,
+							      ns_thermal,
+							      &ns_thermal_ops);
+	if (IS_ERR(ns_thermal->tz)) {
+		iounmap(ns_thermal->pvtmon);
+		return PTR_ERR(ns_thermal->tz);
+	}
+
+	platform_set_drvdata(pdev, ns_thermal);
+
+	return 0;
+}
+
+static int ns_thermal_remove(struct platform_device *pdev)
+{
+	struct ns_thermal *ns_thermal = platform_get_drvdata(pdev);
+
+	iounmap(ns_thermal->pvtmon);
+
+	return 0;
+}
+
+static const struct of_device_id ns_thermal_of_match[] = {
+	{ .compatible = "brcm,ns-thermal", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ns_thermal_of_match);
+
+static struct platform_driver ns_thermal_driver = {
+	.probe		= ns_thermal_probe,
+	.remove		= ns_thermal_remove,
+	.driver = {
+		.name = "ns-thermal",
+		.of_match_table = ns_thermal_of_match,
+	},
+};
+module_platform_driver(ns_thermal_driver);
+
+MODULE_DESCRIPTION("Northstar thermal driver");
+MODULE_LICENSE("GPL v2");
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH V4 1/2] dt-bindings: thermal: add support for Broadcom's Northstar thermal
From: Rafał Miłecki @ 2017-03-31 20:11 UTC (permalink / raw)
  To: Zhang Rui, Eduardo Valentin
  Cc: Rob Herring, Mark Rutland, Stephen Warren, Lee Jones, Eric Anholt,
	Florian Fainelli, Ray Jui, Scott Branden,
	bcm-kernel-feedback-list, linux-pm, devicetree, linux-rpi-kernel,
	linux-arm-kernel, Rafał Miłecki
In-Reply-To: <20170331073132.21457-2-zajec5@gmail.com>

From: Rafał Miłecki <rafal@milecki.pl>

This commit documents binding for thermal used in Northstar family SoCs.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
V3: Add thermal-zones to the example
    Rob: Because of this update, I didn't include Acked-by I got for V2
---
 .../devicetree/bindings/thermal/brcm,ns-thermal    | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/brcm,ns-thermal

diff --git a/Documentation/devicetree/bindings/thermal/brcm,ns-thermal b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
new file mode 100644
index 000000000000..c561c7349f17
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
@@ -0,0 +1,26 @@
+* Broadcom Northstar Thermal
+
+This binding describes thermal sensor that is part of Northstar's DMU (Device
+Management Unit).
+
+Required properties:
+- compatible : Must be "brcm,ns-thermal"
+- reg : iomem address range of PVTMON registers
+- #thermal-sensor-cells : Should be <0>
+
+Example:
+
+thermal: thermal@1800c2c0 {
+	compatible = "brcm,ns-thermal";
+	reg = <0x1800c2c0 0x10>;
+	#thermal-sensor-cells = <0>;
+};
+
+thermal-zones {
+	cpu_thermal: cpu-thermal {
+		polling-delay-passive = <0>;
+		polling-delay = <1000>;
+		coefficients = <(-556) 418000>;
+		thermal-sensors = <&thermal>;
+	};
+};
-- 
2.11.0

^ permalink raw reply related

* [PATCH V12 4/4] thermal: bcm2835: add thermal driver for bcm2835 SoC
From: Stefan Wahren @ 2017-03-31 20:03 UTC (permalink / raw)
  To: Eduardo Valentin, Zhang Rui, kernel
  Cc: Eric Anholt, Rob Herring, Frank Rowand, Florian Fainelli,
	Rafał Miłecki, linux-rpi-kernel, devicetree, linux-pm,
	Stefan Wahren
In-Reply-To: <1490990586-30898-1-git-send-email-stefan.wahren@i2se.com>

Add basic thermal driver for bcm2835 SoC.

This driver currently make sure that tsense HW block is set up
correctly.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Acked-by: Eric Anholt <eric@anholt.net>
Acked-by: Eduardo Valentin <edubezval@gmail.com>
---
 drivers/thermal/Kconfig           |    8 +
 drivers/thermal/Makefile          |    1 +
 drivers/thermal/bcm2835_thermal.c |  314 +++++++++++++++++++++++++++++++++++++
 3 files changed, 323 insertions(+)
 create mode 100644 drivers/thermal/bcm2835_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 776b343..3bd2406 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -453,4 +453,12 @@ config ZX2967_THERMAL
 	  the primitive temperature sensor embedded in zx2967 SoCs.
 	  This sensor generates the real time die temperature.
 
+config BCM2835_THERMAL
+	tristate "Thermal sensors on bcm2835 SoC"
+	depends on ARCH_BCM2835 || COMPILE_TEST
+	depends on HAS_IOMEM
+	depends on THERMAL_OF
+	help
+	  Support for thermal sensors on Broadcom bcm2835 SoCs.
+
 endif
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 7adae20..f23cde0 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -58,3 +58,4 @@ obj-$(CONFIG_HISI_THERMAL)     += hisi_thermal.o
 obj-$(CONFIG_MTK_THERMAL)	+= mtk_thermal.o
 obj-$(CONFIG_GENERIC_ADC_THERMAL)	+= thermal-generic-adc.o
 obj-$(CONFIG_ZX2967_THERMAL)	+= zx2967_thermal.o
+obj-$(CONFIG_BCM2835_THERMAL)	+= bcm2835_thermal.o
diff --git a/drivers/thermal/bcm2835_thermal.c b/drivers/thermal/bcm2835_thermal.c
new file mode 100644
index 0000000..0ecf808
--- /dev/null
+++ b/drivers/thermal/bcm2835_thermal.c
@@ -0,0 +1,314 @@
+/*
+ * Driver for Broadcom BCM2835 SoC temperature sensor
+ *
+ * Copyright (C) 2016 Martin Sperl
+ *
+ * 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/clk.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/thermal.h>
+
+#define BCM2835_TS_TSENSCTL			0x00
+#define BCM2835_TS_TSENSSTAT			0x04
+
+#define BCM2835_TS_TSENSCTL_PRWDW		BIT(0)
+#define BCM2835_TS_TSENSCTL_RSTB		BIT(1)
+
+/*
+ * bandgap reference voltage in 6 mV increments
+ * 000b = 1178 mV, 001b = 1184 mV, ... 111b = 1220 mV
+ */
+#define BCM2835_TS_TSENSCTL_CTRL_BITS		3
+#define BCM2835_TS_TSENSCTL_CTRL_SHIFT		2
+#define BCM2835_TS_TSENSCTL_CTRL_MASK		    \
+	GENMASK(BCM2835_TS_TSENSCTL_CTRL_BITS +     \
+		BCM2835_TS_TSENSCTL_CTRL_SHIFT - 1, \
+		BCM2835_TS_TSENSCTL_CTRL_SHIFT)
+#define BCM2835_TS_TSENSCTL_CTRL_DEFAULT	1
+#define BCM2835_TS_TSENSCTL_EN_INT		BIT(5)
+#define BCM2835_TS_TSENSCTL_DIRECT		BIT(6)
+#define BCM2835_TS_TSENSCTL_CLR_INT		BIT(7)
+#define BCM2835_TS_TSENSCTL_THOLD_SHIFT		8
+#define BCM2835_TS_TSENSCTL_THOLD_BITS		10
+#define BCM2835_TS_TSENSCTL_THOLD_MASK		     \
+	GENMASK(BCM2835_TS_TSENSCTL_THOLD_BITS +     \
+		BCM2835_TS_TSENSCTL_THOLD_SHIFT - 1, \
+		BCM2835_TS_TSENSCTL_THOLD_SHIFT)
+/*
+ * time how long the block to be asserted in reset
+ * which based on a clock counter (TSENS clock assumed)
+ */
+#define BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT	18
+#define BCM2835_TS_TSENSCTL_RSTDELAY_BITS	8
+#define BCM2835_TS_TSENSCTL_REGULEN		BIT(26)
+
+#define BCM2835_TS_TSENSSTAT_DATA_BITS		10
+#define BCM2835_TS_TSENSSTAT_DATA_SHIFT		0
+#define BCM2835_TS_TSENSSTAT_DATA_MASK		     \
+	GENMASK(BCM2835_TS_TSENSSTAT_DATA_BITS +     \
+		BCM2835_TS_TSENSSTAT_DATA_SHIFT - 1, \
+		BCM2835_TS_TSENSSTAT_DATA_SHIFT)
+#define BCM2835_TS_TSENSSTAT_VALID		BIT(10)
+#define BCM2835_TS_TSENSSTAT_INTERRUPT		BIT(11)
+
+struct bcm2835_thermal_data {
+	struct thermal_zone_device *tz;
+	void __iomem *regs;
+	struct clk *clk;
+	struct dentry *debugfsdir;
+};
+
+static int bcm2835_thermal_adc2temp(u32 adc, int offset, int slope)
+{
+	return offset + slope * adc;
+}
+
+static int bcm2835_thermal_temp2adc(int temp, int offset, int slope)
+{
+	temp -= offset;
+	temp /= slope;
+
+	if (temp < 0)
+		temp = 0;
+	if (temp >= BIT(BCM2835_TS_TSENSSTAT_DATA_BITS))
+		temp = BIT(BCM2835_TS_TSENSSTAT_DATA_BITS) - 1;
+
+	return temp;
+}
+
+static int bcm2835_thermal_get_temp(void *d, int *temp)
+{
+	struct bcm2835_thermal_data *data = d;
+	u32 val = readl(data->regs + BCM2835_TS_TSENSSTAT);
+
+	if (!(val & BCM2835_TS_TSENSSTAT_VALID))
+		return -EIO;
+
+	val &= BCM2835_TS_TSENSSTAT_DATA_MASK;
+
+	*temp = bcm2835_thermal_adc2temp(
+		val,
+		thermal_zone_get_offset(data->tz),
+		thermal_zone_get_slope(data->tz));
+
+	return 0;
+}
+
+static const struct debugfs_reg32 bcm2835_thermal_regs[] = {
+	{
+		.name = "ctl",
+		.offset = 0
+	},
+	{
+		.name = "stat",
+		.offset = 4
+	}
+};
+
+static void bcm2835_thermal_debugfs(struct platform_device *pdev)
+{
+	struct thermal_zone_device *tz = platform_get_drvdata(pdev);
+	struct bcm2835_thermal_data *data = tz->devdata;
+	struct debugfs_regset32 *regset;
+
+	data->debugfsdir = debugfs_create_dir("bcm2835_thermal", NULL);
+	if (!data->debugfsdir)
+		return;
+
+	regset = devm_kzalloc(&pdev->dev, sizeof(*regset), GFP_KERNEL);
+	if (!regset)
+		return;
+
+	regset->regs = bcm2835_thermal_regs;
+	regset->nregs = ARRAY_SIZE(bcm2835_thermal_regs);
+	regset->base = data->regs;
+
+	debugfs_create_regset32("regset", 0444, data->debugfsdir, regset);
+}
+
+static struct thermal_zone_of_device_ops bcm2835_thermal_ops = {
+	.get_temp = bcm2835_thermal_get_temp,
+};
+
+/*
+ * Note: as per Raspberry Foundation FAQ
+ * (https://www.raspberrypi.org/help/faqs/#performanceOperatingTemperature)
+ * the recommended temperature range for the SoC -40C to +85C
+ * so the trip limit is set to 80C.
+ * this applies to all the BCM283X SoC
+ */
+
+static const struct of_device_id bcm2835_thermal_of_match_table[] = {
+	{
+		.compatible = "brcm,bcm2835-thermal",
+	},
+	{
+		.compatible = "brcm,bcm2836-thermal",
+	},
+	{
+		.compatible = "brcm,bcm2837-thermal",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table);
+
+static int bcm2835_thermal_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	struct thermal_zone_device *tz;
+	struct bcm2835_thermal_data *data;
+	struct resource *res;
+	int err = 0;
+	u32 val;
+	unsigned long rate;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	match = of_match_device(bcm2835_thermal_of_match_table,
+				&pdev->dev);
+	if (!match)
+		return -EINVAL;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	data->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(data->regs)) {
+		err = PTR_ERR(data->regs);
+		dev_err(&pdev->dev, "Could not get registers: %d\n", err);
+		return err;
+	}
+
+	data->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(data->clk)) {
+		err = PTR_ERR(data->clk);
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Could not get clk: %d\n", err);
+		return err;
+	}
+
+	err = clk_prepare_enable(data->clk);
+	if (err)
+		return err;
+
+	rate = clk_get_rate(data->clk);
+	if ((rate < 1920000) || (rate > 5000000))
+		dev_warn(&pdev->dev,
+			 "Clock %pCn running at %pCr Hz is outside of the recommended range: 1.92 to 5MHz\n",
+			 data->clk, data->clk);
+
+	/* register of thermal sensor and get info from DT */
+	tz = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
+					     &bcm2835_thermal_ops);
+	if (IS_ERR(tz)) {
+		err = PTR_ERR(tz);
+		dev_err(&pdev->dev,
+			"Failed to register the thermal device: %d\n",
+			err);
+		goto err_clk;
+	}
+
+	/*
+	 * right now the FW does set up the HW-block, so we are not
+	 * touching the configuration registers.
+	 * But if the HW is not enabled, then set it up
+	 * using "sane" values used by the firmware right now.
+	 */
+	val = readl(data->regs + BCM2835_TS_TSENSCTL);
+	if (!(val & BCM2835_TS_TSENSCTL_RSTB)) {
+		int trip_temp, offset, slope;
+
+		slope = thermal_zone_get_slope(tz);
+		offset = thermal_zone_get_offset(tz);
+		/*
+		 * For now we deal only with critical, otherwise
+		 * would need to iterate
+		 */
+		err = tz->ops->get_trip_temp(tz, 0, &trip_temp);
+		if (err < 0) {
+			err = PTR_ERR(tz);
+			dev_err(&pdev->dev,
+				"Not able to read trip_temp: %d\n",
+				err);
+			goto err_tz;
+		}
+
+		/* set bandgap reference voltage and enable voltage regulator */
+		val = (BCM2835_TS_TSENSCTL_CTRL_DEFAULT <<
+		       BCM2835_TS_TSENSCTL_CTRL_SHIFT) |
+		      BCM2835_TS_TSENSCTL_REGULEN;
+
+		/* use the recommended reset duration */
+		val |= (0xFE << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT);
+
+		/*  trip_adc value from info */
+		val |= bcm2835_thermal_temp2adc(trip_temp,
+						offset,
+						slope)
+			<< BCM2835_TS_TSENSCTL_THOLD_SHIFT;
+
+		/* write the value back to the register as 2 steps */
+		writel(val, data->regs + BCM2835_TS_TSENSCTL);
+		val |= BCM2835_TS_TSENSCTL_RSTB;
+		writel(val, data->regs + BCM2835_TS_TSENSCTL);
+	}
+
+	data->tz = tz;
+
+	platform_set_drvdata(pdev, tz);
+
+	bcm2835_thermal_debugfs(pdev);
+
+	return 0;
+err_tz:
+	thermal_zone_of_sensor_unregister(&pdev->dev, tz);
+err_clk:
+	clk_disable_unprepare(data->clk);
+
+	return err;
+}
+
+static int bcm2835_thermal_remove(struct platform_device *pdev)
+{
+	struct thermal_zone_device *tz = platform_get_drvdata(pdev);
+	struct bcm2835_thermal_data *data = tz->devdata;
+
+	debugfs_remove_recursive(data->debugfsdir);
+	thermal_zone_of_sensor_unregister(&pdev->dev, tz);
+	clk_disable_unprepare(data->clk);
+
+	return 0;
+}
+
+static struct platform_driver bcm2835_thermal_driver = {
+	.probe = bcm2835_thermal_probe,
+	.remove = bcm2835_thermal_remove,
+	.driver = {
+		.name = "bcm2835_thermal",
+		.of_match_table = bcm2835_thermal_of_match_table,
+	},
+};
+module_platform_driver(bcm2835_thermal_driver);
+
+MODULE_AUTHOR("Martin Sperl");
+MODULE_DESCRIPTION("Thermal driver for bcm2835 chip");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V12 3/4] ARM64: dts: bcm2837: Define CPU thermal coefficients
From: Stefan Wahren @ 2017-03-31 20:03 UTC (permalink / raw)
  To: Eduardo Valentin, Zhang Rui, kernel
  Cc: Eric Anholt, Rob Herring, Frank Rowand, Florian Fainelli,
	Rafał Miłecki, linux-rpi-kernel, devicetree, linux-pm,
	Stefan Wahren
In-Reply-To: <1490990586-30898-1-git-send-email-stefan.wahren@i2se.com>

This defines the bcm2837 SoC specific thermal coefficients in
order to initialize the thermal driver correctly.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 arch/arm64/boot/dts/broadcom/bcm2837.dtsi |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
index 19f2fe6..2d5de6f0 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
@@ -75,6 +75,10 @@
 	interrupts = <8>;
 };
 
+&cpu_thermal {
+	coefficients = <(-538)	412000>;
+};
+
 /* enable thermal sensor with the correct compatible property set */
 &thermal {
 	compatible = "brcm,bcm2837-thermal";
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V12 2/4] ARM: dts: bcm283x: Add CPU thermal zone with 1 trip point
From: Stefan Wahren @ 2017-03-31 20:03 UTC (permalink / raw)
  To: Eduardo Valentin, Zhang Rui, kernel-TqfNSX0MhmxHKSADF0wUEw
  Cc: Eric Anholt, Rob Herring, Frank Rowand, Florian Fainelli,
	Rafał Miłecki,
	linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-pm-u79uwXL29TY76Z2rM5mHXA, Stefan Wahren
In-Reply-To: <1490990586-30898-1-git-send-email-stefan.wahren-eS4NqCHxEME@public.gmane.org>

As suggested by Eduardo Valentin this adds the thermal zone for
the bcm2835 SoC with its single thermal sensor. We start with
the criticial trip point and leave the cooling devices empty
since we don't have any at the moment. Since the coefficients
could vary depending on the SoC we need to define them separate.

Signed-off-by: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
---
 arch/arm/boot/dts/bcm2835.dtsi |    4 ++++
 arch/arm/boot/dts/bcm2836.dtsi |    4 ++++
 arch/arm/boot/dts/bcm283x.dtsi |   21 +++++++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 0890d97..659b6e9 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -24,6 +24,10 @@
 	};
 };
 
+&cpu_thermal {
+	coefficients = <(-538)	407000>;
+};
+
 /* enable thermal sensor with the correct compatible property set */
 &thermal {
 	compatible = "brcm,bcm2835-thermal";
diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
index 519a44f..da3deeb 100644
--- a/arch/arm/boot/dts/bcm2836.dtsi
+++ b/arch/arm/boot/dts/bcm2836.dtsi
@@ -77,6 +77,10 @@
 	interrupts = <8>;
 };
 
+&cpu_thermal {
+	coefficients = <(-538)	407000>;
+};
+
 /* enable thermal sensor with the correct compatible property set */
 &thermal {
 	compatible = "brcm,bcm2836-thermal";
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index a3106aa..9bc0a1c9 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -19,6 +19,26 @@
 		bootargs = "earlyprintk console=ttyAMA0";
 	};
 
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&thermal>;
+
+			trips {
+				cpu-crit {
+					temperature	= <80000>;
+					hysteresis	= <0>;
+					type		= "critical";
+				};
+			};
+
+			cooling-maps {
+			};
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -394,6 +414,7 @@
 			compatible = "brcm,bcm2835-thermal";
 			reg = <0x7e212000 0x8>;
 			clocks = <&clocks BCM2835_CLOCK_TSENS>;
+			#thermal-sensor-cells = <0>;
 			status = "disabled";
 		};
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH V12 1/4] dt-bindings: Add thermal zone to bcm2835-thermal example
From: Stefan Wahren @ 2017-03-31 20:03 UTC (permalink / raw)
  To: Eduardo Valentin, Zhang Rui, kernel
  Cc: Eric Anholt, Rob Herring, Frank Rowand, Florian Fainelli,
	Rafał Miłecki, linux-rpi-kernel, devicetree, linux-pm,
	Stefan Wahren
In-Reply-To: <1490990586-30898-1-git-send-email-stefan.wahren@i2se.com>

Add a thermal zone in order to make the example complete.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../bindings/thermal/brcm,bcm2835-thermal.txt      |   32 +++++++++++++++++---
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
index 474531d..da8c5b7 100644
--- a/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
@@ -3,15 +3,39 @@ Binding for Thermal Sensor driver for BCM2835 SoCs.
 Required parameters:
 -------------------
 
-compatible: 	should be one of: "brcm,bcm2835-thermal",
-		"brcm,bcm2836-thermal" or "brcm,bcm2837-thermal"
-reg:		Address range of the thermal registers.
-clocks: 	Phandle of the clock used by the thermal sensor.
+compatible: 		should be one of: "brcm,bcm2835-thermal",
+			"brcm,bcm2836-thermal" or "brcm,bcm2837-thermal"
+reg:			Address range of the thermal registers.
+clocks: 		Phandle of the clock used by the thermal sensor.
+#thermal-sensor-cells:	should be 0 (see thermal.txt)
 
 Example:
 
+thermal-zones {
+	cpu_thermal: cpu-thermal {
+		polling-delay-passive = <0>;
+		polling-delay = <1000>;
+
+		thermal-sensors = <&thermal>;
+
+		trips {
+			cpu-crit {
+				temperature	= <80000>;
+				hysteresis	= <0>;
+				type		= "critical";
+			};
+		};
+
+		coefficients = <(-538)	407000>;
+
+		cooling-maps {
+		};
+	};
+};
+
 thermal: thermal@7e212000 {
 	compatible = "brcm,bcm2835-thermal";
 	reg = <0x7e212000 0x8>;
 	clocks = <&clocks BCM2835_CLOCK_TSENS>;
+	#thermal-sensor-cells = <0>;
 };
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V12 0/4] thermal: bcm2835: add thermal driver for bcm2835 SoC
From: Stefan Wahren @ 2017-03-31 20:03 UTC (permalink / raw)
  To: Eduardo Valentin, Zhang Rui, kernel-TqfNSX0MhmxHKSADF0wUEw
  Cc: Eric Anholt, Rob Herring, Frank Rowand, Florian Fainelli,
	Rafał Miłecki,
	linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-pm-u79uwXL29TY76Z2rM5mHXA, Stefan Wahren

This is an attempt to finish Martin's great work on the bcm2835
thermal driver. It includes now all Eduardo's suggestions and the
explanations from the Raspberry Pi forum [1].

ChangeLog:
V1 -> V2: added specific settings depending on compatiblity
added trip point based on register
setting up ctrl-register if HW is not enabled by firmware
as per recommendation of Eric (untested)
check that clock frequency is in range
(1.9 - 5MHz - as per comment in clk-bcm2835.c)
V2 -> V4: moved back to thermal (not using bcm sub-directory)
set polling interval to 1second (was 0ms, so interrupt driven)
V5 -> V6: added correct depends in KConfig
removed defined default for RESET_DELAY
removed obvious comments
clarify HW setup comments if not set up by FW already
move clk_prepare_enable to an earlier stage and add error handling
clarify warning when TS-clock runs out of recommended range
clk_disable_unprepare added in bcm2835_thermal_remove
added comment on recommended temperature ranges for SOC
V6 -> V7: removed depends on ARCH_BCM2836 || ARCH_BCM2837 in Kconfig
V7 -> V8: rebased
V8 -> V9: moved to use the thermal framework offset and slope in
thermal_zone_parameters as per request
V9 -> V10: implement support for thermal zone descriptor, define offset and
slope within DT, apply forum explanations, replace symbolic with octal
permissions
V10 -> V11: fix parse issue in bcm2837.dtsi, fix probing and remove unused tzp
V11 -> V12: split of-thermal changes from this series since they aren't
necessary, avoid double definition of matching table

[1] - https://www.raspberrypi.org/forums/viewtopic.php?f=72&t=160289&p=1040448

Stefan Wahren (4):
  dt-bindings: Add thermal zone to bcm2835-thermal example
  ARM: dts: bcm283x: Add CPU thermal zone with 1 trip point
  ARM64: dts: bcm2837: Define CPU thermal coefficients
  thermal: bcm2835: add thermal driver for bcm2835 SoC

 .../bindings/thermal/brcm,bcm2835-thermal.txt      |   32 +-
 arch/arm/boot/dts/bcm2835.dtsi                     |    4 +
 arch/arm/boot/dts/bcm2836.dtsi                     |    4 +
 arch/arm/boot/dts/bcm283x.dtsi                     |   21 ++
 arch/arm64/boot/dts/broadcom/bcm2837.dtsi          |    4 +
 drivers/thermal/Kconfig                            |    8 +
 drivers/thermal/Makefile                           |    1 +
 drivers/thermal/bcm2835_thermal.c                  |  314 ++++++++++++++++++++
 8 files changed, 384 insertions(+), 4 deletions(-)
 create mode 100644 drivers/thermal/bcm2835_thermal.c

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] arm64: dts: rk3399: add support for firefly-rk3399 board
From: Heiko Stuebner @ 2017-03-31 19:41 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Kever Yang, linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Jianqun Xu,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andy Yan, Rob Herring,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Will Deacon,
	Mark Rutland, Catalin Marinas, Matthias Brugger
In-Reply-To: <9cfe8ee4-16bc-fa5a-78bc-1939d595101a-l3A5Bk7waGM@public.gmane.org>

Hi,

Am Freitag, 31. März 2017, 18:59:49 CEST schrieb Andreas Färber:
> Am 31.03.2017 um 14:56 schrieb Heiko Stuebner:
> > Hi Kever,
> > 
> > Am Freitag, 31. März 2017, 17:59:07 CEST schrieb Kever Yang:
> >> Firefly-rk3399 is a bord from T-Firefly, you can find detail about
> >> it here:
> >> http://en.t-firefly.com/en/firenow/Firefly_RK3399/
> >>
> >> This patch add basic node for the board and make it able to bring
> >> up.
> > 
> > This more a first glance, I didn't check every binding, but already found
> > some dubious ones, so in general, please make sure to only include nodes
> > with approved bindings.
> > 
> > 
> > [...]
> > 
> >>  arch/arm64/boot/dts/rockchip/Makefile           |   1 +
> >>  arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 772 ++++++++++++++++++++++++
> > 
> > please provide a binding addition for the board in a separate patch as well.
> > 
> > 
> >>  2 files changed, 773 insertions(+)
> >>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
> >>
> >> diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> >> index 3a86289..dd3d550 100644
> >> --- a/arch/arm64/boot/dts/rockchip/Makefile
> >> +++ b/arch/arm64/boot/dts/rockchip/Makefile
> >> @@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb
> >>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-px5-evb.dtb
> >>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb
> >>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-evb.dtb
> >> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb
> > 
> > if possible, please rebase on top of my for-next branch, as we also
> > have the first gru board in there now.
> > 
> >>  
> >>  always		:= $(dtb-y)
> >>  subdir-y	:= $(dts-dirs)
> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
> >> new file mode 100644
> >> index 0000000..686977b
> >> --- /dev/null
> >> +++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
> >> @@ -0,0 +1,772 @@
> >> +/*
> >> + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
> 
> "Ltd."?
> 
> >> + *
> >> + * This file is dual-licensed: you can use it either under the terms
> >> + * of the GPL or the X11 license, at your option. Note that this dual
> >> + * licensing only applies to this file, and not this project as a
> >> + * whole.
> >> + *
> >> + *  a) This file 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 file 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.
> >> + *
> >> + * Or, alternatively,
> >> + *
> >> + *  b) Permission is hereby granted, free of charge, to any person
> >> + *     obtaining a copy of this software and associated documentation
> >> + *     files (the "Software"), to deal in the Software without
> >> + *     restriction, including without limitation the rights to use,
> >> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> >> + *     sell copies of the Software, and to permit persons to whom the
> >> + *     Software is furnished to do so, subject to the following
> >> + *     conditions:
> >> + *
> >> + *     The above copyright notice and this permission notice shall be
> >> + *     included in all copies or substantial portions of the Software.
> >> + *
> >> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> >> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> >> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> >> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> >> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> >> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> >> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> >> + *     OTHER DEALINGS IN THE SOFTWARE.
> 
> This should be shorter: "SPDX-License-Identifier: GPL-2.0+ OR MIT"

I'm not sure about that. There was disagreement over using SPDX in some
other dts [0]. Sadly it doesn't look like it was resolved either way.

Asking armsoc people on IRC just now, there really isn't any decision one
way or another, so please stay with real license texts until there is an
actual consensus on using spdx tags instead of license texts.


[0] https://lkml.org/lkml/2017/2/28/750

> 
> >> + */
> >> +
> >> +/dts-v1/;
> >> +#include <dt-bindings/pwm/pwm.h>
> >> +#include "rk3399.dtsi"
> >> +
> >> +/ {
> >> +	model = "Rockchip RK3399 Firefly Board (Linux Opensource)";
> 
> "(Linux Opensource)" is not a hardware description, please drop.
> 
> >> +	compatible = "rockchip,rk3399-firefly-linux", "rockchip,rk3399";
> > 
> > Just to make sure, is this really a Rockchip board? I would've expected
> > to see something like "firefly,firefly-rk3399" here, like on the rk3288-
> > variant. Not a requirement, just a question to clarify who designed the
> > board please :-) .
> 
> +1, especially no -linux suffix please. The same device tree should in
> theory be usable with Linux, Android, FreeBSD or any other OS with
> drivers based on the official bindings.
> 
> >> +
> >> +	backlight: backlight {
> >> +		status = "okay";
> >> +		compatible = "pwm-backlight";
> >> +		enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
> >> +		pwms = <&pwm0 0 25000 0>;
> >> +		brightness-levels = <
> >> +			  0   1   2   3   4   5   6   7
> >> +			  8   9  10  11  12  13  14  15
> >> +			 16  17  18  19  20  21  22  23
> >> +			 24  25  26  27  28  29  30  31
> >> +			 32  33  34  35  36  37  38  39
> >> +			 40  41  42  43  44  45  46  47
> >> +			 48  49  50  51  52  53  54  55
> >> +			 56  57  58  59  60  61  62  63
> >> +			 64  65  66  67  68  69  70  71
> >> +			 72  73  74  75  76  77  78  79
> >> +			 80  81  82  83  84  85  86  87
> >> +			 88  89  90  91  92  93  94  95
> >> +			 96  97  98  99 100 101 102 103
> >> +			104 105 106 107 108 109 110 111
> >> +			112 113 114 115 116 117 118 119
> >> +			120 121 122 123 124 125 126 127
> >> +			128 129 130 131 132 133 134 135
> >> +			136 137 138 139 140 141 142 143
> >> +			144 145 146 147 148 149 150 151
> >> +			152 153 154 155 156 157 158 159
> >> +			160 161 162 163 164 165 166 167
> >> +			168 169 170 171 172 173 174 175
> >> +			176 177 178 179 180 181 182 183
> >> +			184 185 186 187 188 189 190 191
> >> +			192 193 194 195 196 197 198 199
> >> +			200 201 202 203 204 205 206 207
> >> +			208 209 210 211 212 213 214 215
> >> +			216 217 218 219 220 221 222 223
> >> +			224 225 226 227 228 229 230 231
> >> +			232 233 234 235 236 237 238 239
> >> +			240 241 242 243 244 245 246 247
> >> +			248 249 250 251 252 253 254 255>;
> >> +		default-brightness-level = <200>;
> >> +	};
> >> +
> >> +	clkin_gmac: external-gmac-clock {
> >> +		compatible = "fixed-clock";
> >> +		clock-frequency = <125000000>;
> >> +		clock-output-names = "clkin_gmac";
> >> +		#clock-cells = <0>;
> >> +	};
> >> +
> >> +	rt5640-sound {
> 
> Drop rt5640- node prefix, or is there more than one?

There can be more, the dw_hdmi (once we support graphics) also brings its
sound node, if I remember correctly.


> 
> >> +		compatible = "simple-audio-card";
> >> +		simple-audio-card,format = "i2s";
> >> +		simple-audio-card,name = "rockchip,rt5640-codec";
> >> +		simple-audio-card,mclk-fs = <256>;
> >> +		simple-audio-card,widgets =
> >> +			"Microphone", "Mic Jack",
> >> +			"Headphone", "Headphone Jack";
> >> +		simple-audio-card,routing =
> >> +			"Mic Jack", "MICBIAS1",
> >> +			"IN1P", "Mic Jack",
> >> +			"Headphone Jack", "HPOL",
> >> +			"Headphone Jack", "HPOR";
> >> +		simple-audio-card,cpu {
> >> +			sound-dai = <&i2s1>;
> >> +		};
> >> +		simple-audio-card,codec {
> >> +			sound-dai = <&rt5640>;
> >> +		};
> 
> Insert while lines before these two nodes for readability?
> 
> >> +	};
> >> +
> >> +	sdio_pwrseq: sdio-pwrseq {
> >> +		compatible = "mmc-pwrseq-simple";
> >> +		clocks = <&rk808 1>;
> >> +		clock-names = "ext_clock";
> >> +		pinctrl-names = "default";
> >> +		pinctrl-0 = <&wifi_enable_h>;
> >> +
> >> +		/*
> >> +		 * On the module itself this is one of these (depending
> >> +		 * on the actual card populated):
> >> +		 * - SDIO_RESET_L_WL_REG_ON
> >> +		 * - PDN (power down when low)
> >> +		 */
> >> +		reset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; /* GPIO0_B2 */
> > 
> > Thanks to Andy's persistence, we have nice constants in the pinctrl-
> > binding-header now, like RK_PB2 for the above. So you can drop the
> > comment and use the constant instead for easier reading.
> > Same for other pins.
> > 
> > 
> >> +	};
> >> +
> >> +	vcc3v3_pcie: vcc3v3-pcie-regulator {
> >> +		compatible = "regulator-fixed";
> >> +		enable-active-high;
> >> +		regulator-always-on;
> >> +		regulator-boot-on;
> >> +		gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>;
> >> +		pinctrl-names = "default";
> >> +		pinctrl-0 = <&pcie_drv>;
> >> +		regulator-name = "vcc3v3_pcie";
> >> +	};
> >> +
> >> +	vcc3v3_sys: vcc3v3-sys {
> >> +		compatible = "regulator-fixed";
> >> +		regulator-name = "vcc3v3_sys";
> >> +		regulator-always-on;
> >> +		regulator-boot-on;
> >> +		regulator-min-microvolt = <3300000>;
> >> +		regulator-max-microvolt = <3300000>;
> >> +	};
> >> +
> >> +	vcc5v0_host: vcc5v0-host-regulator {
> >> +		compatible = "regulator-fixed";
> >> +		enable-active-high;
> >> +		gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>;
> >> +		pinctrl-names = "default";
> >> +		pinctrl-0 = <&host_vbus_drv>;
> >> +		regulator-name = "vcc5v0_host";
> >> +		regulator-always-on;
> >> +	};
> >> +
> >> +	vcc5v0_sys: vcc5v0-sys {
> >> +		compatible = "regulator-fixed";
> >> +		regulator-name = "vcc5v0_sys";
> >> +		regulator-always-on;
> >> +		regulator-boot-on;
> >> +		regulator-min-microvolt = <5000000>;
> >> +		regulator-max-microvolt = <5000000>;
> >> +	};
> >> +
> >> +	vcc_phy: vcc-phy-regulator {
> >> +		compatible = "regulator-fixed";
> >> +		regulator-name = "vcc_phy";
> >> +		regulator-always-on;
> >> +		regulator-boot-on;
> >> +	};
> >> +
> >> +	vdd_log: vdd-log {
> >> +		compatible = "pwm-regulator";
> >> +		pwms = <&pwm2 0 25000 1>;
> >> +		regulator-name = "vdd_log";
> >> +		regulator-min-microvolt = <800000>;
> >> +		regulator-max-microvolt = <1400000>;
> >> +		regulator-always-on;
> >> +		regulator-boot-on;
> >> +
> >> +		/* for rockchip boot on */
> >> +		rockchip,pwm_id= <2>;
> >> +		rockchip,pwm_voltage = <1000000>;
> >> +	};
> >> +
> >> +	vccadc_ref: vccadc-ref {
> >> +		compatible = "regulator-fixed";
> >> +		regulator-name = "vcc1v8_sys";
> >> +		regulator-always-on;
> >> +		regulator-boot-on;
> >> +		regulator-min-microvolt = <1800000>;
> >> +		regulator-max-microvolt = <1800000>;
> >> +	};
> >> +
> >> +	wireless-wlan {
> >> +		compatible = "wlan-platdata";
> >> +		rockchip,grf = <&grf>;
> >> +		wifi_chip_type = "ap6354";
> >> +		sdio_vref = <1800>;
> >> +		WIFI,host_wake_irq = <&gpio0 3 GPIO_ACTIVE_HIGH>; /* GPIO0_a3 */
> >> +		status = "okay";
> > 
> > that is not a valid binding, am I right? ;-)
> > So should be dropped.
> 
> ... or should be replaced by the proper binding (brcmfmac probably?).
> 
> > 
> >> +	};
> >> +
> >> +	wireless-bluetooth {
> >> +		compatible = "bluetooth-platdata";
> >> +		//wifi-bt-power-toggle;
> >> +		uart_rts_gpios = <&gpio2 19 GPIO_ACTIVE_LOW>; /* GPIO2_C3 */
> >> +		pinctrl-names = "default", "rts_gpio";
> >> +		pinctrl-0 = <&uart0_rts>;
> >> +		pinctrl-1 = <&uart0_gpios>;
> >> +		//BT,power_gpio  = <&gpio3 19 GPIO_ACTIVE_HIGH>; /* GPIOx_xx */
> >> +		BT,reset_gpio    = <&gpio0 9 GPIO_ACTIVE_HIGH>; /* GPIO0_B1 */
> >> +		BT,wake_gpio     = <&gpio2 26 GPIO_ACTIVE_HIGH>; /* GPIO2_D2 */
> >> +		BT,wake_host_irq = <&gpio0 4 GPIO_ACTIVE_HIGH>; /* GPIO0_A4 */
> >> +		status = "okay";
> >> +	};
> > 
> > same here
> 
> Move to corresponding uart node? (serdev bindings)

Oh, did this get merged, that would be pretty cool.


> >> +};
> >> +
> >> +&cpu_l0 {
> >> +	cpu-supply = <&vdd_cpu_l>;
> >> +};
> >> +
> >> +&cpu_l1 {
> >> +	cpu-supply = <&vdd_cpu_l>;
> >> +};
> >> +
> >> +&cpu_l2 {
> >> +	cpu-supply = <&vdd_cpu_l>;
> >> +};
> >> +
> >> +&cpu_l3 {
> >> +	cpu-supply = <&vdd_cpu_l>;
> >> +};
> >> +
> >> +&cpu_b0 {
> >> +	cpu-supply = <&vdd_cpu_b>;
> >> +};
> >> +
> >> +&cpu_b1 {
> >> +	cpu-supply = <&vdd_cpu_b>;
> >> +};
> >> +
> >> +&emmc_phy {
> >> +	status = "okay";
> >> +};
> >> +
> >> +&gmac {
> >> +	assigned-clocks = <&cru SCLK_RMII_SRC>;
> >> +	assigned-clock-parents = <&clkin_gmac>;
> >> +	clock_in_out = "input";
> >> +	phy-supply = <&vcc_phy>;
> >> +	phy-mode = "rgmii";
> >> +	pinctrl-names = "default";
> >> +	pinctrl-0 = <&rgmii_pins>;
> >> +	snps,reset-gpio = <&gpio3 15 GPIO_ACTIVE_LOW>;
> >> +	snps,reset-active-low;
> >> +	snps,reset-delays-us = <0 10000 50000>;
> >> +	tx_delay = <0x28>;
> >> +	rx_delay = <0x11>;
> >> +	status = "okay";
> >> +};
> >> +
> >> +&i2c0 {
> >> +	status = "okay";
> >> +	i2c-scl-rising-time-ns = <168>;
> >> +	i2c-scl-falling-time-ns = <4>;
> >> +	clock-frequency = <400000>;
> >> +
> >> +	vdd_cpu_b: syr827@40 {
> 
> Node name should not duplicate the model. pmic@40?

Thanks Andreas for finding all these little bits :-)


Heiko
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v5 16/24] dt-bindings: PCI: dra7xx: Add dt bindings to enable unaligned access
From: Rob Herring @ 2017-03-31 19:07 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Bjorn Helgaas, Joao Pinto, linux-pci, linux-doc, linux-kernel,
	devicetree, linux-omap, linux-arm-kernel, hch, nsekhar
In-Reply-To: <20170327094520.3129-17-kishon@ti.com>

On Mon, Mar 27, 2017 at 03:15:12PM +0530, Kishon Vijay Abraham I wrote:
> Update device tree binding documentation of TI's dra7xx PCI
> controller to include property for enabling unaligned mem access.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  Documentation/devicetree/bindings/pci/ti-pci.txt | 5 +++++
>  1 file changed, 5 insertions(+)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* Re: [PATCH v5 14/24] dt-bindings: mfd: syscon: Add documentation for #syscon-cells property
From: Rob Herring @ 2017-03-31 19:06 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Bjorn Helgaas, Joao Pinto, linux-pci, linux-doc, linux-kernel,
	devicetree, linux-omap, linux-arm-kernel, hch, nsekhar
In-Reply-To: <20170331185852.mxa4gvjxbuxl65dq@rob-hp-laptop>

On Fri, Mar 31, 2017 at 01:58:52PM -0500, Rob Herring wrote:
> On Mon, Mar 27, 2017 at 03:15:10PM +0530, Kishon Vijay Abraham I wrote:
> > Add documentation for the optional #syscon-cells property to determine
> > the number of cells that should be given in the phandle while
> > referencing the syscon-node.
> > 
> > Suggested-by: Rob Herring <robh@kernel.org>
> 
> I did? When?
> 
> I'm not remembering why we need this. Generally, phandles to a syscon 
> are for a single defined purpose. When do we need a list of them?

Ah, I remember now the context. I suggested using standard parsing 
function rather than open coding. I wasn't suggesting changing the 
binding. Instead of of_parse_phandle_with_args, can't 
of_parse_phandle_with_fixed_args work?

Rob

^ permalink raw reply

* Re: [PATCH v5 14/24] dt-bindings: mfd: syscon: Add documentation for #syscon-cells property
From: Rob Herring @ 2017-03-31 18:58 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Bjorn Helgaas, Joao Pinto, linux-pci, linux-doc, linux-kernel,
	devicetree, linux-omap, linux-arm-kernel, hch, nsekhar
In-Reply-To: <20170327094520.3129-15-kishon@ti.com>

On Mon, Mar 27, 2017 at 03:15:10PM +0530, Kishon Vijay Abraham I wrote:
> Add documentation for the optional #syscon-cells property to determine
> the number of cells that should be given in the phandle while
> referencing the syscon-node.
> 
> Suggested-by: Rob Herring <robh@kernel.org>

I did? When?

I'm not remembering why we need this. Generally, phandles to a syscon 
are for a single defined purpose. When do we need a list of them?

Rob

> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  Documentation/devicetree/bindings/mfd/syscon.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/syscon.txt b/Documentation/devicetree/bindings/mfd/syscon.txt
> index 408f768686f1..446b47e8fb71 100644
> --- a/Documentation/devicetree/bindings/mfd/syscon.txt
> +++ b/Documentation/devicetree/bindings/mfd/syscon.txt
> @@ -16,6 +16,8 @@ Required properties:
>  Optional property:
>  - reg-io-width: the size (in bytes) of the IO accesses that should be
>    performed on the device.
> +- #syscon-cells: determine the number of cells that should be given in the
> +  phandle while referencing this syscon-node.
>  
>  Examples:
>  gpr: iomuxc-gpr@020e0000 {
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH RESEND v5 7/7] mfd: dt-bindings: Add RK805 device tree bindings document
From: Rob Herring @ 2017-03-31 18:53 UTC (permalink / raw)
  To: Elaine Zhang
  Cc: lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	huangtao-TNX95d0MmH7DzftRWevZcw, xxx-TNX95d0MmH7DzftRWevZcw,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	chenjh-TNX95d0MmH7DzftRWevZcw, mark.rutland-5wv7dgnIgG8,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	w.egorov-guT5V/WYfQezQB+pC5nmwQ
In-Reply-To: <1490597615-852-1-git-send-email-zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

On Mon, Mar 27, 2017 at 02:53:35PM +0800, Elaine Zhang wrote:
> Add device tree bindings documentation for Rockchip's RK805 PMIC.
> 
> Signed-off-by: Elaine Zhang <zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/mfd/rk808.txt | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 2/3] doc,dts - add XRA1403 DTS binding documentation
From: Rob Herring @ 2017-03-31 18:49 UTC (permalink / raw)
  To: Nandor Han
  Cc: linus.walleij, gnurou, mark.rutland, linux-gpio, devicetree,
	linux-kernel
In-Reply-To: <39ba92bacf48da957f8f85d5cb11d3254fe3d68f.1490595641.git.nandor.han@ge.com>

On Mon, Mar 27, 2017 at 09:23:01AM +0300, Nandor Han wrote:
> Add the XRA1403 DTS binding documentation.

"dt-bindings: gpio: ..." for the subject prefix please.

> 
> Signed-off-by: Nandor Han <nandor.han@ge.com>
> ---
>  .../devicetree/bindings/gpio/gpio-xra1403.txt      | 37 ++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-xra1403.txt
> 
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-xra1403.txt b/Documentation/devicetree/bindings/gpio/gpio-xra1403.txt
> new file mode 100644
> index 0000000..ccf5337
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/gpio-xra1403.txt
> @@ -0,0 +1,37 @@
> +GPIO Driver for XRA1403 16-BIT GPIO Expander With Reset Input from EXAR
> +
> +The XRA1403 is an 16-bit GPIO expander with an SPI interface. Features available:
> +	- Individually programmable inputs:
> +		- Internal pull-up resistors
> +		- Polarity inversion
> +		- Individual interrupt enable
> +		- Rising edge and/or Falling edge interrupt
> +		- Input filter
> +	- Individually programmable outputs
> +		- Output Level Control
> +		- Output Three-State Control
> +
> +Properties
> +----------
> +Check documentation for SPI and GPIO controllers regarding properties needed to configure the node.
> +
> +	- compatible = "exar,xra1403".
> +	- reg = SPI id of the device.
> +	- gpio-controller: mark the node as gpio.

#gpio-cells?

> +
> +Optional properties:
> +-------------------
> +	- reset-gpios: in case available used to control the device reset line.
> +
> +Example
> +--------
> +
> +	gpioxra0: gpio@2 {
> +		compatible = "exar,xra1403";
> +		reg = <2>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		reset-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
> +		spi-max-frequency = <1000000>;
> +		status = "okay";

Don't show status in examples.

> +	};
> -- 
> 2.10.1
> 

^ permalink raw reply

* Re: [PATCH] ARM: dts: armada-38x: label USB and SATA nodes
From: Andrew Lunn @ 2017-03-31 18:21 UTC (permalink / raw)
  To: Ralph Sennhauser
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Jason Cooper,
	Gregory Clement, Sebastian Hesselbarth, Rob Herring, Mark Rutland,
	Russell King, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170331193920.030d9ca8-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Fri, Mar 31, 2017 at 07:39:20PM +0200, Ralph Sennhauser wrote:
> On Fri, 31 Mar 2017 18:50:15 +0200
> Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> wrote:
> 
> > > -			sata@a8000 {
> > > +			satac0: sata@a8000 {  
> > 
> > Hi Ralph
> > 
> > Why the c in satac0?
> 
> For controller and to not conflict with a use case of sata0 for a port,
> similarly to pciec and pcie1. See armada-385-synology-ds116.dts.

:~/linux/arch/arm/boot/dts$ ls *ds116*
ls: cannot access '*ds116*': No such file or directory

But anyway, a few boards seem to solve this by calling the controller
node ahci0: and the port sata0:

> > > -			usb3@f0000 {
> > > +			usb3_0: usb3@f0000 {
> > >  				compatible =
> > > "marvell,armada-380-xhci"; reg = <0xf0000 0x4000>,<0xf4000 0x4000>;
> > >  				interrupts = <GIC_SPI 16
> > > IRQ_TYPE_LEVEL_HIGH>; @@ -598,7 +598,7 @@
> > >  				status = "disabled";
> > >  			};
> > >  
> > > -			usb3@f8000 {
> > > +			usb3_1: usb3@f8000 {
> > >  				compatible =
> > > "marvell,armada-380-xhci"; reg = <0xf8000 0x4000>,<0xfc000 0x4000>;
> > >  				interrupts = <GIC_SPI 17
> > > IRQ_TYPE_LEVEL_HIGH>;  
> > 
> > I can understand what you are saying. But does anybody else care? Are
> > there other .dtsi files differentiating between USB 1.1, 2 and 3?
> 
> It's handled differently where ever I looked, some do some don't. A
> case for distinguishing USB 2.0 and USB 3.0 like this is
> armada-388-gp.dts.

Humm...

                        /* CON4 */
                        usb@58000 {
                                vcc-supply = <&reg_usb2_0_vbus>;
                                status = "okay";
                        };


			/* CON5 */
                        usb3@f0000 {
                                usb-phy = <&usb2_1_phy>;
                                status = "okay";
                        };

                        /* CON7 */
                        usb3@f8000 {
                                usb-phy = <&usb3_phy>;
                                status = "okay";
                        };

Is this clear? Is CON5 a USB 3 host, but has a USB 2 PHY connected to
it? CON7 is the only true USB 3 port? I think some comments written in
schwiizerdütsch would be clearre.:-)

		 Andrew
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFC PATCH 2/5] soc/fsl/qbman: Use shared-dma-pool for QMan private memory allocations
From: Robin Murphy @ 2017-03-31 17:55 UTC (permalink / raw)
  To: Michael Ellerman, roy.pledge-3arQi8VN3Tc,
	oss-fOR+EgIDQEHk1uMJSBkQmQ, linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: madalin.bucur-3arQi8VN3Tc, Mark Rutland
In-Reply-To: <871ste5dmw.fsf-W0DJWXSxmBNbyGPkN3NxC2scP1bn1w/D@public.gmane.org>

On 31/03/17 04:27, Michael Ellerman wrote:
> Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org> writes:
> 
>> Hi Roy,
>>
>> On 29/03/17 22:13, Roy Pledge wrote:
>>> Use the shared-memory-pool mechanism for frame queue descriptor and
>>> packed frame descriptor record area allocations.
>>
>> Thanks for persevering with this - in my opinion it's now looking like
>> it was worth the effort :)
>>
>> AFAICS the ioremap_wc() that this leads to does appear to give back
>> something non-cacheable on PPC (assuming "pgprot_noncached_wc" isn't
>> horrendously misnamed), and "no-map" should rule out any cacheable
>> linear map alias existing, so it would seem that this approach should
>> avert Scott's concerns about attribute mismatches.
> 
> How does 'no-map' translate into something being excluded from the
> linear mapping?

Reserved regions marked with "no-map" get memblock_remove()d by
early_init_dt_alloc_reserved_memory_arch(). As I understand things, the
linear map should only cover memblock areas, and it would be explicitly
violating the semantics of "no-map" to still cover such a region.

Robin.

> 
> cheers
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH V3 0/5] iommu/arm-smmu: Add runtime pm/sleep support
From: Will Deacon @ 2017-03-31 17:54 UTC (permalink / raw)
  To: Sricharan R
  Cc: robin.murphy-5wv7dgnIgG8, joro-zLv9SwRftAIdnm+yROfE0A,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8
In-Reply-To: <1489073748-3659-1-git-send-email-sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

On Thu, Mar 09, 2017 at 09:05:43PM +0530, Sricharan R wrote:
> This series provides the support for turning on the arm-smmu's
> clocks/power domains using runtime pm. This is done using the
> recently introduced device links patches, which lets the symmu's
> runtime to follow the master's runtime pm, so the smmu remains
> powered only when the masters use it.

Do you have any numbers for the power savings you achieve with this?
How often do we actually manage to stop the SMMU clocks on an SoC with
a handful of masters?

In other words, is this too coarse-grained to be useful, or is it common
that all the devices upstream of the SMMU are suspended?

Thanks,

Will

> 
> Took some reference from the exynos runtime patches [2].
> Tested this with MDP, GPU, VENUS devices on apq8096-db820c board.
> 
> Previous version of the patchset [1].
> 
> [V3]
>    * Reworked the patches to keep the clocks init/enabling function
>      seperately for each compatible.
> 
>    * Added clocks bindings for MMU40x/500.
> 
>    * Added a new compatible for qcom,smmu-v2 implementation and
>      the clock bindings for the same.
> 
>    * Rebased on top of 4.11-rc1
> 
> [V2]
>    * Split the patches little differently.
> 
>    * Addressed comments.
> 
>    * Removed the patch #4 [3] from previous post
>      for arm-smmu context save restore. Planning to
>      post this separately after reworking/addressing Robin's
>      feedback.
> 
>    * Reversed the sequence to disable clocks than enabling.
>      This was required for those cases where the
>      clocks are populated in a dependent order from DT.
> 
> [1] https://www.spinics.net/lists/linux-arm-msm/msg23870.html
> [2] https://lkml.org/lkml/2016/10/20/70
> [3] https://patchwork.kernel.org/patch/9389717/
> 
> Sricharan R (5):
>   iommu/arm-smmu: Add pm_runtime/sleep ops
>   iommu/arm-smmu: Add support for MMU40x/500 clocks
>   drivers: arm-smmu: Add clock support for QCOM_SMMUV2
>   iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
>   iommu/arm-smmu: Add the device_link between masters and smmu
> 
>  .../devicetree/bindings/iommu/arm,smmu.txt         |  35 +++
>  drivers/iommu/arm-smmu.c                           | 349 ++++++++++++++++++++-
>  2 files changed, 373 insertions(+), 11 deletions(-)
> 
> -- 
> QUALCOMM INDIA, on behalf of 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 devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox