Linux RTC
 help / color / mirror / Atom feed
* [RFC v3 2/7] platform/x86: intel_pmc_ipc: Use MFD framework to create dependent devices
From: sathyanarayanan.kuppuswamy @ 2017-09-05  5:37 UTC (permalink / raw)
  To: a.zummo, x86, wim, mingo, alexandre.belloni, qipeng.zha, hpa,
	dvhart, tglx, lee.jones, andy, souvik.k.chakravarty
  Cc: linux-rtc, linux-watchdog, linux-kernel, platform-driver-x86,
	sathyaosid, Kuppuswamy Sathyanarayanan
In-Reply-To: <cover.1504588701.git.sathyanarayanan.kuppuswamy@linux.intel.com>

From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>

Currently, we have lot of repetitive code in dependent device resource
allocation and device creation handling code. This logic can be improved if
we use MFD framework for dependent device creation. This patch adds this
support.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
 drivers/platform/x86/intel_pmc_ipc.c | 397 +++++++++++++----------------------
 1 file changed, 142 insertions(+), 255 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 5eef649..021dcf6 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -33,6 +33,7 @@
 #include <linux/suspend.h>
 #include <linux/acpi.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/mfd/core.h>
 
 #include <asm/intel_pmc_ipc.h>
 
@@ -87,6 +88,7 @@
 #define PLAT_RESOURCE_ISP_IFACE_INDEX	5
 #define PLAT_RESOURCE_GTD_DATA_INDEX	6
 #define PLAT_RESOURCE_GTD_IFACE_INDEX	7
+#define PLAT_RESOURCE_MEM_MAX_INDEX	8
 #define PLAT_RESOURCE_ACPI_IO_INDEX	0
 
 /*
@@ -105,8 +107,6 @@
 #define TELEM_SSRAM_SIZE		240
 #define TELEM_PMC_SSRAM_OFFSET		0x1B00
 #define TELEM_PUNIT_SSRAM_OFFSET	0x1A00
-#define TCO_PMC_OFFSET			0x8
-#define TCO_PMC_SIZE			0x4
 
 /* PMC register bit definitions */
 
@@ -123,25 +123,12 @@ static struct intel_pmc_ipc_dev {
 	int cmd;
 	struct completion cmd_complete;
 
-	/* The following PMC BARs share the same ACPI device with the IPC */
-	resource_size_t acpi_io_base;
-	int acpi_io_size;
-	struct platform_device *tco_dev;
-
 	/* gcr */
 	void __iomem *gcr_mem_base;
 	bool has_gcr_regs;
 
-	/* punit */
-	struct platform_device *punit_dev;
-
 	/* Telemetry */
-	resource_size_t telem_pmc_ssram_base;
-	resource_size_t telem_punit_ssram_base;
-	int telem_pmc_ssram_size;
-	int telem_punit_ssram_size;
 	u8 telem_res_inval;
-	struct platform_device *telemetry_dev;
 } ipcdev;
 
 static char *ipc_err_sources[] = {
@@ -589,44 +576,6 @@ static const struct attribute_group intel_ipc_group = {
 	.attrs = intel_ipc_attrs,
 };
 
-static struct resource punit_res_array[] = {
-	/* Punit BIOS */
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	/* Punit ISP */
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	/* Punit GTD */
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-#define TCO_RESOURCE_ACPI_IO		0
-#define TCO_RESOURCE_SMI_EN_IO		1
-#define TCO_RESOURCE_GCR_MEM		2
-static struct resource tco_res[] = {
-	/* ACPI - TCO */
-	{
-		.flags = IORESOURCE_IO,
-	},
-	/* ACPI - SMI */
-	{
-		.flags = IORESOURCE_IO,
-	},
-};
-
 static struct itco_wdt_platform_data tco_info = {
 	.name = "Apollo Lake SoC",
 	.version = 5,
@@ -634,237 +583,186 @@ static struct itco_wdt_platform_data tco_info = {
 	.update_no_reboot_bit = update_no_reboot_bit,
 };
 
-#define TELEMETRY_RESOURCE_PUNIT_SSRAM	0
-#define TELEMETRY_RESOURCE_PMC_SSRAM	1
-static struct resource telemetry_res[] = {
-	/*Telemetry*/
-	{
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-static int ipc_create_punit_device(void)
+static int ipc_create_punit_device(struct platform_device *pdev)
 {
-	struct platform_device *pdev;
-	const struct platform_device_info pdevinfo = {
-		.parent = ipcdev.dev,
-		.name = PUNIT_DEVICE_NAME,
-		.id = -1,
-		.res = punit_res_array,
-		.num_res = ARRAY_SIZE(punit_res_array),
+	struct resource *res;
+	static struct resource punit_res[PLAT_RESOURCE_MEM_MAX_INDEX];
+	static struct mfd_cell punit_cell;
+	int mindex, pindex = 0;
+
+	for (mindex = 0; mindex <= PLAT_RESOURCE_MEM_MAX_INDEX; mindex++) {
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, mindex);
+
+		switch (mindex) {
+		/* Get PUNIT resources */
+		case PLAT_RESOURCE_BIOS_DATA_INDEX:
+		case PLAT_RESOURCE_BIOS_IFACE_INDEX:
+			/* BIOS resources are required, so return error if not
+			 * available */
+			if (!res) {
+				dev_err(&pdev->dev,
+					"Failed to get punit mem resource %d\n",
+					pindex);
+				return -ENXIO;
+			}
+		case PLAT_RESOURCE_ISP_DATA_INDEX:
+		case PLAT_RESOURCE_ISP_IFACE_INDEX:
+		case PLAT_RESOURCE_GTD_DATA_INDEX:
+		case PLAT_RESOURCE_GTD_IFACE_INDEX:
+			/* if not valid resource, skip the rest of steps */
+			if (!res) {
+				pindex++;
+				continue;
+			}
+			memcpy(&punit_res[pindex], res, sizeof(*res));
+			punit_res[pindex].flags = IORESOURCE_MEM;
+			dev_info(&pdev->dev, "PUNIT memory res: %pR\n",
+					&punit_res[pindex]);
+			pindex++;
+			break;
 		};
+	}
 
-	pdev = platform_device_register_full(&pdevinfo);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	ipcdev.punit_dev = pdev;
+	/* Create PUNIT IPC MFD cell */
+	punit_cell.name = PUNIT_DEVICE_NAME;
+	punit_cell.id = -1;
+	punit_cell.num_resources = ARRAY_SIZE(punit_res);
+	punit_cell.resources = punit_res;
+	punit_cell.ignore_resource_conflicts = 1;
 
-	return 0;
+	return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
+			&punit_cell, 1, NULL, 0, NULL);
 }
 
-static int ipc_create_tco_device(void)
+static int ipc_create_wdt_device(struct platform_device *pdev)
 {
-	struct platform_device *pdev;
+	static struct resource wdt_ipc_res[2];
 	struct resource *res;
-	const struct platform_device_info pdevinfo = {
-		.parent = ipcdev.dev,
-		.name = TCO_DEVICE_NAME,
-		.id = -1,
-		.res = tco_res,
-		.num_res = ARRAY_SIZE(tco_res),
-		.data = &tco_info,
-		.size_data = sizeof(tco_info),
-		};
-
-	res = tco_res + TCO_RESOURCE_ACPI_IO;
-	res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET;
-	res->end = res->start + TCO_REGS_SIZE - 1;
+	static struct mfd_cell wdt_cell;
 
-	res = tco_res + TCO_RESOURCE_SMI_EN_IO;
-	res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET;
-	res->end = res->start + SMI_EN_SIZE - 1;
+	/* If we have ACPI based watchdog use that instead, othewise create
+	 * a MFD cell for iTCO watchdog*/
+	if (acpi_has_watchdog())
+		return 0;
 
-	pdev = platform_device_register_full(&pdevinfo);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	ipcdev.tco_dev = pdev;
+	/* Get iTCO watchdog resources */
+	res = platform_get_resource(pdev, IORESOURCE_IO,
+				    PLAT_RESOURCE_ACPI_IO_INDEX);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get wdt resource\n");
+		return -ENXIO;
+	}
 
-	return 0;
+	wdt_ipc_res[0].start = res->start + TCO_BASE_OFFSET;
+	wdt_ipc_res[0].end = res->start + TCO_BASE_OFFSET +
+		TCO_REGS_SIZE - 1;
+	wdt_ipc_res[0].flags = IORESOURCE_IO;
+	wdt_ipc_res[1].start = res->start + SMI_EN_OFFSET;
+	wdt_ipc_res[1].end = res->start +
+		SMI_EN_OFFSET + SMI_EN_SIZE - 1;
+	wdt_ipc_res[1].flags = IORESOURCE_IO;
+
+	dev_info(&pdev->dev, "watchdog res 0: %pR\n",
+			&wdt_ipc_res[0]);
+	dev_info(&pdev->dev, "watchdog res 1: %pR\n",
+			&wdt_ipc_res[1]);
+
+	wdt_cell.name = TCO_DEVICE_NAME;
+	wdt_cell.id = -1;
+	wdt_cell.platform_data = &tco_info;
+	wdt_cell.pdata_size = sizeof(tco_info);
+	wdt_cell.num_resources = ARRAY_SIZE(wdt_ipc_res);
+	wdt_cell.resources = wdt_ipc_res;
+	wdt_cell.ignore_resource_conflicts = 1;
+
+	return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
+			&wdt_cell, 1, NULL, 0, NULL);
 }
 
-static int ipc_create_telemetry_device(void)
+static int ipc_create_telemetry_device(struct platform_device *pdev)
 {
-	struct platform_device *pdev;
+	static struct resource telemetry_ipc_res[2];
 	struct resource *res;
-	const struct platform_device_info pdevinfo = {
-		.parent = ipcdev.dev,
-		.name = TELEMETRY_DEVICE_NAME,
-		.id = -1,
-		.res = telemetry_res,
-		.num_res = ARRAY_SIZE(telemetry_res),
-		};
-
-	res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM;
-	res->start = ipcdev.telem_punit_ssram_base;
-	res->end = res->start + ipcdev.telem_punit_ssram_size - 1;
+	static struct mfd_cell telemetry_cell;
 
-	res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM;
-	res->start = ipcdev.telem_pmc_ssram_base;
-	res->end = res->start + ipcdev.telem_pmc_ssram_size - 1;
-
-	pdev = platform_device_register_full(&pdevinfo);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	ipcdev.telemetry_dev = pdev;
+	/* Get telemetry resources */
+	res = platform_get_resource(pdev, IORESOURCE_MEM,
+				    PLAT_RESOURCE_TELEM_SSRAM_INDEX);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get telemetry resource\n");
+		return -ENXIO;
+	}
 
-	return 0;
+	telemetry_ipc_res[0].start = res->start +
+		TELEM_PUNIT_SSRAM_OFFSET;
+	telemetry_ipc_res[0].end = res->start +
+		TELEM_PUNIT_SSRAM_OFFSET + TELEM_SSRAM_SIZE - 1;
+	telemetry_ipc_res[0].flags = IORESOURCE_MEM;
+	telemetry_ipc_res[1].start = res->start + TELEM_PMC_SSRAM_OFFSET;
+	telemetry_ipc_res[1].end = res->start +
+		TELEM_PMC_SSRAM_OFFSET + TELEM_SSRAM_SIZE - 1;
+	telemetry_ipc_res[1].flags = IORESOURCE_MEM;
+
+	dev_info(&pdev->dev, "Telemetry res 0: %pR\n",
+			&telemetry_ipc_res[0]);
+	dev_info(&pdev->dev, "Telemetry res 1: %pR\n",
+			&telemetry_ipc_res[1]);
+
+	telemetry_cell.name = TELEMETRY_DEVICE_NAME;
+	telemetry_cell.id = -1;
+	telemetry_cell.num_resources = ARRAY_SIZE(telemetry_ipc_res);
+	telemetry_cell.resources = telemetry_ipc_res;
+	telemetry_cell.ignore_resource_conflicts = 1;
+
+	return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
+			&telemetry_cell, 1, NULL, 0, NULL);
 }
 
-static int ipc_create_pmc_devices(void)
+static int ipc_create_pmc_devices(struct platform_device *pdev)
 {
 	int ret;
 
-	/* If we have ACPI based watchdog use that instead */
-	if (!acpi_has_watchdog()) {
-		ret = ipc_create_tco_device();
-		if (ret) {
-			dev_err(ipcdev.dev, "Failed to add tco platform device\n");
-			return ret;
-		}
-	}
+	ret = ipc_create_punit_device(pdev);
+	if (ret < 0)
+		return ret;
 
-	ret = ipc_create_punit_device();
-	if (ret) {
-		dev_err(ipcdev.dev, "Failed to add punit platform device\n");
-		platform_device_unregister(ipcdev.tco_dev);
-	}
+	ret = ipc_create_wdt_device(pdev);
+	if (ret < 0)
+		return ret;
 
-	if (!ipcdev.telem_res_inval) {
-		ret = ipc_create_telemetry_device();
-		if (ret)
-			dev_warn(ipcdev.dev,
-				"Failed to add telemetry platform device\n");
-	}
+	ret = ipc_create_telemetry_device(pdev);
+	if (ret < 0)
+		return ret;
 
-	return ret;
+	return 0;
 }
 
 static int ipc_plat_get_res(struct platform_device *pdev)
 {
-	struct resource *res, *punit_res;
+	struct resource *res;
 	void __iomem *addr;
-	int size;
-
-	res = platform_get_resource(pdev, IORESOURCE_IO,
-				    PLAT_RESOURCE_ACPI_IO_INDEX);
-	if (!res) {
-		dev_err(&pdev->dev, "Failed to get io resource\n");
-		return -ENXIO;
-	}
-	size = resource_size(res);
-	ipcdev.acpi_io_base = res->start;
-	ipcdev.acpi_io_size = size;
-	dev_info(&pdev->dev, "io res: %pR\n", res);
-
-	punit_res = punit_res_array;
-	/* This is index 0 to cover BIOS data register */
-	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_BIOS_DATA_INDEX);
-	if (!res) {
-		dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n");
-		return -ENXIO;
-	}
-	*punit_res = *res;
-	dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res);
 
-	/* This is index 1 to cover BIOS interface register */
+	/* Get IPC resources */
 	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_BIOS_IFACE_INDEX);
+			PLAT_RESOURCE_IPC_INDEX);
 	if (!res) {
-		dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n");
+		dev_err(&pdev->dev, "Failed to get IPC resources\n");
 		return -ENXIO;
 	}
-	*++punit_res = *res;
-	dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res);
-
-	/* This is index 2 to cover ISP data register, optional */
-	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_ISP_DATA_INDEX);
-	++punit_res;
-	if (res) {
-		*punit_res = *res;
-		dev_info(&pdev->dev, "punit ISP data res: %pR\n", res);
-	}
-
-	/* This is index 3 to cover ISP interface register, optional */
-	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_ISP_IFACE_INDEX);
-	++punit_res;
-	if (res) {
-		*punit_res = *res;
-		dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res);
-	}
 
-	/* This is index 4 to cover GTD data register, optional */
-	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_GTD_DATA_INDEX);
-	++punit_res;
-	if (res) {
-		*punit_res = *res;
-		dev_info(&pdev->dev, "punit GTD data res: %pR\n", res);
-	}
-
-	/* This is index 5 to cover GTD interface register, optional */
-	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_GTD_IFACE_INDEX);
-	++punit_res;
-	if (res) {
-		*punit_res = *res;
-		dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res);
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_IPC_INDEX);
-	if (!res) {
-		dev_err(&pdev->dev, "Failed to get ipc resource\n");
-		return -ENXIO;
-	}
 	res->end = (res->start + PLAT_RESOURCE_IPC_SIZE +
-		    PLAT_RESOURCE_GCR_SIZE - 1);
+			PLAT_RESOURCE_GCR_SIZE - 1);
 
 	addr = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(addr)) {
-		dev_err(&pdev->dev,
-			"PMC I/O memory remapping failed\n");
-		return PTR_ERR(addr);
+		dev_err(&pdev->dev, "PMC I/O memory remapping failed\n");
+			return PTR_ERR(addr);
 	}
 
 	ipcdev.ipc_base = addr;
-
 	ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
-	dev_info(&pdev->dev, "ipc res: %pR\n", res);
-
-	ipcdev.telem_res_inval = 0;
-	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_TELEM_SSRAM_INDEX);
-	if (!res) {
-		dev_err(&pdev->dev, "Failed to get telemetry ssram resource\n");
-		ipcdev.telem_res_inval = 1;
-	} else {
-		ipcdev.telem_punit_ssram_base = res->start +
-						TELEM_PUNIT_SSRAM_OFFSET;
-		ipcdev.telem_punit_ssram_size = TELEM_SSRAM_SIZE;
-		ipcdev.telem_pmc_ssram_base = res->start +
-						TELEM_PMC_SSRAM_OFFSET;
-		ipcdev.telem_pmc_ssram_size = TELEM_SSRAM_SIZE;
-		dev_info(&pdev->dev, "telemetry ssram res: %pR\n", res);
-	}
+	dev_info(&pdev->dev, "PMC IPC resource %pR\n", res);
 
 	return 0;
 }
@@ -919,7 +817,7 @@ static int ipc_plat_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = ipc_create_pmc_devices();
+	ret = ipc_create_pmc_devices(pdev);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create pmc devices\n");
 		return ret;
@@ -928,37 +826,26 @@ static int ipc_plat_probe(struct platform_device *pdev)
 	if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND,
 			     "intel_pmc_ipc", &ipcdev)) {
 		dev_err(&pdev->dev, "Failed to request irq\n");
-		ret = -EBUSY;
-		goto unregister_devices;
+		return -EBUSY;
 	}
 
 	ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
 			ret);
-		goto unregister_devices;
+		return ret;
 	}
 
 	ipcdev.has_gcr_regs = true;
 
 	return 0;
-
-unregister_devices:
-	platform_device_unregister(ipcdev.tco_dev);
-	platform_device_unregister(ipcdev.punit_dev);
-	platform_device_unregister(ipcdev.telemetry_dev);
-
-	return ret;
 }
 
 static int ipc_plat_remove(struct platform_device *pdev)
 {
 	sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
-	devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
-	platform_device_unregister(ipcdev.tco_dev);
-	platform_device_unregister(ipcdev.punit_dev);
-	platform_device_unregister(ipcdev.telemetry_dev);
 	ipcdev.dev = NULL;
+
 	return 0;
 }
 
-- 
2.7.4

^ permalink raw reply related

* [RFC v3 1/7] platform/x86: intel_pmc_ipc: Use devm_* calls in driver probe function
From: sathyanarayanan.kuppuswamy @ 2017-09-05  5:37 UTC (permalink / raw)
  To: a.zummo, x86, wim, mingo, alexandre.belloni, qipeng.zha, hpa,
	dvhart, tglx, lee.jones, andy, souvik.k.chakravarty
  Cc: linux-rtc, linux-watchdog, linux-kernel, platform-driver-x86,
	sathyaosid, Kuppuswamy Sathyanarayanan
In-Reply-To: <cover.1504588701.git.sathyanarayanan.kuppuswamy@linux.intel.com>

From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>

This patch cleans up unnecessary free/alloc calls in ipc_plat_probe(),
ipc_pci_probe() and ipc_plat_get_res() functions by using devm_*
calls.

This patch also adds proper error handling for failure cases in
ipc_pci_probe() function.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
 drivers/platform/x86/intel_pmc_ipc.c | 104 ++++++++++++-----------------------
 1 file changed, 34 insertions(+), 70 deletions(-)

Changes since v2:
 * Used pcim_* device managed functions.

Changes since v1:
 * Merged devm_* related changes into a single function.
 * Instead of removing free_irq, use devm_free_irq function.

diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index bb792a5..5eef649 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -480,52 +480,39 @@ static irqreturn_t ioc(int irq, void *dev_id)
 
 static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-	resource_size_t pci_resource;
 	int ret;
-	int len;
+	struct intel_pmc_ipc_dev *pmc = &ipcdev;
 
-	ipcdev.dev = &pci_dev_get(pdev)->dev;
-	ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ;
+	/* Only one PMC is supported */
+	if (pmc->dev)
+		return -EBUSY;
 
-	ret = pci_enable_device(pdev);
+	pmc->irq_mode = IPC_TRIGGER_MODE_IRQ;
+
+	ret = pcim_enable_device(pdev);
 	if (ret)
 		return ret;
 
-	ret = pci_request_regions(pdev, "intel_pmc_ipc");
+	ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
 	if (ret)
 		return ret;
 
-	pci_resource = pci_resource_start(pdev, 0);
-	len = pci_resource_len(pdev, 0);
-	if (!pci_resource || !len) {
-		dev_err(&pdev->dev, "Failed to get resource\n");
-		return -ENOMEM;
-	}
+	init_completion(&pmc->cmd_complete);
 
-	init_completion(&ipcdev.cmd_complete);
+	pmc->ipc_base =  pcim_iomap_table(pdev)[0];
 
-	if (request_irq(pdev->irq, ioc, 0, "intel_pmc_ipc", &ipcdev)) {
+	ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc",
+				pmc);
+	if (ret) {
 		dev_err(&pdev->dev, "Failed to request irq\n");
-		return -EBUSY;
+		return ret;
 	}
 
-	ipcdev.ipc_base = ioremap_nocache(pci_resource, len);
-	if (!ipcdev.ipc_base) {
-		dev_err(&pdev->dev, "Failed to ioremap ipc base\n");
-		free_irq(pdev->irq, &ipcdev);
-		ret = -ENOMEM;
-	}
+	pmc->dev = &pdev->dev;
 
-	return ret;
-}
+	pci_set_drvdata(pdev, pmc);
 
-static void ipc_pci_remove(struct pci_dev *pdev)
-{
-	free_irq(pdev->irq, &ipcdev);
-	pci_release_regions(pdev);
-	pci_dev_put(pdev);
-	iounmap(ipcdev.ipc_base);
-	ipcdev.dev = NULL;
+	return 0;
 }
 
 static const struct pci_device_id ipc_pci_ids[] = {
@@ -540,7 +527,6 @@ static struct pci_driver ipc_pci_driver = {
 	.name = "intel_pmc_ipc",
 	.id_table = ipc_pci_ids,
 	.probe = ipc_pci_probe,
-	.remove = ipc_pci_remove,
 };
 
 static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
@@ -849,18 +835,16 @@ static int ipc_plat_get_res(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Failed to get ipc resource\n");
 		return -ENXIO;
 	}
-	size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE;
+	res->end = (res->start + PLAT_RESOURCE_IPC_SIZE +
+		    PLAT_RESOURCE_GCR_SIZE - 1);
 
-	if (!request_mem_region(res->start, size, pdev->name)) {
-		dev_err(&pdev->dev, "Failed to request ipc resource\n");
-		return -EBUSY;
-	}
-	addr = ioremap_nocache(res->start, size);
-	if (!addr) {
-		dev_err(&pdev->dev, "I/O memory remapping failed\n");
-		release_mem_region(res->start, size);
-		return -ENOMEM;
+	addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(addr)) {
+		dev_err(&pdev->dev,
+			"PMC I/O memory remapping failed\n");
+		return PTR_ERR(addr);
 	}
+
 	ipcdev.ipc_base = addr;
 
 	ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
@@ -917,7 +901,6 @@ MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids);
 
 static int ipc_plat_probe(struct platform_device *pdev)
 {
-	struct resource *res;
 	int ret;
 
 	ipcdev.dev = &pdev->dev;
@@ -939,61 +922,42 @@ static int ipc_plat_probe(struct platform_device *pdev)
 	ret = ipc_create_pmc_devices();
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create pmc devices\n");
-		goto err_device;
+		return ret;
 	}
 
-	if (request_irq(ipcdev.irq, ioc, IRQF_NO_SUSPEND,
-			"intel_pmc_ipc", &ipcdev)) {
+	if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND,
+			     "intel_pmc_ipc", &ipcdev)) {
 		dev_err(&pdev->dev, "Failed to request irq\n");
 		ret = -EBUSY;
-		goto err_irq;
+		goto unregister_devices;
 	}
 
 	ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
 			ret);
-		goto err_sys;
+		goto unregister_devices;
 	}
 
 	ipcdev.has_gcr_regs = true;
 
 	return 0;
-err_sys:
-	free_irq(ipcdev.irq, &ipcdev);
-err_irq:
+
+unregister_devices:
 	platform_device_unregister(ipcdev.tco_dev);
 	platform_device_unregister(ipcdev.punit_dev);
 	platform_device_unregister(ipcdev.telemetry_dev);
-err_device:
-	iounmap(ipcdev.ipc_base);
-	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_IPC_INDEX);
-	if (res) {
-		release_mem_region(res->start,
-				   PLAT_RESOURCE_IPC_SIZE +
-				   PLAT_RESOURCE_GCR_SIZE);
-	}
+
 	return ret;
 }
 
 static int ipc_plat_remove(struct platform_device *pdev)
 {
-	struct resource *res;
-
 	sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
-	free_irq(ipcdev.irq, &ipcdev);
+	devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
 	platform_device_unregister(ipcdev.tco_dev);
 	platform_device_unregister(ipcdev.punit_dev);
 	platform_device_unregister(ipcdev.telemetry_dev);
-	iounmap(ipcdev.ipc_base);
-	res = platform_get_resource(pdev, IORESOURCE_MEM,
-				    PLAT_RESOURCE_IPC_INDEX);
-	if (res) {
-		release_mem_region(res->start,
-				   PLAT_RESOURCE_IPC_SIZE +
-				   PLAT_RESOURCE_GCR_SIZE);
-	}
 	ipcdev.dev = NULL;
 	return 0;
 }
-- 
2.7.4

^ permalink raw reply related

* [RFC v3 3/7] platform/x86: intel_pmc_ipc: Use regmap calls for GCR updates
From: sathyanarayanan.kuppuswamy @ 2017-09-05  5:37 UTC (permalink / raw)
  To: a.zummo, x86, wim, mingo, alexandre.belloni, qipeng.zha, hpa,
	dvhart, tglx, lee.jones, andy, souvik.k.chakravarty
  Cc: linux-rtc, linux-watchdog, linux-kernel, platform-driver-x86,
	sathyaosid, Kuppuswamy Sathyanarayanan
In-Reply-To: <cover.1504588701.git.sathyanarayanan.kuppuswamy@linux.intel.com>

From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>

Currently, update_no_reboot_bit() function implemented in this driver
uses mutex_lock to protect its register updates. But this function is
called with in atomic context in iTCO_wdt_start() and iTCO_wdt_stop()
functions in iTCO_wdt.c driver, which in turn causes "sleeping into
atomic context" issue. This patch fixes this issue by refactoring the
current GCR read/write/update functions with regmap APIs.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
 drivers/platform/x86/Kconfig         |   1 +
 drivers/platform/x86/intel_pmc_ipc.c | 115 ++++++++++++-----------------------
 2 files changed, 40 insertions(+), 76 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 80b8795..45f4e79 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1054,6 +1054,7 @@ config PVPANIC
 config INTEL_PMC_IPC
 	tristate "Intel PMC IPC Driver"
 	depends on ACPI
+	select REGMAP_MMIO
 	---help---
 	This driver provides support for PMC control on some Intel platforms.
 	The PMC is an ARC processor which defines IPC commands for communication
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index 021dcf6..40a25f8 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -31,9 +31,11 @@
 #include <linux/atomic.h>
 #include <linux/notifier.h>
 #include <linux/suspend.h>
+#include <linux/spinlock.h>
 #include <linux/acpi.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/mfd/core.h>
+#include <linux/regmap.h>
 
 #include <asm/intel_pmc_ipc.h>
 
@@ -125,7 +127,7 @@ static struct intel_pmc_ipc_dev {
 
 	/* gcr */
 	void __iomem *gcr_mem_base;
-	bool has_gcr_regs;
+	struct regmap *gcr_regs;
 
 	/* Telemetry */
 	u8 telem_res_inval;
@@ -150,6 +152,14 @@ static char *ipc_err_sources[] = {
 		"Unsigned kernel",
 };
 
+static struct regmap_config gcr_regmap_config = {
+        .reg_bits = 32,
+        .reg_stride = 4,
+        .val_bits = 32,
+	.fast_io = true,
+	.max_register = PLAT_RESOURCE_GCR_SIZE,
+};
+
 /* Prevent concurrent calls to the PMC */
 static DEFINE_MUTEX(ipclock);
 
@@ -183,21 +193,6 @@ static inline u32 ipc_data_readl(u32 offset)
 	return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
 }
 
-static inline u64 gcr_data_readq(u32 offset)
-{
-	return readq(ipcdev.gcr_mem_base + offset);
-}
-
-static inline int is_gcr_valid(u32 offset)
-{
-	if (!ipcdev.has_gcr_regs)
-		return -EACCES;
-
-	if (offset > PLAT_RESOURCE_GCR_SIZE)
-		return -EINVAL;
-
-	return 0;
-}
 
 /**
  * intel_pmc_gcr_read() - Read PMC GCR register
@@ -210,21 +205,10 @@ static inline int is_gcr_valid(u32 offset)
  */
 int intel_pmc_gcr_read(u32 offset, u32 *data)
 {
-	int ret;
-
-	mutex_lock(&ipclock);
-
-	ret = is_gcr_valid(offset);
-	if (ret < 0) {
-		mutex_unlock(&ipclock);
-		return ret;
-	}
-
-	*data = readl(ipcdev.gcr_mem_base + offset);
-
-	mutex_unlock(&ipclock);
+	if (!ipcdev.gcr_regs)
+		return -EACCES;
 
-	return 0;
+	return regmap_read(ipcdev.gcr_regs, offset, data);
 }
 EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);
 
@@ -240,21 +224,10 @@ EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);
  */
 int intel_pmc_gcr_write(u32 offset, u32 data)
 {
-	int ret;
-
-	mutex_lock(&ipclock);
-
-	ret = is_gcr_valid(offset);
-	if (ret < 0) {
-		mutex_unlock(&ipclock);
-		return ret;
-	}
-
-	writel(data, ipcdev.gcr_mem_base + offset);
-
-	mutex_unlock(&ipclock);
+	if (!ipcdev.gcr_regs)
+		return -EACCES;
 
-	return 0;
+	return regmap_write(ipcdev.gcr_regs, offset, data);
 }
 EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);
 
@@ -271,33 +244,10 @@ EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);
  */
 int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
 {
-	u32 new_val;
-	int ret = 0;
-
-	mutex_lock(&ipclock);
-
-	ret = is_gcr_valid(offset);
-	if (ret < 0)
-		goto gcr_ipc_unlock;
-
-	new_val = readl(ipcdev.gcr_mem_base + offset);
-
-	new_val &= ~mask;
-	new_val |= val & mask;
-
-	writel(new_val, ipcdev.gcr_mem_base + offset);
-
-	new_val = readl(ipcdev.gcr_mem_base + offset);
-
-	/* check whether the bit update is successful */
-	if ((new_val & mask) != (val & mask)) {
-		ret = -EIO;
-		goto gcr_ipc_unlock;
-	}
+	if (!ipcdev.gcr_regs)
+		return -EACCES;
 
-gcr_ipc_unlock:
-	mutex_unlock(&ipclock);
-	return ret;
+	return regmap_update_bits(ipcdev.gcr_regs, offset, mask, val);
 }
 EXPORT_SYMBOL_GPL(intel_pmc_gcr_update);
 
@@ -776,16 +726,24 @@ static int ipc_plat_get_res(struct platform_device *pdev)
 int intel_pmc_s0ix_counter_read(u64 *data)
 {
 	u64 deep, shlw;
+	int ret;
 
-	if (!ipcdev.has_gcr_regs)
+	if (!ipcdev.gcr_regs)
 		return -EACCES;
 
-	deep = gcr_data_readq(PMC_GCR_TELEM_DEEP_S0IX_REG);
-	shlw = gcr_data_readq(PMC_GCR_TELEM_SHLW_S0IX_REG);
+	ret = regmap_bulk_read(ipcdev.gcr_regs, PMC_GCR_TELEM_DEEP_S0IX_REG,
+			&deep, 2);
+	if (ret)
+		return ret;
+
+	ret = regmap_bulk_read(ipcdev.gcr_regs, PMC_GCR_TELEM_SHLW_S0IX_REG,
+			&shlw, 2);
+	if (ret)
+		return ret;
 
 	*data = S0IX_RESIDENCY_IN_USECS(deep, shlw);
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(intel_pmc_s0ix_counter_read);
 
@@ -817,6 +775,13 @@ static int ipc_plat_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+        ipcdev.gcr_regs = devm_regmap_init_mmio_clk(ipcdev.dev, NULL,
+			ipcdev.gcr_mem_base, &gcr_regmap_config);
+        if (IS_ERR(ipcdev.gcr_regs)) {
+                dev_err(ipcdev.dev, "gcr_regs regmap init failed\n");
+                return PTR_ERR(ipcdev.gcr_regs);;
+        }
+
 	ret = ipc_create_pmc_devices(pdev);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to create pmc devices\n");
@@ -836,8 +801,6 @@ static int ipc_plat_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ipcdev.has_gcr_regs = true;
-
 	return 0;
 }
 
-- 
2.7.4

^ permalink raw reply related

* [RFC v3 0/7] PMC/PUNIT IPC driver cleanup
From: sathyanarayanan.kuppuswamy @ 2017-09-05  5:37 UTC (permalink / raw)
  To: a.zummo, x86, wim, mingo, alexandre.belloni, qipeng.zha, hpa,
	dvhart, tglx, lee.jones, andy, souvik.k.chakravarty
  Cc: linux-rtc, linux-watchdog, linux-kernel, platform-driver-x86,
	sathyaosid, Kuppuswamy Sathyanarayanan

From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>

Hi All,

Currently intel_pmc_ipc.c, intel_punit_ipc.c, intel_scu_ipc.c drivers implements the same IPC features.
This code duplication could be avoided if we implement the IPC driver as a generic library and let custom
device drivers use API provided by generic driver. This patchset mainly addresses this issue.

Along with above code duplication issue, This patchset also addresses following issues in intel_pmc_ipc and
intel_punit_ipc drivers. 

1. Intel_pmc_ipc.c driver does not use any resource managed (devm_*) calls.
2. In Intel_pmc_ipc.c driver, dependent devices like PUNIT, Telemetry and iTCO are created manually and uses lot of redundant buffer code.
3. Global variable is used to store the IPC device structure and it is used across all functions in intel_pmc_ipc.c and intel_punit_ipc.c.

More info on Intel IPC device library:
-------------------------------------

A generic Intel IPC class driver has been implemented and all common IPC helper functions has been moved to this driver. It exposes APIs to create IPC device channel, send raw IPC command and simple IPC commands. It also creates device attribute to send IPC command from user space.

API for creating a new IPC channel device is,

struct intel_ipc_dev *devm_intel_ipc_dev_create(struct device *dev, const char *devname, struct intel_ipc_dev_cfg *cfg, struct intel_ipc_dev_ops *ops)

The IPC channel drivers (PUNIT/PMC/SCU) when creating a new device can configure their device params like register mapping, irq, irq-mode, channel type,etc  using intel_ipc_dev_cfg and intel_ipc_dev_ops arguments. After a new IPC channel device is created, IPC users can use the generic APIs to make IPC calls.

For example, after using this new model, IPC call to PMC device will look like,

pmc_ipc_dev = intel_ipc_dev_get(INTEL_PMC_IPC_DEV);
ipc_dev_raw_cmd(pmc_ipc_dev, cmd, PMC_PARAM_LEN, (u32 *)ipc_in, 1, NULL, 0, 0, 0);

I am still testing the driver in different products. But posted it to get some early comments. I also welcome any PMC/PUNIT driver users to check these patches in their product.

Changes since v2:
 * Refactored intel_scu_ipc.c to use generic IPC device APIs.
 * Fixed intel_pmc_ipc.c to use pcim_* device managed functions.

Changes since v1:
 * Merged devm_* changes in pmc_plat_probe and pmc_pci_probe functions into a
   single patch.
 * Addressed Andy's comment about keeping the library generic by not implementing
   the low level reg access calls in intel_ipc_dev.c. This version will start using
   the regmap pointer provided by channel drivers instead of fixed memory map.
 * Removed custom IPC APIs in intel_pmc_ipc.c and intel_punit_ipc.c.
 * Cleaned up IPC driver users to use APIs provided by generic library (intel_ipc_dev.c).

Kuppuswamy Sathyanarayanan (7):
  platform/x86: intel_pmc_ipc: Use devm_* calls in driver probe function
  platform/x86: intel_pmc_ipc: Use MFD framework to create dependent
    devices
  platform/x86: intel_pmc_ipc: Use regmap calls for GCR updates
  platform: x86: Add generic Intel IPC driver
  platform/x86: intel_punit_ipc: Use generic intel ipc device calls
  platform/x86: intel_pmc_ipc: Use generic Intel IPC device calls
  platform/x86: intel_scu_ipc: Use generic Intel IPC device calls

 arch/x86/include/asm/intel_pmc_ipc.h            |  37 +-
 arch/x86/include/asm/intel_punit_ipc.h          | 125 ++--
 arch/x86/include/asm/intel_scu_ipc.h            |  23 +-
 arch/x86/platform/intel-mid/intel-mid.c         |  12 +-
 drivers/mfd/intel_soc_pmic_bxtwc.c              |  18 +-
 drivers/platform/x86/Kconfig                    |  11 +
 drivers/platform/x86/Makefile                   |   1 +
 drivers/platform/x86/intel_ipc_dev.c            | 539 ++++++++++++++
 drivers/platform/x86/intel_pmc_ipc.c            | 948 +++++++++---------------
 drivers/platform/x86/intel_punit_ipc.c          | 297 +++-----
 drivers/platform/x86/intel_scu_ipc.c            | 483 +++++-------
 drivers/platform/x86/intel_telemetry_pltdrv.c   | 210 +++---
 drivers/rtc/rtc-mrst.c                          |  15 +-
 drivers/watchdog/intel-mid_wdt.c                |  12 +-
 drivers/watchdog/intel_scu_watchdog.c           |  17 +-
 include/linux/mfd/intel_soc_pmic.h              |   2 +
 include/linux/platform_data/x86/intel_ipc_dev.h | 187 +++++
 17 files changed, 1617 insertions(+), 1320 deletions(-)
 create mode 100644 drivers/platform/x86/intel_ipc_dev.c
 create mode 100644 include/linux/platform_data/x86/intel_ipc_dev.h

-- 
2.7.4

^ permalink raw reply

* Re: [PATCH 0/5] rtc: ds1307: factor out more stuff from ds1307_probe and improve ds1307_set_time
From: Heiner Kallweit @ 2017-09-05  5:27 UTC (permalink / raw)
  To: Alexandre Belloni; +Cc: linux-rtc
In-Reply-To: <20170826104457.sdeeacwgboeectpw@piout.net>

Am 26.08.2017 um 12:44 schrieb Alexandre Belloni:
> On 26/08/2017 at 12:16:53 +0200, Heiner Kallweit wrote:
>> That's exactly my point. The driver is too big already.
>>
>> The patches so far increase size of the driver a little, only subsequent
>> patches start to reduce it.
>>
>> More things like even exporting clocks work the same on all chips
>> supporting this feature. Just the layout of the alarm registers usually is
>> quite different. Therefore it's my plan to create such a ds1307_lib with all
>> the generic code.
>>
>> If it helps I can provide the full patch set (as far as I came so far) via
>> Github, then you can check whether it's the right direction also from your
>> point of view (w/o having to review each single patch in detail already).
>>
> 
> Yes, please do that.
> 
I rebased the patch set on top of your latest ds1307 changes and published
it here: https://github.com/hkallweit/linux_rtc_ds1307/tree/rtc-ds1307

Most code went into a new rtc-ds1307-lib library in a generic form, the driver
contains mainly chip configuration info now plus chip-specific routines for
reading / setting alarm.
Now it would require very little effort to e.g. make ds3231 a separate driver
because the hwmon code is needed for this chip only.

Regards,
Heiner

>> By the way: This current patch set with the 5 patches I have to change,
>> so there will be a v2. No need for you to spend reviewing effort on it now.
>>
> 
> Ok, thanks.
> 

^ permalink raw reply

* [PATCH v4 2/3] rtc: Add Realtek RTD1295
From: Andreas Färber @ 2017-09-04 22:53 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, Roc He, 蒋丽琴,
	Andreas Färber, Alessandro Zummo, Alexandre Belloni,
	linux-rtc
In-Reply-To: <20170904225324.29138-1-afaerber@suse.de>

Based on QNAP's arch/arm/mach-rtk119x/driver/rtk_rtc_drv.c code and
mach-rtk119x/driver/dc2vo/fpga/include/mis_reg.h register definitions.

The base year 2014 was observed on all of Zidoo X9S, ProBox2 Ava and
Beelink Lake I.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v3 -> v4:
 * Added missing clk_put() (Alexandre)
 
 v2 -> v3:
 * Dropped spinlock (Andrew)
 * Refactored days-in-year helper to avoid rtc_year_days()
 
 v1 -> v2:
 * Dropped open/release in favor of probe/remove (Alexandre)
 * read_time: Reordered register accesses (Alexandre)
 * read_time/set_time: Refactored day calculations to avoid time64_t (Alexandre)
 * read_time: Retry if seconds change (Alexandre)
 * probe: Added missing RTCACR initialization code
 * set_time: Fixed year check (off by 1900)
 * set_time: Fixed new seconds (off by factor two)
 * Cleaned up debug output (Andrew)
 * Added spinlocks around register accesses
 * Added masks for register fields
 
 drivers/rtc/Kconfig       |   8 ++
 drivers/rtc/Makefile      |   1 +
 drivers/rtc/rtc-rtd119x.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 251 insertions(+)
 create mode 100644 drivers/rtc/rtc-rtd119x.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index a76a26e2292a..e0e58f3b1420 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1765,6 +1765,14 @@ config RTC_DRV_CPCAP
 	   Say y here for CPCAP rtc found on some Motorola phones
 	   and tablets such as Droid 4.
 
+config RTC_DRV_RTD119X
+	bool "Realtek RTD129x RTC"
+	depends on ARCH_REALTEK || COMPILE_TEST
+	default ARCH_REALTEK
+	help
+	  If you say yes here, you get support for the RTD1295 SoC
+	  Real Time Clock.
+
 comment "HID Sensor RTC drivers"
 
 config RTC_DRV_HID_SENSOR_TIME
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index d995d49d8218..7230014c92af 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -131,6 +131,7 @@ obj-$(CONFIG_RTC_DRV_RP5C01)	+= rtc-rp5c01.o
 obj-$(CONFIG_RTC_DRV_RS5C313)	+= rtc-rs5c313.o
 obj-$(CONFIG_RTC_DRV_RS5C348)	+= rtc-rs5c348.o
 obj-$(CONFIG_RTC_DRV_RS5C372)	+= rtc-rs5c372.o
+obj-$(CONFIG_RTC_DRV_RTD119X)	+= rtc-rtd119x.o
 obj-$(CONFIG_RTC_DRV_RV3029C2)	+= rtc-rv3029c2.o
 obj-$(CONFIG_RTC_DRV_RV8803)	+= rtc-rv8803.o
 obj-$(CONFIG_RTC_DRV_RX4581)	+= rtc-rx4581.o
diff --git a/drivers/rtc/rtc-rtd119x.c b/drivers/rtc/rtc-rtd119x.c
new file mode 100644
index 000000000000..b3b0b97b98e2
--- /dev/null
+++ b/drivers/rtc/rtc-rtd119x.c
@@ -0,0 +1,242 @@
+/*
+ * Realtek RTD129x RTC
+ *
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/spinlock.h>
+
+#define RTD_RTCSEC		0x00
+#define RTD_RTCMIN		0x04
+#define RTD_RTCHR		0x08
+#define RTD_RTCDATE1		0x0c
+#define RTD_RTCDATE2		0x10
+#define RTD_RTCACR		0x28
+#define RTD_RTCEN		0x2c
+#define RTD_RTCCR		0x30
+
+#define RTD_RTCSEC_RTCSEC_MASK		0x7f
+
+#define RTD_RTCMIN_RTCMIN_MASK		0x3f
+
+#define RTD_RTCHR_RTCHR_MASK		0x1f
+
+#define RTD_RTCDATE1_RTCDATE1_MASK	0xff
+
+#define RTD_RTCDATE2_RTCDATE2_MASK	0x7f
+
+#define RTD_RTCACR_RTCPWR		BIT(7)
+
+#define RTD_RTCEN_RTCEN_MASK		0xff
+
+#define RTD_RTCCR_RTCRST		BIT(6)
+
+struct rtd119x_rtc {
+	void __iomem *base;
+	struct clk *clk;
+	struct rtc_device *rtcdev;
+	unsigned int base_year;
+};
+
+static inline int rtd119x_rtc_days_in_year(int year)
+{
+	return 365 + (is_leap_year(year) ? 1 : 0);
+}
+
+static void rtd119x_rtc_reset(struct device *dev)
+{
+	struct rtd119x_rtc *data = dev_get_drvdata(dev);
+	u32 val;
+
+	val = readl_relaxed(data->base + RTD_RTCCR);
+	val |= RTD_RTCCR_RTCRST;
+	writel_relaxed(val, data->base + RTD_RTCCR);
+
+	val &= ~RTD_RTCCR_RTCRST;
+	writel(val, data->base + RTD_RTCCR);
+}
+
+static void rtd119x_rtc_set_enabled(struct device *dev, bool enable)
+{
+	struct rtd119x_rtc *data = dev_get_drvdata(dev);
+	u32 val;
+
+	val = readl_relaxed(data->base + RTD_RTCEN);
+	if (enable) {
+		if ((val & RTD_RTCEN_RTCEN_MASK) == 0x5a)
+			return;
+		writel_relaxed(0x5a, data->base + RTD_RTCEN);
+	} else {
+		writel_relaxed(0, data->base + RTD_RTCEN);
+	}
+}
+
+static int rtd119x_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rtd119x_rtc *data = dev_get_drvdata(dev);
+	s32 day;
+	u32 sec;
+	unsigned int year;
+	int tries = 0;
+
+	while (true) {
+		tm->tm_sec = (readl_relaxed(data->base + RTD_RTCSEC) & RTD_RTCSEC_RTCSEC_MASK) >> 1;
+		tm->tm_min  = readl_relaxed(data->base + RTD_RTCMIN) & RTD_RTCMIN_RTCMIN_MASK;
+		tm->tm_hour = readl_relaxed(data->base + RTD_RTCHR) & RTD_RTCHR_RTCHR_MASK;
+		day  =  readl_relaxed(data->base + RTD_RTCDATE1) & RTD_RTCDATE1_RTCDATE1_MASK;
+		day |= (readl_relaxed(data->base + RTD_RTCDATE2) & RTD_RTCDATE2_RTCDATE2_MASK) << 8;
+		sec  = (readl_relaxed(data->base + RTD_RTCSEC) & RTD_RTCSEC_RTCSEC_MASK) >> 1;
+		tries++;
+
+		if (sec == tm->tm_sec)
+			break;
+
+		if (tries >= 3)
+			return -EINVAL;
+	}
+	if (tries > 1)
+		dev_dbg(dev, "%s: needed %i tries\n", __func__, tries);
+
+	year = data->base_year;
+	while (day >= rtd119x_rtc_days_in_year(year)) {
+		day -= rtd119x_rtc_days_in_year(year);
+		year++;
+	}
+	tm->tm_year = year - 1900;
+	tm->tm_yday = day;
+
+	tm->tm_mon = 0;
+	while (day >= rtc_month_days(tm->tm_mon, year)) {
+		day -= rtc_month_days(tm->tm_mon, year);
+		tm->tm_mon++;
+	}
+	tm->tm_mday = day + 1;
+
+	return 0;
+}
+
+static int rtd119x_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rtd119x_rtc *data = dev_get_drvdata(dev);
+	unsigned int day;
+	int i;
+
+	if (1900 + tm->tm_year < data->base_year)
+		return -EINVAL;
+
+	day = 0;
+	for (i = data->base_year; i < 1900 + tm->tm_year; i++)
+		day += rtd119x_rtc_days_in_year(i);
+
+	day += tm->tm_yday;
+	if (day > 0x7fff)
+		return -EINVAL;
+
+	rtd119x_rtc_set_enabled(dev, false);
+
+	writel_relaxed((tm->tm_sec << 1) & RTD_RTCSEC_RTCSEC_MASK, data->base + RTD_RTCSEC);
+	writel_relaxed(tm->tm_min & RTD_RTCMIN_RTCMIN_MASK, data->base + RTD_RTCMIN);
+	writel_relaxed(tm->tm_hour & RTD_RTCHR_RTCHR_MASK, data->base + RTD_RTCHR);
+	writel_relaxed(day & RTD_RTCDATE1_RTCDATE1_MASK, data->base + RTD_RTCDATE1);
+	writel_relaxed((day >> 8) & RTD_RTCDATE2_RTCDATE2_MASK, data->base + RTD_RTCDATE2);
+
+	rtd119x_rtc_set_enabled(dev, true);
+
+	return 0;
+}
+
+static const struct rtc_class_ops rtd119x_rtc_ops = {
+	.read_time	= rtd119x_rtc_read_time,
+	.set_time	= rtd119x_rtc_set_time,
+};
+
+static const struct of_device_id rtd119x_rtc_dt_ids[] = {
+	 { .compatible = "realtek,rtd1295-rtc" },
+	 { }
+};
+
+static int rtd119x_rtc_probe(struct platform_device *pdev)
+{
+	struct rtd119x_rtc *data;
+	struct resource *res;
+	u32 val;
+	int ret;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, data);
+	data->base_year = 2014;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	data->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(data->base))
+		return PTR_ERR(data->base);
+
+	data->clk = of_clk_get(pdev->dev.of_node, 0);
+	if (IS_ERR(data->clk))
+		return PTR_ERR(data->clk);
+
+	ret = clk_prepare_enable(data->clk);
+	if (ret) {
+		clk_put(data->clk);
+		return ret;
+	}
+
+	val = readl_relaxed(data->base + RTD_RTCACR);
+	if (!(val & RTD_RTCACR_RTCPWR)) {
+		writel_relaxed(RTD_RTCACR_RTCPWR, data->base + RTD_RTCACR);
+
+		rtd119x_rtc_reset(&pdev->dev);
+
+		writel_relaxed(0, data->base + RTD_RTCMIN);
+		writel_relaxed(0, data->base + RTD_RTCHR);
+		writel_relaxed(0, data->base + RTD_RTCDATE1);
+		writel_relaxed(0, data->base + RTD_RTCDATE2);
+	}
+
+	rtd119x_rtc_set_enabled(&pdev->dev, true);
+
+	data->rtcdev = devm_rtc_device_register(&pdev->dev, "rtc",
+				&rtd119x_rtc_ops, THIS_MODULE);
+	if (IS_ERR(data->rtcdev)) {
+		dev_err(&pdev->dev, "failed to register rtc device");
+		clk_disable_unprepare(data->clk);
+		clk_put(data->clk);
+		return PTR_ERR(data->rtcdev);
+	}
+
+	return 0;
+}
+
+static int rtd119x_rtc_remove(struct platform_device *pdev)
+{
+	struct rtd119x_rtc *data = platform_get_drvdata(pdev);
+
+	rtd119x_rtc_set_enabled(&pdev->dev, false);
+
+	clk_disable_unprepare(data->clk);
+	clk_put(data->clk);
+
+	return 0;
+}
+
+static struct platform_driver rtd119x_rtc_driver = {
+	.probe = rtd119x_rtc_probe,
+	.remove = rtd119x_rtc_remove,
+	.driver = {
+		.name = "rtd1295-rtc",
+		.of_match_table	= rtd119x_rtc_dt_ids,
+	},
+};
+builtin_platform_driver(rtd119x_rtc_driver);
-- 
2.13.5

^ permalink raw reply related

* [PATCH v4 1/3] dt-bindings: rtc: Add Realtek RTD1295
From: Andreas Färber @ 2017-09-04 22:53 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, Roc He, 蒋丽琴,
	Andreas Färber, Alessandro Zummo, Alexandre Belloni,
	Rob Herring, Mark Rutland, linux-rtc, devicetree
In-Reply-To: <20170904225324.29138-1-afaerber@suse.de>

Add a binding for the RTC on the Realtek RTD119x/RTD129x SoC families.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v1 -> v2 -> v3 -> v4: Unchanged
 
 .../devicetree/bindings/rtc/realtek,rtd119x.txt          | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt

diff --git a/Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt b/Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt
new file mode 100644
index 000000000000..bbf1ccb5df31
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt
@@ -0,0 +1,16 @@
+Realtek RTD129x Real-Time Clock
+===============================
+
+Required properties:
+- compatible :  Should be "realtek,rtd1295-rtc"
+- reg        :  Specifies the physical base address and size
+- clocks     :  Specifies the clock gate
+
+
+Example:
+
+	rtc@9801b600 {
+		compatible = "realtek,rtd1295-clk";
+		reg = <0x9801b600 0x100>;
+		clocks = <&clkc RTD1295_CLK_EN_MISC_RTC>;
+	};
-- 
2.13.5

^ permalink raw reply related

* [PATCH v4 0/3] arm64: Realtek RTD1295 RTC
From: Andreas Färber @ 2017-09-04 22:53 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, Roc He, 蒋丽琴,
	Andreas Färber, Alessandro Zummo, Alexandre Belloni,
	linux-rtc, devicetree, Andrew Lunn

Hello,

This series adds the RTC for the Realtek RTD1295 SoC.
Based on my RTD1295 clk series.

There being no public source code for RTD1295, the implementation is based on
register offsets seen in the vendor DT, as well as older mach-rtk119x code
published by QNAP.

v4 adds a missing clk_put().

The DT node depends on the clk series for clock index and header.

More experimental patches at:
https://github.com/afaerber/linux/commits/rtd1295-next

Have a lot of fun!

Cheers,
Andreas

v3 -> v4:
* Added clk_put() (Alexandre)

v2 -> v3:
* Dropped spinlock (Andrew)
* Improved year_days vs. days_in_year readability

v1 -> v2:
* Updated rtc driver to no longer use open/release (Alexandre)
* Cleaned up debug output (Andrew)
* Avoided COMPILE_TEST division errors (kbuild)
* Various cleanups and extensions

Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: linux-rtc@vger.kernel.org
Cc: Roc He <hepeng@zidoo.tv>
Cc: 蒋丽琴 <jiang.liqin@geniatech.com>
Cc: devicetree@vger.kernel.org
Cc: Andrew Lunn <andrew@lunn.ch>

Andreas Färber (3):
  dt-bindings: rtc: Add Realtek RTD1295
  rtc: Add Realtek RTD1295
  arm64: dts: realtek: Add RTD1295 RTC node

 .../devicetree/bindings/rtc/realtek,rtd119x.txt    |  16 ++
 arch/arm64/boot/dts/realtek/rtd1295.dtsi           |   6 +
 drivers/rtc/Kconfig                                |   8 +
 drivers/rtc/Makefile                               |   1 +
 drivers/rtc/rtc-rtd119x.c                          | 242 +++++++++++++++++++++
 5 files changed, 273 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt
 create mode 100644 drivers/rtc/rtc-rtd119x.c

-- 
2.13.5

^ permalink raw reply

* [PATCH 6/7] rtc: ds1307: fix braces
From: Alexandre Belloni @ 2017-09-04 20:46 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Heiner Kallweit, Alexandre Belloni
In-Reply-To: <20170904204608.7090-1-alexandre.belloni@free-electrons.com>

Fix unnecessary or unbalanced braces.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-ds1307.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index bac0f9ec9351..9df50db228c6 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1667,9 +1667,8 @@ static int ds1307_probe(struct i2c_client *client,
 	}
 
 	ds1307->rtc = devm_rtc_allocate_device(ds1307->dev);
-	if (IS_ERR(ds1307->rtc)) {
+	if (IS_ERR(ds1307->rtc))
 		return PTR_ERR(ds1307->rtc);
-	}
 
 	if (ds1307_can_wakeup_device && !want_irq) {
 		dev_info(ds1307->dev,
@@ -1688,8 +1687,9 @@ static int ds1307_probe(struct i2c_client *client,
 			device_set_wakeup_capable(ds1307->dev, false);
 			clear_bit(HAS_ALARM, &ds1307->flags);
 			dev_err(ds1307->dev, "unable to request IRQ!\n");
-		} else
+		} else {
 			dev_dbg(ds1307->dev, "got IRQ %d\n", client->irq);
+		}
 	}
 
 	if (chip->nvram_size) {
-- 
2.14.1

^ permalink raw reply related

* [PATCH 7/7] rtc: ds1307: use octal permissions
From: Alexandre Belloni @ 2017-09-04 20:46 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Heiner Kallweit, Alexandre Belloni
In-Reply-To: <20170904204608.7090-1-alexandre.belloni@free-electrons.com>

Octal permissions are preferred over symbolic permissions.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-ds1307.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 9df50db228c6..9d680d36afc0 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1051,7 +1051,7 @@ static ssize_t ds3231_hwmon_show_temp(struct device *dev,
 
 	return sprintf(buf, "%d\n", temp);
 }
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ds3231_hwmon_show_temp,
+static SENSOR_DEVICE_ATTR(temp1_input, 0444, ds3231_hwmon_show_temp,
 			  NULL, 0);
 
 static struct attribute *ds3231_hwmon_attrs[] = {
-- 
2.14.1

^ permalink raw reply related

* [PATCH 1/7] rtc: ds1307: remove regs member
From: Alexandre Belloni @ 2017-09-04 20:46 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Heiner Kallweit, Alexandre Belloni

ds1307->regs is never used before being read or initialized locally. There
is no point in keeping a copy in memory.

Also limit the size of the read buffer to what is really used, rename buf
to regs for consistency and use sizeof() where possible.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-ds1307.c | 207 ++++++++++++++++++++++++-----------------------
 1 file changed, 107 insertions(+), 100 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 6038c49ed68a..8de1d7116461 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -116,7 +116,6 @@ enum ds_type {
 
 
 struct ds1307 {
-	u8			regs[11];
 	struct nvmem_config	nvmem_cfg;
 	enum ds_type		type;
 	unsigned long		flags;
@@ -397,34 +396,36 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
 	struct ds1307	*ds1307 = dev_get_drvdata(dev);
 	int		tmp, ret;
 	const struct chip_desc *chip = &chips[ds1307->type];
+	u8 regs[7];
 
 	/* read the RTC date and time registers all at once */
-	ret = regmap_bulk_read(ds1307->regmap, chip->offset, ds1307->regs, 7);
+	ret = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
+			       sizeof(regs));
 	if (ret) {
 		dev_err(dev, "%s error %d\n", "read", ret);
 		return ret;
 	}
 
-	dev_dbg(dev, "%s: %7ph\n", "read", ds1307->regs);
+	dev_dbg(dev, "%s: %7ph\n", "read", regs);
 
 	/* if oscillator fail bit is set, no data can be trusted */
 	if (ds1307->type == m41t0 &&
-	    ds1307->regs[DS1307_REG_MIN] & M41T0_BIT_OF) {
+	    regs[DS1307_REG_MIN] & M41T0_BIT_OF) {
 		dev_warn_once(dev, "oscillator failed, set time!\n");
 		return -EINVAL;
 	}
 
-	t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f);
-	t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f);
-	tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f;
+	t->tm_sec = bcd2bin(regs[DS1307_REG_SECS] & 0x7f);
+	t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f);
+	tmp = regs[DS1307_REG_HOUR] & 0x3f;
 	t->tm_hour = bcd2bin(tmp);
-	t->tm_wday = bcd2bin(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1;
-	t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
-	tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
+	t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
+	t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f);
+	tmp = regs[DS1307_REG_MONTH] & 0x1f;
 	t->tm_mon = bcd2bin(tmp) - 1;
-	t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100;
+	t->tm_year = bcd2bin(regs[DS1307_REG_YEAR]) + 100;
 
-	if (ds1307->regs[chip->century_reg] & chip->century_bit &&
+	if (regs[chip->century_reg] & chip->century_bit &&
 	    IS_ENABLED(CONFIG_RTC_DRV_DS1307_CENTURY))
 		t->tm_year += 100;
 
@@ -444,7 +445,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
 	const struct chip_desc *chip = &chips[ds1307->type];
 	int		result;
 	int		tmp;
-	u8		*buf = ds1307->regs;
+	u8		regs[7];
 
 	dev_dbg(dev, "%s secs=%d, mins=%d, "
 		"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -463,35 +464,36 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
 		return -EINVAL;
 #endif
 
-	buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
-	buf[DS1307_REG_MIN] = bin2bcd(t->tm_min);
-	buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
-	buf[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
-	buf[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
-	buf[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
+	regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
+	regs[DS1307_REG_MIN] = bin2bcd(t->tm_min);
+	regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
+	regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
+	regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
+	regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
 
 	/* assume 20YY not 19YY */
 	tmp = t->tm_year - 100;
-	buf[DS1307_REG_YEAR] = bin2bcd(tmp);
+	regs[DS1307_REG_YEAR] = bin2bcd(tmp);
 
 	if (chip->century_enable_bit)
-		buf[chip->century_reg] |= chip->century_enable_bit;
+		regs[chip->century_reg] |= chip->century_enable_bit;
 	if (t->tm_year > 199 && chip->century_bit)
-		buf[chip->century_reg] |= chip->century_bit;
+		regs[chip->century_reg] |= chip->century_bit;
 
 	if (ds1307->type == mcp794xx) {
 		/*
 		 * these bits were cleared when preparing the date/time
 		 * values and need to be set again before writing the
-		 * buffer out to the device.
+		 * regsfer out to the device.
 		 */
-		buf[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
-		buf[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
+		regs[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
+		regs[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
 	}
 
-	dev_dbg(dev, "%s: %7ph\n", "write", buf);
+	dev_dbg(dev, "%s: %7ph\n", "write", regs);
 
-	result = regmap_bulk_write(ds1307->regmap, chip->offset, buf, 7);
+	result = regmap_bulk_write(ds1307->regmap, chip->offset, regs,
+				   sizeof(regs));
 	if (result) {
 		dev_err(dev, "%s error %d\n", "write", result);
 		return result;
@@ -503,33 +505,34 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
 	struct ds1307		*ds1307 = dev_get_drvdata(dev);
 	int			ret;
+	u8			regs[9];
 
 	if (!test_bit(HAS_ALARM, &ds1307->flags))
 		return -EINVAL;
 
 	/* read all ALARM1, ALARM2, and status registers at once */
 	ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS,
-			       ds1307->regs, 9);
+			       regs, sizeof(regs));
 	if (ret) {
 		dev_err(dev, "%s error %d\n", "alarm read", ret);
 		return ret;
 	}
 
 	dev_dbg(dev, "%s: %4ph, %3ph, %2ph\n", "alarm read",
-		&ds1307->regs[0], &ds1307->regs[4], &ds1307->regs[7]);
+		&regs[0], &regs[4], &regs[7]);
 
 	/*
 	 * report alarm time (ALARM1); assume 24 hour and day-of-month modes,
 	 * and that all four fields are checked matches
 	 */
-	t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
-	t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f);
-	t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f);
-	t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f);
+	t->time.tm_sec = bcd2bin(regs[0] & 0x7f);
+	t->time.tm_min = bcd2bin(regs[1] & 0x7f);
+	t->time.tm_hour = bcd2bin(regs[2] & 0x3f);
+	t->time.tm_mday = bcd2bin(regs[3] & 0x3f);
 
 	/* ... and status */
-	t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE);
-	t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I);
+	t->enabled = !!(regs[7] & DS1337_BIT_A1IE);
+	t->pending = !!(regs[8] & DS1337_BIT_A1I);
 
 	dev_dbg(dev, "%s secs=%d, mins=%d, "
 		"hours=%d, mday=%d, enabled=%d, pending=%d\n",
@@ -543,7 +546,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
 	struct ds1307		*ds1307 = dev_get_drvdata(dev);
-	unsigned char		*buf = ds1307->regs;
+	unsigned char		regs[9];
 	u8			control, status;
 	int			ret;
 
@@ -557,33 +560,35 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 		t->enabled, t->pending);
 
 	/* read current status of both alarms and the chip */
-	ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS, buf, 9);
+	ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS, regs,
+			       sizeof(regs));
 	if (ret) {
 		dev_err(dev, "%s error %d\n", "alarm write", ret);
 		return ret;
 	}
-	control = ds1307->regs[7];
-	status = ds1307->regs[8];
+	control = regs[7];
+	status = regs[8];
 
 	dev_dbg(dev, "%s: %4ph, %3ph, %02x %02x\n", "alarm set (old status)",
-		&ds1307->regs[0], &ds1307->regs[4], control, status);
+		&regs[0], &regs[4], control, status);
 
 	/* set ALARM1, using 24 hour and day-of-month modes */
-	buf[0] = bin2bcd(t->time.tm_sec);
-	buf[1] = bin2bcd(t->time.tm_min);
-	buf[2] = bin2bcd(t->time.tm_hour);
-	buf[3] = bin2bcd(t->time.tm_mday);
+	regs[0] = bin2bcd(t->time.tm_sec);
+	regs[1] = bin2bcd(t->time.tm_min);
+	regs[2] = bin2bcd(t->time.tm_hour);
+	regs[3] = bin2bcd(t->time.tm_mday);
 
 	/* set ALARM2 to non-garbage */
-	buf[4] = 0;
-	buf[5] = 0;
-	buf[6] = 0;
+	regs[4] = 0;
+	regs[5] = 0;
+	regs[6] = 0;
 
 	/* disable alarms */
-	buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
-	buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
+	regs[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
+	regs[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
 
-	ret = regmap_bulk_write(ds1307->regmap, DS1339_REG_ALARM1_SECS, buf, 9);
+	ret = regmap_bulk_write(ds1307->regmap, DS1339_REG_ALARM1_SECS, regs,
+				sizeof(regs));
 	if (ret) {
 		dev_err(dev, "can't set alarm time\n");
 		return ret;
@@ -592,8 +597,8 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	/* optionally enable ALARM1 */
 	if (t->enabled) {
 		dev_dbg(dev, "alarm IRQ armed\n");
-		buf[7] |= DS1337_BIT_A1IE;	/* only ALARM1 is used */
-		regmap_write(ds1307->regmap, DS1337_REG_CONTROL, buf[7]);
+		regs[7] |= DS1337_BIT_A1IE;	/* only ALARM1 is used */
+		regmap_write(ds1307->regmap, DS1337_REG_CONTROL, regs[7]);
 	}
 
 	return 0;
@@ -830,26 +835,27 @@ static irqreturn_t mcp794xx_irq(int irq, void *dev_id)
 static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
 	struct ds1307 *ds1307 = dev_get_drvdata(dev);
-	u8 *regs = ds1307->regs;
+	u8 regs[10];
 	int ret;
 
 	if (!test_bit(HAS_ALARM, &ds1307->flags))
 		return -EINVAL;
 
 	/* Read control and alarm 0 registers. */
-	ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10);
+	ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs,
+			       sizeof(regs));
 	if (ret)
 		return ret;
 
 	t->enabled = !!(regs[0] & MCP794XX_BIT_ALM0_EN);
 
 	/* Report alarm 0 time assuming 24-hour and day-of-month modes. */
-	t->time.tm_sec = bcd2bin(ds1307->regs[3] & 0x7f);
-	t->time.tm_min = bcd2bin(ds1307->regs[4] & 0x7f);
-	t->time.tm_hour = bcd2bin(ds1307->regs[5] & 0x3f);
-	t->time.tm_wday = bcd2bin(ds1307->regs[6] & 0x7) - 1;
-	t->time.tm_mday = bcd2bin(ds1307->regs[7] & 0x3f);
-	t->time.tm_mon = bcd2bin(ds1307->regs[8] & 0x1f) - 1;
+	t->time.tm_sec = bcd2bin(regs[3] & 0x7f);
+	t->time.tm_min = bcd2bin(regs[4] & 0x7f);
+	t->time.tm_hour = bcd2bin(regs[5] & 0x3f);
+	t->time.tm_wday = bcd2bin(regs[6] & 0x7) - 1;
+	t->time.tm_mday = bcd2bin(regs[7] & 0x3f);
+	t->time.tm_mon = bcd2bin(regs[8] & 0x1f) - 1;
 	t->time.tm_year = -1;
 	t->time.tm_yday = -1;
 	t->time.tm_isdst = -1;
@@ -858,9 +864,9 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 		"enabled=%d polarity=%d irq=%d match=%d\n", __func__,
 		t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
 		t->time.tm_wday, t->time.tm_mday, t->time.tm_mon, t->enabled,
-		!!(ds1307->regs[6] & MCP794XX_BIT_ALMX_POL),
-		!!(ds1307->regs[6] & MCP794XX_BIT_ALMX_IF),
-		(ds1307->regs[6] & MCP794XX_MSK_ALMX_MATCH) >> 4);
+		!!(regs[6] & MCP794XX_BIT_ALMX_POL),
+		!!(regs[6] & MCP794XX_BIT_ALMX_IF),
+		(regs[6] & MCP794XX_MSK_ALMX_MATCH) >> 4);
 
 	return 0;
 }
@@ -868,7 +874,7 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
 	struct ds1307 *ds1307 = dev_get_drvdata(dev);
-	unsigned char *regs = ds1307->regs;
+	unsigned char regs[10];
 	int ret;
 
 	if (!test_bit(HAS_ALARM, &ds1307->flags))
@@ -881,7 +887,8 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 		t->enabled, t->pending);
 
 	/* Read control and alarm 0 registers. */
-	ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10);
+	ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs,
+			       sizeof(regs));
 	if (ret)
 		return ret;
 
@@ -900,7 +907,8 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	/* Disable interrupt. We will not enable until completely programmed */
 	regs[0] &= ~MCP794XX_BIT_ALM0_EN;
 
-	ret = regmap_bulk_write(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10);
+	ret = regmap_bulk_write(ds1307->regmap, MCP794XX_REG_CONTROL, regs,
+				sizeof(regs));
 	if (ret)
 		return ret;
 
@@ -1344,7 +1352,7 @@ static int ds1307_probe(struct i2c_client *client,
 	const struct chip_desc	*chip;
 	bool			want_irq;
 	bool			ds1307_can_wakeup_device = false;
-	unsigned char		*buf;
+	unsigned char		regs[8];
 	struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
 	struct rtc_time		tm;
 	unsigned long		timestamp;
@@ -1400,8 +1408,6 @@ static int ds1307_probe(struct i2c_client *client,
 			     trickle_charger_setup);
 	}
 
-	buf = ds1307->regs;
-
 #ifdef CONFIG_OF
 /*
  * For devices with no IRQ directly connected to the SoC, the RTC chip
@@ -1423,15 +1429,15 @@ static int ds1307_probe(struct i2c_client *client,
 	case ds_3231:
 		/* get registers that the "rtc" read below won't read... */
 		err = regmap_bulk_read(ds1307->regmap, DS1337_REG_CONTROL,
-				       buf, 2);
+				       regs, 2);
 		if (err) {
 			dev_dbg(ds1307->dev, "read error %d\n", err);
 			goto exit;
 		}
 
 		/* oscillator off?  turn it on, so clock can tick. */
-		if (ds1307->regs[0] & DS1337_BIT_nEOSC)
-			ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
+		if (regs[0] & DS1337_BIT_nEOSC)
+			regs[0] &= ~DS1337_BIT_nEOSC;
 
 		/*
 		 * Using IRQ or defined as wakeup-source?
@@ -1440,77 +1446,77 @@ static int ds1307_probe(struct i2c_client *client,
 		 * running on Vbackup (BBSQI/BBSQW)
 		 */
 		if (want_irq || ds1307_can_wakeup_device) {
-			ds1307->regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit;
-			ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
+			regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit;
+			regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
 		}
 
 		regmap_write(ds1307->regmap, DS1337_REG_CONTROL,
-			     ds1307->regs[0]);
+			     regs[0]);
 
 		/* oscillator fault?  clear flag, and warn */
-		if (ds1307->regs[1] & DS1337_BIT_OSF) {
+		if (regs[1] & DS1337_BIT_OSF) {
 			regmap_write(ds1307->regmap, DS1337_REG_STATUS,
-				     ds1307->regs[1] & ~DS1337_BIT_OSF);
+				     regs[1] & ~DS1337_BIT_OSF);
 			dev_warn(ds1307->dev, "SET TIME!\n");
 		}
 		break;
 
 	case rx_8025:
 		err = regmap_bulk_read(ds1307->regmap,
-				       RX8025_REG_CTRL1 << 4 | 0x08, buf, 2);
+				       RX8025_REG_CTRL1 << 4 | 0x08, regs, 2);
 		if (err) {
 			dev_dbg(ds1307->dev, "read error %d\n", err);
 			goto exit;
 		}
 
 		/* oscillator off?  turn it on, so clock can tick. */
-		if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
-			ds1307->regs[1] |= RX8025_BIT_XST;
+		if (!(regs[1] & RX8025_BIT_XST)) {
+			regs[1] |= RX8025_BIT_XST;
 			regmap_write(ds1307->regmap,
 				     RX8025_REG_CTRL2 << 4 | 0x08,
-				     ds1307->regs[1]);
+				     regs[1]);
 			dev_warn(ds1307->dev,
 				 "oscillator stop detected - SET TIME!\n");
 		}
 
-		if (ds1307->regs[1] & RX8025_BIT_PON) {
-			ds1307->regs[1] &= ~RX8025_BIT_PON;
+		if (regs[1] & RX8025_BIT_PON) {
+			regs[1] &= ~RX8025_BIT_PON;
 			regmap_write(ds1307->regmap,
 				     RX8025_REG_CTRL2 << 4 | 0x08,
-				     ds1307->regs[1]);
+				     regs[1]);
 			dev_warn(ds1307->dev, "power-on detected\n");
 		}
 
-		if (ds1307->regs[1] & RX8025_BIT_VDET) {
-			ds1307->regs[1] &= ~RX8025_BIT_VDET;
+		if (regs[1] & RX8025_BIT_VDET) {
+			regs[1] &= ~RX8025_BIT_VDET;
 			regmap_write(ds1307->regmap,
 				     RX8025_REG_CTRL2 << 4 | 0x08,
-				     ds1307->regs[1]);
+				     regs[1]);
 			dev_warn(ds1307->dev, "voltage drop detected\n");
 		}
 
 		/* make sure we are running in 24hour mode */
-		if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
+		if (!(regs[0] & RX8025_BIT_2412)) {
 			u8 hour;
 
 			/* switch to 24 hour mode */
 			regmap_write(ds1307->regmap,
 				     RX8025_REG_CTRL1 << 4 | 0x08,
-				     ds1307->regs[0] | RX8025_BIT_2412);
+				     regs[0] | RX8025_BIT_2412);
 
 			err = regmap_bulk_read(ds1307->regmap,
 					       RX8025_REG_CTRL1 << 4 | 0x08,
-					       buf, 2);
+					       regs, 2);
 			if (err) {
 				dev_dbg(ds1307->dev, "read error %d\n", err);
 				goto exit;
 			}
 
 			/* correct hour */
-			hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
+			hour = bcd2bin(regs[DS1307_REG_HOUR]);
 			if (hour == 12)
 				hour = 0;
-			if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
+			if (regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
 				hour += 12;
 
 			regmap_write(ds1307->regmap,
@@ -1523,7 +1529,8 @@ static int ds1307_probe(struct i2c_client *client,
 
 read_rtc:
 	/* read RTC registers */
-	err = regmap_bulk_read(ds1307->regmap, chip->offset, buf, 8);
+	err = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
+			       sizeof(regs));
 	if (err) {
 		dev_dbg(ds1307->dev, "read error %d\n", err);
 		goto exit;
@@ -1534,7 +1541,7 @@ static int ds1307_probe(struct i2c_client *client,
 	 * specify the extra bits as must-be-zero, but there are
 	 * still a few values that are clearly out-of-range.
 	 */
-	tmp = ds1307->regs[DS1307_REG_SECS];
+	tmp = regs[DS1307_REG_SECS];
 	switch (ds1307->type) {
 	case ds_1307:
 	case m41t0:
@@ -1553,9 +1560,9 @@ static int ds1307_probe(struct i2c_client *client,
 			regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
 
 		/* oscillator fault?  clear flag, and warn */
-		if (ds1307->regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
+		if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
 			regmap_write(ds1307->regmap, DS1307_REG_CONTROL,
-					ds1307->regs[DS1307_REG_CONTROL] &
+					regs[DS1307_REG_CONTROL] &
 					~DS1338_BIT_OSF);
 			dev_warn(ds1307->dev, "SET TIME!\n");
 			goto read_rtc;
@@ -1580,9 +1587,9 @@ static int ds1307_probe(struct i2c_client *client,
 		break;
 	case mcp794xx:
 		/* make sure that the backup battery is enabled */
-		if (!(ds1307->regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
+		if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
 			regmap_write(ds1307->regmap, DS1307_REG_WDAY,
-				     ds1307->regs[DS1307_REG_WDAY] |
+				     regs[DS1307_REG_WDAY] |
 				     MCP794XX_BIT_VBATEN);
 		}
 
@@ -1599,7 +1606,7 @@ static int ds1307_probe(struct i2c_client *client,
 		break;
 	}
 
-	tmp = ds1307->regs[DS1307_REG_HOUR];
+	tmp = regs[DS1307_REG_HOUR];
 	switch (ds1307->type) {
 	case ds_1340:
 	case m41t0:
@@ -1622,7 +1629,7 @@ static int ds1307_probe(struct i2c_client *client,
 		tmp = bcd2bin(tmp & 0x1f);
 		if (tmp == 12)
 			tmp = 0;
-		if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
+		if (regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
 			tmp += 12;
 		regmap_write(ds1307->regmap, chip->offset + DS1307_REG_HOUR,
 			     bin2bcd(tmp));
-- 
2.14.1

^ permalink raw reply related

* [PATCH 3/7] rtc: ds1307: use u32
From: Alexandre Belloni @ 2017-09-04 20:46 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Heiner Kallweit, Alexandre Belloni
In-Reply-To: <20170904204608.7090-1-alexandre.belloni@free-electrons.com>

u32 should be used instead of uint32_t

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-ds1307.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 93fb08452159..328183e0e121 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -142,13 +142,13 @@ struct chip_desc {
 	irq_handler_t		irq_handler;
 	const struct rtc_class_ops *rtc_ops;
 	u16			trickle_charger_reg;
-	u8			(*do_trickle_setup)(struct ds1307 *, uint32_t,
+	u8			(*do_trickle_setup)(struct ds1307 *, u32,
 						    bool);
 };
 
 static int ds1307_get_time(struct device *dev, struct rtc_time *t);
 static int ds1307_set_time(struct device *dev, struct rtc_time *t);
-static u8 do_trickle_setup_ds1339(struct ds1307 *, uint32_t ohms, bool diode);
+static u8 do_trickle_setup_ds1339(struct ds1307 *, u32 ohms, bool diode);
 static irqreturn_t rx8130_irq(int irq, void *dev_id);
 static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t);
 static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t);
@@ -963,7 +963,7 @@ static int ds1307_nvram_write(void *priv, unsigned int offset, void *val,
 /*----------------------------------------------------------------------*/
 
 static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307,
-				  uint32_t ohms, bool diode)
+				  u32 ohms, bool diode)
 {
 	u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE :
 		DS1307_TRICKLE_CHARGER_NO_DIODE;
@@ -989,7 +989,7 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307,
 static u8 ds1307_trickle_init(struct ds1307 *ds1307,
 			      const struct chip_desc *chip)
 {
-	uint32_t ohms;
+	u32 ohms;
 	bool diode = true;
 
 	if (!chip->do_trickle_setup)
-- 
2.14.1

^ permalink raw reply related

* [PATCH 5/7] rtc: ds1307: fix alignments and blank lines
From: Alexandre Belloni @ 2017-09-04 20:46 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Heiner Kallweit, Alexandre Belloni
In-Reply-To: <20170904204608.7090-1-alexandre.belloni@free-electrons.com>

Alignment should always match open parenthesis.
Also remove two unnecessary blank lines

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-ds1307.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 5b2fe3579e45..bac0f9ec9351 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -51,7 +51,6 @@ enum ds_type {
 	/* rs5c372 too?  different address... */
 };
 
-
 /* RTC registers don't differ much, except for the century flag */
 #define DS1307_REG_SECS		0x00	/* 00-59 */
 #	define DS1307_BIT_CH		0x80
@@ -114,7 +113,6 @@ enum ds_type {
 #	define RX8025_BIT_VDET		0x40
 #	define RX8025_BIT_XST		0x20
 
-
 struct ds1307 {
 	struct nvmem_config	nvmem_cfg;
 	enum ds_type		type;
@@ -1042,7 +1040,7 @@ static int ds3231_hwmon_read_temp(struct device *dev, s32 *mC)
 }
 
 static ssize_t ds3231_hwmon_show_temp(struct device *dev,
-				struct device_attribute *attr, char *buf)
+				      struct device_attribute *attr, char *buf)
 {
 	int ret;
 	s32 temp;
@@ -1054,7 +1052,7 @@ static ssize_t ds3231_hwmon_show_temp(struct device *dev,
 	return sprintf(buf, "%d\n", temp);
 }
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ds3231_hwmon_show_temp,
-			NULL, 0);
+			  NULL, 0);
 
 static struct attribute *ds3231_hwmon_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
@@ -1070,7 +1068,8 @@ static void ds1307_hwmon_register(struct ds1307 *ds1307)
 		return;
 
 	dev = devm_hwmon_device_register_with_groups(ds1307->dev, ds1307->name,
-						ds1307, ds3231_hwmon_groups);
+						     ds1307,
+						     ds3231_hwmon_groups);
 	if (IS_ERR(dev)) {
 		dev_warn(ds1307->dev, "unable to register hwmon device %ld\n",
 			 PTR_ERR(dev));
@@ -1142,7 +1141,7 @@ static unsigned long ds3231_clk_sqw_recalc_rate(struct clk_hw *hw,
 }
 
 static long ds3231_clk_sqw_round_rate(struct clk_hw *hw, unsigned long rate,
-					unsigned long *prate)
+				      unsigned long *prate)
 {
 	int i;
 
@@ -1155,7 +1154,7 @@ static long ds3231_clk_sqw_round_rate(struct clk_hw *hw, unsigned long rate,
 }
 
 static int ds3231_clk_sqw_set_rate(struct clk_hw *hw, unsigned long rate,
-					unsigned long parent_rate)
+				   unsigned long parent_rate)
 {
 	struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw);
 	int control = 0;
@@ -1215,7 +1214,7 @@ static const struct clk_ops ds3231_clk_sqw_ops = {
 };
 
 static unsigned long ds3231_clk_32khz_recalc_rate(struct clk_hw *hw,
-						unsigned long parent_rate)
+						  unsigned long parent_rate)
 {
 	return 32768;
 }
@@ -1306,7 +1305,7 @@ static int ds3231_clks_register(struct ds1307 *ds1307)
 
 		/* optional override of the clockname */
 		of_property_read_string_index(node, "clock-output-names", i,
-						&init.name);
+					      &init.name);
 		ds1307->clks[i].init = &init;
 
 		onecell->clks[i] = devm_clk_register(ds1307->dev,
@@ -1570,8 +1569,8 @@ static int ds1307_probe(struct i2c_client *client,
 		/* oscillator fault?  clear flag, and warn */
 		if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
 			regmap_write(ds1307->regmap, DS1307_REG_CONTROL,
-					regs[DS1307_REG_CONTROL] &
-					~DS1338_BIT_OSF);
+				     regs[DS1307_REG_CONTROL] &
+				     ~DS1338_BIT_OSF);
 			dev_warn(ds1307->dev, "SET TIME!\n");
 			goto read_rtc;
 		}
-- 
2.14.1

^ permalink raw reply related

* [PATCH 2/7] rtc: ds1307: use sizeof
From: Alexandre Belloni @ 2017-09-04 20:46 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Heiner Kallweit, Alexandre Belloni
In-Reply-To: <20170904204608.7090-1-alexandre.belloni@free-electrons.com>

Use sizeof where possible to ensure we don't read/write more than the
allocated buffer.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-ds1307.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 8de1d7116461..93fb08452159 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -650,7 +650,8 @@ static irqreturn_t rx8130_irq(int irq, void *dev_id)
 	mutex_lock(lock);
 
 	/* Read control registers. */
-	ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
+	ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
+			       sizeof(ctl));
 	if (ret < 0)
 		goto out;
 	if (!(ctl[1] & RX8130_REG_FLAG_AF))
@@ -658,7 +659,8 @@ static irqreturn_t rx8130_irq(int irq, void *dev_id)
 	ctl[1] &= ~RX8130_REG_FLAG_AF;
 	ctl[2] &= ~RX8130_REG_CONTROL0_AIE;
 
-	ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
+	ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
+				sizeof(ctl));
 	if (ret < 0)
 		goto out;
 
@@ -680,12 +682,14 @@ static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 		return -EINVAL;
 
 	/* Read alarm registers. */
-	ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald, 3);
+	ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald,
+			       sizeof(ald));
 	if (ret < 0)
 		return ret;
 
 	/* Read control registers. */
-	ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
+	ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
+			       sizeof(ctl));
 	if (ret < 0)
 		return ret;
 
@@ -726,7 +730,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 		t->enabled, t->pending);
 
 	/* Read control registers. */
-	ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
+	ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
+			       sizeof(ctl));
 	if (ret < 0)
 		return ret;
 
@@ -734,7 +739,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	ctl[1] |= RX8130_REG_FLAG_AF;
 	ctl[2] &= ~RX8130_REG_CONTROL0_AIE;
 
-	ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
+	ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
+				sizeof(ctl));
 	if (ret < 0)
 		return ret;
 
@@ -743,7 +749,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	ald[1] = bin2bcd(t->time.tm_hour);
 	ald[2] = bin2bcd(t->time.tm_mday);
 
-	ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_ALARM_MIN, ald, 3);
+	ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_ALARM_MIN, ald,
+				sizeof(ald));
 	if (ret < 0)
 		return ret;
 
@@ -752,7 +759,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 
 	ctl[2] |= RX8130_REG_CONTROL0_AIE;
 
-	return regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3);
+	return regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
+				 sizeof(ctl));
 }
 
 static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled)
-- 
2.14.1

^ permalink raw reply related

* [PATCH 4/7] rtc: ds1307: use BIT
From: Alexandre Belloni @ 2017-09-04 20:46 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Heiner Kallweit, Alexandre Belloni
In-Reply-To: <20170904204608.7090-1-alexandre.belloni@free-electrons.com>

Use the BIT macro were possbiel.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-ds1307.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 328183e0e121..5b2fe3579e45 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -634,11 +634,11 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
 #define RX8130_REG_ALARM_HOUR		0x08
 #define RX8130_REG_ALARM_WEEK_OR_DAY	0x09
 #define RX8130_REG_EXTENSION		0x0c
-#define RX8130_REG_EXTENSION_WADA	(1 << 3)
+#define RX8130_REG_EXTENSION_WADA	BIT(3)
 #define RX8130_REG_FLAG			0x0d
-#define RX8130_REG_FLAG_AF		(1 << 3)
+#define RX8130_REG_FLAG_AF		BIT(3)
 #define RX8130_REG_CONTROL0		0x0e
-#define RX8130_REG_CONTROL0_AIE		(1 << 3)
+#define RX8130_REG_CONTROL0_AIE		BIT(3)
 
 static irqreturn_t rx8130_irq(int irq, void *dev_id)
 {
@@ -798,11 +798,11 @@ static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled)
 #define MCP794XX_REG_ALARM0_CTRL	0x0d
 #define MCP794XX_REG_ALARM1_BASE	0x11
 #define MCP794XX_REG_ALARM1_CTRL	0x14
-#	define MCP794XX_BIT_ALMX_IF	(1 << 3)
-#	define MCP794XX_BIT_ALMX_C0	(1 << 4)
-#	define MCP794XX_BIT_ALMX_C1	(1 << 5)
-#	define MCP794XX_BIT_ALMX_C2	(1 << 6)
-#	define MCP794XX_BIT_ALMX_POL	(1 << 7)
+#	define MCP794XX_BIT_ALMX_IF	BIT(3)
+#	define MCP794XX_BIT_ALMX_C0	BIT(4)
+#	define MCP794XX_BIT_ALMX_C1	BIT(5)
+#	define MCP794XX_BIT_ALMX_C2	BIT(6)
+#	define MCP794XX_BIT_ALMX_POL	BIT(7)
 #	define MCP794XX_MSK_ALMX_MATCH	(MCP794XX_BIT_ALMX_C0 | \
 					 MCP794XX_BIT_ALMX_C1 | \
 					 MCP794XX_BIT_ALMX_C2)
@@ -869,7 +869,7 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 	t->time.tm_isdst = -1;
 
 	dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d "
-		"enabled=%d polarity=%d irq=%d match=%d\n", __func__,
+		"enabled=%d polarity=%d irq=%d match=%lu\n", __func__,
 		t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
 		t->time.tm_wday, t->time.tm_mday, t->time.tm_mon, t->enabled,
 		!!(regs[6] & MCP794XX_BIT_ALMX_POL),
-- 
2.14.1

^ permalink raw reply related

* Re: [PATCH v3 2/5] dt-bindings: input: Add document bindings for mtk-pmic-keys
From: Chen Zhong @ 2017-09-02  2:16 UTC (permalink / raw)
  To: Rob Herring
  Cc: Dmitry Torokhov, Mark Rutland, Matthias Brugger, Lee Jones,
	Eddie Huang, Alessandro Zummo, Alexandre Belloni, Andi Shyti,
	Javier Martinez Canillas, Linus Walleij, Jaechul Lee, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	linux-rtc
In-Reply-To: <20170831195239.b2litxbu7smhkkjl@rob-hp-laptop>

On Thu, 2017-08-31 at 14:52 -0500, Rob Herring wrote:
> On Fri, Aug 25, 2017 at 02:32:30PM +0800, Chen Zhong wrote:
> > This patch adds the device tree binding documentation for the MediaTek
> > pmic keys found on PMIC MT6397/MT6323.
> > 
> > Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
> > ---
> >  .../devicetree/bindings/input/mtk-pmic-keys.txt    |   38 ++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> > new file mode 100644
> > index 0000000..100ec44
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> > @@ -0,0 +1,38 @@
> > +MediaTek MT6397/MT6323 PMIC Keys Device Driver
> > +
> > +There are two key functions provided by MT6397/MT6323 PMIC, pwrkey
> > +and homekey. The key functions are defined as the subnode of the function
> > +node provided by MT6397/MT6323 PMIC that is being defined as one kind
> > +of Muti-Function Device (MFD)
> > +
> > +For MT6397/MT6323 MFD bindings see:
> > +Documentation/devicetree/bindings/mfd/mt6397.txt
> > +
> > +Required properties:
> > +- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
> > +- linux,keycodes: Specifies the numeric keycode values to
> > +	be used for reporting keys presses. The array can
> > +	contain up to 2 entries.
> > +
> > +Optional Properties:
> > +- wakeup-source: each key can be used as a wakeup source.
> 
> wakeup-source is defined as a boolean.

Hi Rob,

Could I modify it as this?

mediatek,wakeup-keys = <1>, <0>;
wakeup-source;

Thanks.
> 
> > +- mediatek,long-press-mode: Long press key shutdown setting, 1 for
> > +	pwrkey only, 2 for pwrkey/homekey together, others for disabled.
> > +- debounce-interval: Long press key shutdown debouncing interval time
> > +	in seconds. 0/1/2/3 for 8/11/14/5 seconds. If not specified defaults to 0.
> > +
> > +Example:
> > +
> > +	pmic: mt6397 {
> > +		compatible = "mediatek,mt6397";
> > +
> > +		...
> > +
> > +		mt6397keys: mt6397keys {
> > +			compatible = "mediatek,mt6397-keys";
> > +			linux,keycodes = <KEY_POWER>, <KEY_VOLUMEDOWN>;
> > +			wakeup-source = <1>, <0>;
> > +			mediatek,long-press-mode = <1>;
> > +			debounce-interval = <0>;
> > +		};
> > +	};
> > -- 
> > 1.7.9.5
> > 

^ permalink raw reply

* Re: [PATCH v3 2/5] dt-bindings: input: Add document bindings for mtk-pmic-keys
From: Chen Zhong @ 2017-09-01  2:00 UTC (permalink / raw)
  To: Rob Herring
  Cc: Dmitry Torokhov, Mark Rutland, Matthias Brugger, Lee Jones,
	Eddie Huang, Alessandro Zummo, Alexandre Belloni, Andi Shyti,
	Javier Martinez Canillas, Linus Walleij, Jaechul Lee, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	linux-rtc
In-Reply-To: <20170831195239.b2litxbu7smhkkjl@rob-hp-laptop>

On Thu, 2017-08-31 at 14:52 -0500, Rob Herring wrote:
> On Fri, Aug 25, 2017 at 02:32:30PM +0800, Chen Zhong wrote:
> > This patch adds the device tree binding documentation for the MediaTek
> > pmic keys found on PMIC MT6397/MT6323.
> > 
> > Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
> > ---
> >  .../devicetree/bindings/input/mtk-pmic-keys.txt    |   38 ++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> > new file mode 100644
> > index 0000000..100ec44
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> > @@ -0,0 +1,38 @@
> > +MediaTek MT6397/MT6323 PMIC Keys Device Driver
> > +
> > +There are two key functions provided by MT6397/MT6323 PMIC, pwrkey
> > +and homekey. The key functions are defined as the subnode of the function
> > +node provided by MT6397/MT6323 PMIC that is being defined as one kind
> > +of Muti-Function Device (MFD)
> > +
> > +For MT6397/MT6323 MFD bindings see:
> > +Documentation/devicetree/bindings/mfd/mt6397.txt
> > +
> > +Required properties:
> > +- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
> > +- linux,keycodes: Specifies the numeric keycode values to
> > +	be used for reporting keys presses. The array can
> > +	contain up to 2 entries.
> > +
> > +Optional Properties:
> > +- wakeup-source: each key can be used as a wakeup source.
> 
> wakeup-source is defined as a boolean.

Hi Rob,

We have two keys, maybe one key can be used as a wakeup source, another
not.Since wakeup-source is defined as a boolean, we cannot distinguish
the behavior of the two keys. May i know the better way to do this?

Thank you.
> 
> > +- mediatek,long-press-mode: Long press key shutdown setting, 1 for
> > +	pwrkey only, 2 for pwrkey/homekey together, others for disabled.
> > +- debounce-interval: Long press key shutdown debouncing interval time
> > +	in seconds. 0/1/2/3 for 8/11/14/5 seconds. If not specified defaults to 0.
> > +
> > +Example:
> > +
> > +	pmic: mt6397 {
> > +		compatible = "mediatek,mt6397";
> > +
> > +		...
> > +
> > +		mt6397keys: mt6397keys {
> > +			compatible = "mediatek,mt6397-keys";
> > +			linux,keycodes = <KEY_POWER>, <KEY_VOLUMEDOWN>;
> > +			wakeup-source = <1>, <0>;
> > +			mediatek,long-press-mode = <1>;
> > +			debounce-interval = <0>;
> > +		};
> > +	};
> > -- 
> > 1.7.9.5
> > 

^ permalink raw reply

* [rtc-linux] Re: [RESEND v9 05/12] clk: Kconfig: Name RK805 in Kconfig for COMMON_CLK_RK808
From: Stephen Boyd @ 2017-08-31 23:20 UTC (permalink / raw)
  To: Joseph Chen
  Cc: gnurou, linus.walleij, dmitry.torokhov, lee.jones, linux-kernel,
	huangtao, devicetree, linux-gpio, broonie, zhangqing, robh+dt,
	lgirdwood, linux-rockchip, wdc, tony.xie, linux-input,
	mark.rutland, w.egorov, linux-clk, a.zummo, alexandre.belloni,
	rtc-linux
In-Reply-To: <1502848803-22954-1-git-send-email-chenjh@rock-chips.com>

On 08/16, Joseph Chen wrote:
> From: Elaine Zhang <zhangqing@rock-chips.com>
> 
> The RK808 and RK805 PMICs are using a similar register map.
> We can reuse the clk driver for the RK805 PMIC. So let's add
> the RK805 in the Kconfig description.
> 
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
> Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* Re: [PATCH v3 2/5] dt-bindings: input: Add document bindings for mtk-pmic-keys
From: Rob Herring @ 2017-08-31 19:52 UTC (permalink / raw)
  To: Chen Zhong
  Cc: Dmitry Torokhov, Mark Rutland, Matthias Brugger, Lee Jones,
	Eddie Huang, Alessandro Zummo, Alexandre Belloni, Andi Shyti,
	Javier Martinez Canillas, Linus Walleij, Jaechul Lee, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	linux-rtc
In-Reply-To: <1503642753-12385-3-git-send-email-chen.zhong@mediatek.com>

On Fri, Aug 25, 2017 at 02:32:30PM +0800, Chen Zhong wrote:
> This patch adds the device tree binding documentation for the MediaTek
> pmic keys found on PMIC MT6397/MT6323.
> 
> Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
> ---
>  .../devicetree/bindings/input/mtk-pmic-keys.txt    |   38 ++++++++++++++++++++
>  1 file changed, 38 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> 
> diff --git a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> new file mode 100644
> index 0000000..100ec44
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
> @@ -0,0 +1,38 @@
> +MediaTek MT6397/MT6323 PMIC Keys Device Driver
> +
> +There are two key functions provided by MT6397/MT6323 PMIC, pwrkey
> +and homekey. The key functions are defined as the subnode of the function
> +node provided by MT6397/MT6323 PMIC that is being defined as one kind
> +of Muti-Function Device (MFD)
> +
> +For MT6397/MT6323 MFD bindings see:
> +Documentation/devicetree/bindings/mfd/mt6397.txt
> +
> +Required properties:
> +- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
> +- linux,keycodes: Specifies the numeric keycode values to
> +	be used for reporting keys presses. The array can
> +	contain up to 2 entries.
> +
> +Optional Properties:
> +- wakeup-source: each key can be used as a wakeup source.

wakeup-source is defined as a boolean.

> +- mediatek,long-press-mode: Long press key shutdown setting, 1 for
> +	pwrkey only, 2 for pwrkey/homekey together, others for disabled.
> +- debounce-interval: Long press key shutdown debouncing interval time
> +	in seconds. 0/1/2/3 for 8/11/14/5 seconds. If not specified defaults to 0.
> +
> +Example:
> +
> +	pmic: mt6397 {
> +		compatible = "mediatek,mt6397";
> +
> +		...
> +
> +		mt6397keys: mt6397keys {
> +			compatible = "mediatek,mt6397-keys";
> +			linux,keycodes = <KEY_POWER>, <KEY_VOLUMEDOWN>;
> +			wakeup-source = <1>, <0>;
> +			mediatek,long-press-mode = <1>;
> +			debounce-interval = <0>;
> +		};
> +	};
> -- 
> 1.7.9.5
> 

^ permalink raw reply

* Re: [rtc-linux] [PATCH 1/2] rtc: pcf2127: add support for pcf2127 watchdog functionality
From: Sean Nyekjær @ 2017-08-30  7:45 UTC (permalink / raw)
  To: Alexandre Belloni; +Cc: linux-rtc
In-Reply-To: <20170829150739.apyt4lxguypebkbm@piout.net>



On 2017-08-29 17:07, Alexandre Belloni wrote:
> Hi Sean,
>
> I know this patch is 7 months old but I never had the time to write a
> proper reply.
>
> This is using a pretty old API. Can you register a proper watchdog using
> the watchdog subsystem (see drivers/watchdog)? Also, please copy the
> watchdog maintainers.
>
> I understand this will require a significant rewrite effort but the
> final code will be quite cleaner.
Hi Alexandre

I unfortunately don't have access to the hardware anymore...
I think it would be very risky to rewrite the whole code without testing 
it :-)

Yes this driver is quite hacky in some ways. It could be nice if the 
watchdog part for this could be in the driver/watchdog and the rtc part 
here. Maybe we could have 2 entries in the devicetree that shared the 
same i2c device address.

/Sean

^ permalink raw reply

* Re: [rtc-linux] [PATCH 1/2] rtc: pcf2127: add support for pcf2127 watchdog functionality
From: Alexandre Belloni @ 2017-08-30  7:52 UTC (permalink / raw)
  To: Sean Nyekjær; +Cc: linux-rtc
In-Reply-To: <4294cb1e-a01f-66db-8b64-eb4d5e68569e@prevas.dk>

On 30/08/2017 at 09:45:06 +0200, Sean Nyekjær wrote:
> 
> 
> On 2017-08-29 17:07, Alexandre Belloni wrote:
> > Hi Sean,
> > 
> > I know this patch is 7 months old but I never had the time to write a
> > proper reply.
> > 
> > This is using a pretty old API. Can you register a proper watchdog using
> > the watchdog subsystem (see drivers/watchdog)? Also, please copy the
> > watchdog maintainers.
> > 
> > I understand this will require a significant rewrite effort but the
> > final code will be quite cleaner.
> Hi Alexandre
> 
> I unfortunately don't have access to the hardware anymore...
> I think it would be very risky to rewrite the whole code without testing it
> :-)
> 

Ok, too bad. :(

> Yes this driver is quite hacky in some ways. It could be nice if the
> watchdog part for this could be in the driver/watchdog and the rtc part
> here. Maybe we could have 2 entries in the devicetree that shared the same
> i2c device address.
> 

If you want to go that route, the proper way is to use the MFD
subsystem.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH RfC] rtc: ds1307: improve weekday handling
From: Heiner Kallweit @ 2017-08-29 19:52 UTC (permalink / raw)
  To: Alexandre Belloni; +Cc: linux-rtc

The current code for checking and fixing the weekday in ds1307_probe
faces some issues:
- This check is applied to all chips even if its applicable (AFAIK)
  to mcp794xx only
- The check uses MCP794XX constants for registers and bits even though
  it's executed also on other chips (ok, this could be fixed easily)
- It relies on tm_wday being properly populated when core calls set_time
  and set_alarm. This is not guaranteed at all.

First two issue we could solve by moving the check to the
mcp794xx-specific initialization (where also VBATEN flag is set).

The proposed alternative is in the set_alarm path for mcp794xx only and
calculates the alarm weekday based on the current weekday in the RTC
timekeeping regs and the difference between alarm date and current date.
So we are fine with any weekday even if it doesn't match the date.

Still there are cases where this could fail, e.g.:
- rtc date/time + weekday have power-on-reset default values
- alarm is set to actual date/time + x
- set_time is called (may change diff between rtc weekday and actual
  weekday)

But similar issues we have with the current code too:
- rtc date/time + weekday have power-on-reset default values
- alarm is set to rtc date/time + x
- set_time is called before the alarm triggers

Using random rtc date/time with relative alarms simply can interfere
with set_time. I'm not totally convinced of either option yet.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/rtc/rtc-ds1307.c | 52 ++++++++++++++++++++++++------------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 9d680d36..4ba62549 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -787,8 +787,6 @@ static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled)
  * Alarm support for mcp794xx devices.
  */
 
-#define MCP794XX_REG_WEEKDAY		0x3
-#define MCP794XX_REG_WEEKDAY_WDAY_MASK	0x7
 #define MCP794XX_REG_CONTROL		0x07
 #	define MCP794XX_BIT_ALM0_EN	0x10
 #	define MCP794XX_BIT_ALM1_EN	0x20
@@ -877,15 +875,38 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 	return 0;
 }
 
+/*
+ * We may have a random RTC weekday, therefore calculate alarm weekday based
+ * on current weekday we read from the RTC timekeeping regs
+ */
+static int mcp794xx_alm_weekday(struct device *dev, struct rtc_time *tm_alarm)
+{
+	struct rtc_time tm_now;
+	int days_now, days_alarm, ret;
+
+	ret = ds1307_get_time(dev, &tm_now);
+	if (ret)
+		return ret;
+
+	days_now = div_s64(rtc_tm_to_time64(&tm_now), 24 * 60 * 60);
+	days_alarm = div_s64(rtc_tm_to_time64(tm_alarm), 24 * 60 * 60);
+
+	return (tm_now.tm_wday + days_alarm - days_now) % 7 + 1;
+}
+
 static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
 	struct ds1307 *ds1307 = dev_get_drvdata(dev);
 	unsigned char regs[10];
-	int ret;
+	int wday, ret;
 
 	if (!test_bit(HAS_ALARM, &ds1307->flags))
 		return -EINVAL;
 
+	wday = mcp794xx_alm_weekday(dev, &t->time);
+	if (wday < 0)
+		return wday;
+
 	dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d "
 		"enabled=%d pending=%d\n", __func__,
 		t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
@@ -902,7 +923,7 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	regs[3] = bin2bcd(t->time.tm_sec);
 	regs[4] = bin2bcd(t->time.tm_min);
 	regs[5] = bin2bcd(t->time.tm_hour);
-	regs[6] = bin2bcd(t->time.tm_wday + 1);
+	regs[6] = wday;
 	regs[7] = bin2bcd(t->time.tm_mday);
 	regs[8] = bin2bcd(t->time.tm_mon + 1);
 
@@ -1355,14 +1376,12 @@ static int ds1307_probe(struct i2c_client *client,
 {
 	struct ds1307		*ds1307;
 	int			err = -ENODEV;
-	int			tmp, wday;
+	int			tmp;
 	const struct chip_desc	*chip;
 	bool			want_irq;
 	bool			ds1307_can_wakeup_device = false;
 	unsigned char		regs[8];
 	struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
-	struct rtc_time		tm;
-	unsigned long		timestamp;
 	u8			trickle_charger_setup = 0;
 
 	ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL);
@@ -1642,25 +1661,6 @@ static int ds1307_probe(struct i2c_client *client,
 			     bin2bcd(tmp));
 	}
 
-	/*
-	 * Some IPs have weekday reset value = 0x1 which might not correct
-	 * hence compute the wday using the current date/month/year values
-	 */
-	ds1307_get_time(ds1307->dev, &tm);
-	wday = tm.tm_wday;
-	timestamp = rtc_tm_to_time64(&tm);
-	rtc_time64_to_tm(timestamp, &tm);
-
-	/*
-	 * Check if reset wday is different from the computed wday
-	 * If different then set the wday which we computed using
-	 * timestamp
-	 */
-	if (wday != tm.tm_wday)
-		regmap_update_bits(ds1307->regmap, MCP794XX_REG_WEEKDAY,
-				   MCP794XX_REG_WEEKDAY_WDAY_MASK,
-				   tm.tm_wday + 1);
-
 	if (want_irq || ds1307_can_wakeup_device) {
 		device_set_wakeup_capable(ds1307->dev, true);
 		set_bit(HAS_ALARM, &ds1307->flags);
-- 
2.14.1

^ permalink raw reply related

* Re: [rtc-linux] [PATCH 1/2] rtc: pcf2127: add support for pcf2127 watchdog functionality
From: Alexandre Belloni @ 2017-08-29 15:07 UTC (permalink / raw)
  To: Sean Nyekjaer; +Cc: rtc-linux
In-Reply-To: <20170120123644.118612-1-sean.nyekjaer@prevas.dk>

Hi Sean,

I know this patch is 7 months old but I never had the time to write a
proper reply.

This is using a pretty old API. Can you register a proper watchdog using
the watchdog subsystem (see drivers/watchdog)? Also, please copy the
watchdog maintainers.

I understand this will require a significant rewrite effort but the
final code will be quite cleaner.

On 20/01/2017 at 13:36:43 +0100, Sean Nyekjaer wrote:
> PCF2129 does not have watchdog functionality built-in so we
> are only allowing to enable watchdog for PCF2127.
> 
> Watchdog functionality is done with great inspiration from
> the rtc-ds1374 driver.
> 
> Signed-off-by: Sean Nyekjaer <sean.nyekjaer@prevas.dk>
> ---
>  drivers/rtc/Kconfig       |   7 ++
>  drivers/rtc/rtc-pcf2127.c | 174 +++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 180 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index e859d148aba9..c8985be81d83 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -799,6 +799,13 @@ config RTC_DRV_PCF2127
>  	  This driver can also be built as a module. If so, the module
>  	  will be called rtc-pcf2127.
>  
> +config RTC_DRV_PCF2127_WDT
> +	bool "NXP PCF2127 watchdog timer"
> +	depends on RTC_DRV_PCF2127
> +	help
> +	  If you say Y here you will get support for the
> +	  watchdog timer in the NXP PCF2127 chip real-time clock chips.
> +
>  config RTC_DRV_RV3029C2
>  	tristate "Micro Crystal RV3029/3049"
>  	depends on RTC_I2C_AND_SPI
> diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c
> index 2bfdf638b673..31627c59c44d 100644
> --- a/drivers/rtc/rtc-pcf2127.c
> +++ b/drivers/rtc/rtc-pcf2127.c
> @@ -21,6 +21,13 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/regmap.h>
> +#ifdef CONFIG_RTC_DRV_PCF2127_WDT
> +#include <linux/fs.h>
> +#include <linux/ioctl.h>
> +#include <linux/miscdevice.h>
> +#include <linux/reboot.h>
> +#include <linux/watchdog.h>
> +#endif
>  
>  #define PCF2127_REG_CTRL1       (0x00)  /* Control Register 1 */
>  #define PCF2127_REG_CTRL2       (0x01)  /* Control Register 2 */
> @@ -28,6 +35,13 @@
>  #define PCF2127_REG_CTRL3       (0x02)  /* Control Register 3 */
>  #define PCF2127_REG_CTRL3_BLF		BIT(2)
>  
> +#define PCF2127_REG_WDG_TIMCTL		(0x10)
> +#define PCF2127_REG_WDG_TIMCTL_CD	(BIT(7) | BIT(6))
> +#define PCF2127_REG_WDG_T_CD_EN_RST	(BIT(7) | BIT(6))	/* WD en,rst assert */
> +#define PCF2127_REG_WDG_TIMCTL_TF	(BIT(1) | BIT(0))
> +#define PCF2127_REG_WDG_T_TF_1HZ	BIT(1)	/* Timer clock source */
> +#define PCF2127_REG_WDG_TIMVAL		(0x11)
> +
>  #define PCF2127_REG_SC          (0x03)  /* datetime */
>  #define PCF2127_REG_MN          (0x04)
>  #define PCF2127_REG_HR          (0x05)
> @@ -43,6 +57,138 @@ struct pcf2127 {
>  	struct regmap *regmap;
>  };
>  
> +#ifdef CONFIG_RTC_DRV_PCF2127_WDT
> +static struct pcf2127 *save_pcf2127;
> +
> +/* default 32 sec timeout */
> +#define WD_TIMO 32
> +
> +static int wdt_margin = WD_TIMO;
> +
> +static const struct watchdog_info pcf2127_wdt_info = {
> +	.identity = "PCF2127 WDT",
> +	.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
> +};
> +
> +static int pcf2127_wdt_enable(void)
> +{
> +	return regmap_write(save_pcf2127->regmap, PCF2127_REG_WDG_TIMCTL,
> +			    PCF2127_REG_WDG_T_CD_EN_RST |
> +			    PCF2127_REG_WDG_T_TF_1HZ);
> +}
> +
> +static int pcf2127_wdt_settimeout(unsigned int timeout)
> +{
> +	int err;
> +
> +	err = pcf2127_wdt_enable();
> +	if (err)
> +		return err;
> +
> +	err = regmap_write(save_pcf2127->regmap, PCF2127_REG_WDG_TIMVAL,
> +			   timeout);
> +	if (err)
> +		return err;
> +
> +	return 0;
> +}
> +
> +static void pcf2127_wdt_ping(void)
> +{
> +	int ret = 0;
> +
> +	ret = pcf2127_wdt_settimeout(wdt_margin);
> +	if (ret)
> +		pr_info("WD TICK FAIL!!!!!!!!!! %i\n", ret);
> +}
> +
> +static int pcf2127_wdt_disable(void)
> +{
> +	return regmap_write_bits(save_pcf2127->regmap, PCF2127_REG_WDG_TIMCTL,
> +				 PCF2127_REG_WDG_TIMCTL_CD, 0x00);
> +}
> +
> +static long pcf2127_wdt_unlocked_ioctl(struct file *file, unsigned int cmd,
> +				       unsigned long arg)
> +{
> +	int new_margin, options;
> +
> +	switch (cmd) {
> +	case WDIOC_GETSUPPORT:
> +		return copy_to_user((struct watchdog_info __user *)arg,
> +				    &pcf2127_wdt_info,
> +				    sizeof(pcf2127_wdt_info)) ? -EFAULT : 0;
> +	case WDIOC_SETOPTIONS:
> +		if (copy_from_user(&options, (int __user *)arg, sizeof(int)))
> +			return -EFAULT;
> +
> +		if (options & WDIOS_DISABLECARD) {
> +			pr_info("disable watchdog\n");
> +			if (pcf2127_wdt_disable())
> +				return -EFAULT;
> +		}
> +
> +		if (options & WDIOS_ENABLECARD) {
> +			pr_info("enable watchdog\n");
> +			pcf2127_wdt_settimeout(wdt_margin);
> +			pcf2127_wdt_ping();
> +		}
> +
> +		return -EINVAL;
> +	case WDIOC_KEEPALIVE:
> +		pcf2127_wdt_ping();
> +		return 0;
> +	case WDIOC_SETTIMEOUT:
> +		if (get_user(new_margin, (int __user *)arg))
> +			return -EFAULT;
> +
> +		if (new_margin < 1 || new_margin > 255)
> +			return -EINVAL;
> +
> +		wdt_margin = new_margin;
> +		if (pcf2127_wdt_settimeout(new_margin))
> +			return -EFAULT;
> +		pcf2127_wdt_ping();
> +		/* fallthrough */
> +	case WDIOC_GETTIMEOUT:
> +		return put_user(wdt_margin, (int __user *)arg);
> +	default:
> +		return -ENOTTY;
> +	}
> +}
> +
> +static ssize_t pcf2127_wdt_write(struct file *file, const char *data,
> +				 size_t len, loff_t *ppos)
> +{
> +	if (len) {
> +		pcf2127_wdt_ping();
> +		return 1;
> +	}
> +	return 0;
> +}
> +
> +static ssize_t pcf2127_wdt_read(struct file *file, char __user *data,
> +				size_t len, loff_t *ppos)
> +{
> +	return 0;
> +}
> +
> +static const struct file_operations pcf2127_wdt_fops = {
> +	.owner = THIS_MODULE,
> +	.read = pcf2127_wdt_read,
> +	.unlocked_ioctl = pcf2127_wdt_unlocked_ioctl,
> +	.write = pcf2127_wdt_write,
> +	.llseek = no_llseek,
> +};
> +
> +static struct miscdevice pcf2127_wdt_miscdev = {
> +	.minor = WATCHDOG_MINOR,
> +	.name = "watchdog",
> +	.fops = &pcf2127_wdt_fops,
> +};
> +
> +#endif
> +
>  /*
>   * In the routines that deal directly with the pcf2127 hardware, we use
>   * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
> @@ -175,6 +321,9 @@ static const struct rtc_class_ops pcf2127_rtc_ops = {
>  static int pcf2127_probe(struct device *dev, struct regmap *regmap,
>  			const char *name)
>  {
> +#ifdef CONFIG_RTC_DRV_PCF2127_WDT
> +	int ret;
> +#endif
>  	struct pcf2127 *pcf2127;
>  
>  	dev_dbg(dev, "%s\n", __func__);
> @@ -183,6 +332,10 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
>  	if (!pcf2127)
>  		return -ENOMEM;
>  
> +#ifdef CONFIG_RTC_DRV_PCF2127_WDT
> +	save_pcf2127 = pcf2127;
> +#endif
> +
>  	pcf2127->regmap = regmap;
>  
>  	dev_set_drvdata(dev, pcf2127);
> @@ -190,7 +343,22 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
>  	pcf2127->rtc = devm_rtc_device_register(dev, name, &pcf2127_rtc_ops,
>  						THIS_MODULE);
>  
> -	return PTR_ERR_OR_ZERO(pcf2127->rtc);
> +	if (IS_ERR(pcf2127->rtc))
> +		return PTR_ERR_OR_ZERO(pcf2127->rtc);
> +
> +#ifdef CONFIG_RTC_DRV_PCF2127_WDT
> +	if (!of_device_is_compatible(dev->of_node, "nxp,pcf2127"))
> +		return 0;
> +
> +	if (of_property_read_bool(dev->of_node, "watchdog")) {
> +		ret = misc_register(&pcf2127_wdt_miscdev);
> +		if (ret)
> +			return ret;
> +	}
> +	pcf2127_wdt_settimeout(32);
> +#endif
> +
> +	return 0;
>  }
>  
>  #ifdef CONFIG_OF
> @@ -427,6 +595,10 @@ static void __exit pcf2127_exit(void)
>  {
>  	pcf2127_spi_unregister_driver();
>  	pcf2127_i2c_unregister_driver();
> +
> +#ifdef CONFIG_RTC_DRV_PCF2127_WDT
> +	misc_deregister(&pcf2127_wdt_miscdev);
> +#endif
>  }
>  module_exit(pcf2127_exit)
>  
> -- 
> 2.11.0
> 
> -- 
> You received this message because you are subscribed to "rtc-linux".
> Membership options at http://groups.google.com/group/rtc-linux .
> Please read http://groups.google.com/group/rtc-linux/web/checklist
> before submitting a driver.
> --- 
> You received this message because you are subscribed to the Google Groups "rtc-linux" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* Re: [PATCH] rtc: Use PTR_ERR_OR_ZERO
From: Himanshu Jha @ 2017-08-29 14:44 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: a.zummo, baruch, linux-rtc, linux-arm-kernel, linux-kernel
In-Reply-To: <20170829142011.76w67w64a7lheef4@piout.net>

On Tue, Aug 29, 2017 at 04:20:11PM +0200, Alexandre Belloni wrote:
> Hi,
> 
> On 29/08/2017 at 19:16:59 +0530, Himanshu Jha wrote:
> > Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
> > 
> 
> I'm not taking that kind of useless changes (especially since it make
> the code less readable) unless you have other significant improvement in
> those drivers.

Apologies!! I got this change accepted in staging, and didn't think
about it's readability.


Thanks


> 
> > Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com>
> > ---
> >  drivers/rtc/rtc-digicolor.c | 5 +----
> >  drivers/rtc/rtc-ds1347.c    | 5 +----
> >  2 files changed, 2 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/rtc/rtc-digicolor.c b/drivers/rtc/rtc-digicolor.c
> > index b253bf1..1e200a0 100644
> > --- a/drivers/rtc/rtc-digicolor.c
> > +++ b/drivers/rtc/rtc-digicolor.c
> > @@ -202,10 +202,7 @@ static int __init dc_rtc_probe(struct platform_device *pdev)
> >  	platform_set_drvdata(pdev, rtc);
> >  	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
> >  						&dc_rtc_ops, THIS_MODULE);
> > -	if (IS_ERR(rtc->rtc_dev))
> > -		return PTR_ERR(rtc->rtc_dev);
> > -
> > -	return 0;
> > +	return PTR_ERR_OR_ZERO(rtc->rtc_dev);
> >  }
> >  
> >  static const struct of_device_id dc_dt_ids[] = {
> > diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c
> > index ccfc9d4..9a02ca7 100644
> > --- a/drivers/rtc/rtc-ds1347.c
> > +++ b/drivers/rtc/rtc-ds1347.c
> > @@ -155,10 +155,7 @@ static int ds1347_probe(struct spi_device *spi)
> >  	rtc = devm_rtc_device_register(&spi->dev, "ds1347",
> >  				&ds1347_rtc_ops, THIS_MODULE);
> >  
> > -	if (IS_ERR(rtc))
> > -		return PTR_ERR(rtc);
> > -
> > -	return 0;
> > +	return PTR_ERR_OR_ZERO(rtc);
> >  }
> >  
> >  static struct spi_driver ds1347_driver = {
> > -- 
> > 2.7.4
> > 
> 
> -- 
> Alexandre Belloni, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

^ permalink raw reply

* [PATCH] rtc: remove cast to void pointer
From: Himanshu Jha @ 2017-08-29 14:39 UTC (permalink / raw)
  To: alexandre.belloni
  Cc: a.zummo, patrice.chotard, mcoquelin.stm32, maxime.ripard,
	michal.simek, linux-rtc, linux-kernel, linux-arm-kernel,
	Himanshu Jha

casting to void pointer from any pointer type and vice-versa is done
implicitly and therefore casting is not needed in such a case.

Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com>
---
 drivers/rtc/interface.c      | 4 ++--
 drivers/rtc/rtc-88pm80x.c    | 2 +-
 drivers/rtc/rtc-88pm860x.c   | 2 +-
 drivers/rtc/rtc-at32ap700x.c | 2 +-
 drivers/rtc/rtc-hym8563.c    | 2 +-
 drivers/rtc/rtc-m48t59.c     | 2 +-
 drivers/rtc/rtc-max8925.c    | 2 +-
 drivers/rtc/rtc-pic32.c      | 2 +-
 drivers/rtc/rtc-s3c.c        | 4 ++--
 drivers/rtc/rtc-st-lpc.c     | 2 +-
 drivers/rtc/rtc-stm32.c      | 2 +-
 drivers/rtc/rtc-sun6i.c      | 2 +-
 drivers/rtc/rtc-sunxi.c      | 2 +-
 drivers/rtc/rtc-vr41xx.c     | 4 ++--
 drivers/rtc/rtc-xgene.c      | 2 +-
 drivers/rtc/rtc-zynqmp.c     | 2 +-
 16 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 8cec9a0..81c85d2 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -528,7 +528,7 @@ void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
  */
 void rtc_aie_update_irq(void *private)
 {
-	struct rtc_device *rtc = (struct rtc_device *)private;
+	struct rtc_device *rtc = private;
 	rtc_handle_legacy_irq(rtc, 1, RTC_AF);
 }
 
@@ -541,7 +541,7 @@ void rtc_aie_update_irq(void *private)
  */
 void rtc_uie_update_irq(void *private)
 {
-	struct rtc_device *rtc = (struct rtc_device *)private;
+	struct rtc_device *rtc = private;
 	rtc_handle_legacy_irq(rtc, 1,  RTC_UF);
 }
 
diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c
index 466bf7f..819612e 100644
--- a/drivers/rtc/rtc-88pm80x.c
+++ b/drivers/rtc/rtc-88pm80x.c
@@ -60,7 +60,7 @@ struct pm80x_rtc_info {
 
 static irqreturn_t rtc_update_handler(int irq, void *data)
 {
-	struct pm80x_rtc_info *info = (struct pm80x_rtc_info *)data;
+	struct pm80x_rtc_info *info = data;
 	int mask;
 
 	mask = PM800_ALARM | PM800_ALARM_WAKEUP;
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index 19e53b3..67f7fa3 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -59,7 +59,7 @@ struct pm860x_rtc_info {
 
 static irqreturn_t rtc_update_handler(int irq, void *data)
 {
-	struct pm860x_rtc_info *info = (struct pm860x_rtc_info *)data;
+	struct pm860x_rtc_info *info = data;
 	int mask;
 
 	mask = ALARM | ALARM_WAKEUP;
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c
index de8bf56..f603f99 100644
--- a/drivers/rtc/rtc-at32ap700x.c
+++ b/drivers/rtc/rtc-at32ap700x.c
@@ -164,7 +164,7 @@ static int at32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id)
 {
-	struct rtc_at32ap700x *rtc = (struct rtc_at32ap700x *)dev_id;
+	struct rtc_at32ap700x *rtc = dev_id;
 	unsigned long isr = rtc_readl(rtc, ISR);
 	unsigned long events = 0;
 	int ret = IRQ_NONE;
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c
index e5ad527..0709968 100644
--- a/drivers/rtc/rtc-hym8563.c
+++ b/drivers/rtc/rtc-hym8563.c
@@ -436,7 +436,7 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563)
  */
 static irqreturn_t hym8563_irq(int irq, void *dev_id)
 {
-	struct hym8563 *hym8563 = (struct hym8563 *)dev_id;
+	struct hym8563 *hym8563 = dev_id;
 	struct i2c_client *client = hym8563->client;
 	struct mutex *lock = &hym8563->rtc->ops_lock;
 	int data, ret;
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index d99a705..2e35f73 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -302,7 +302,7 @@ static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq)
  */
 static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id)
 {
-	struct device *dev = (struct device *)dev_id;
+	struct device *dev = dev_id;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
 	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c
index 67d6fc2..45d7e40 100644
--- a/drivers/rtc/rtc-max8925.c
+++ b/drivers/rtc/rtc-max8925.c
@@ -74,7 +74,7 @@ struct max8925_rtc_info {
 
 static irqreturn_t rtc_update_handler(int irq, void *data)
 {
-	struct max8925_rtc_info *info = (struct max8925_rtc_info *)data;
+	struct max8925_rtc_info *info = data;
 
 	/* disable ALARM0 except for 1SEC alarm */
 	max8925_set_bits(info->rtc, MAX8925_ALARM0_CNTL, 0x7f, 0);
diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c
index 5cfb6df..04788c3 100644
--- a/drivers/rtc/rtc-pic32.c
+++ b/drivers/rtc/rtc-pic32.c
@@ -92,7 +92,7 @@ static void pic32_rtc_alarm_clk_enable(struct pic32_rtc_dev *pdata,
 
 static irqreturn_t pic32_rtc_alarmirq(int irq, void *id)
 {
-	struct pic32_rtc_dev *pdata = (struct pic32_rtc_dev *)id;
+	struct pic32_rtc_dev *pdata = id;
 
 	clk_enable(pdata->clk);
 	rtc_update_irq(pdata->rtc, 1, RTC_AF | RTC_IRQF);
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index a8992c2..8e8a815 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -113,7 +113,7 @@ static void s3c_rtc_disable_clk(struct s3c_rtc *info)
 /* IRQ Handlers */
 static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
 {
-	struct s3c_rtc *info = (struct s3c_rtc *)id;
+	struct s3c_rtc *info = id;
 
 	if (info->data->irq_handler)
 		info->data->irq_handler(info, S3C2410_INTP_TIC);
@@ -123,7 +123,7 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
 
 static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
 {
-	struct s3c_rtc *info = (struct s3c_rtc *)id;
+	struct s3c_rtc *info = id;
 
 	if (info->data->irq_handler)
 		info->data->irq_handler(info, S3C2410_INTP_ALM);
diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index 82b0af1..75eb92c 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -74,7 +74,7 @@ static void st_rtc_set_hw_alarm(struct st_rtc *rtc,
 
 static irqreturn_t st_rtc_handler(int this_irq, void *data)
 {
-	struct st_rtc *rtc = (struct st_rtc *)data;
+	struct st_rtc *rtc = data;
 
 	rtc_update_irq(rtc->rtc_dev, 1, RTC_AF);
 
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 3a5c3d7..66fc7ba 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -169,7 +169,7 @@ static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
 
 static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 {
-	struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
+	struct stm32_rtc *rtc = dev_id;
 	unsigned int isr, cr;
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 305c4d0..496a8dd 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -256,7 +256,7 @@ CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
 
 static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 {
-	struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
+	struct sun6i_rtc_dev *chip = id;
 	irqreturn_t ret = IRQ_NONE;
 	u32 val;
 
diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c
index abada60..f1f7fd7 100644
--- a/drivers/rtc/rtc-sunxi.c
+++ b/drivers/rtc/rtc-sunxi.c
@@ -158,7 +158,7 @@ struct sunxi_rtc_dev {
 
 static irqreturn_t sunxi_rtc_alarmirq(int irq, void *id)
 {
-	struct sunxi_rtc_dev *chip = (struct sunxi_rtc_dev *) id;
+	struct sunxi_rtc_dev *chip = id;
 	u32 val;
 
 	val = readl(chip->base + SUNXI_ALRM_IRQ_STA);
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index 7ce2296..a0aa377 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -228,7 +228,7 @@ static int vr41xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
 {
-	struct platform_device *pdev = (struct platform_device *)dev_id;
+	struct platform_device *pdev = dev_id;
 	struct rtc_device *rtc = platform_get_drvdata(pdev);
 
 	rtc2_write(RTCINTREG, ELAPSEDTIME_INT);
@@ -240,7 +240,7 @@ static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
 
 static irqreturn_t rtclong1_interrupt(int irq, void *dev_id)
 {
-	struct platform_device *pdev = (struct platform_device *)dev_id;
+	struct platform_device *pdev = dev_id;
 	struct rtc_device *rtc = platform_get_drvdata(pdev);
 	unsigned long count = periodic_count;
 
diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c
index 65b432a..2b8247d 100644
--- a/drivers/rtc/rtc-xgene.c
+++ b/drivers/rtc/rtc-xgene.c
@@ -131,7 +131,7 @@ static const struct rtc_class_ops xgene_rtc_ops = {
 
 static irqreturn_t xgene_rtc_interrupt(int irq, void *id)
 {
-	struct xgene_rtc_dev *pdata = (struct xgene_rtc_dev *) id;
+	struct xgene_rtc_dev *pdata = id;
 
 	/* Check if interrupt asserted */
 	if (!(readl(pdata->csr_base + RTC_STAT) & RTC_STAT_BIT))
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
index da18a8a..f2f8a2d 100644
--- a/drivers/rtc/rtc-zynqmp.c
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -193,7 +193,7 @@ static const struct rtc_class_ops xlnx_rtc_ops = {
 
 static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
 {
-	struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *)id;
+	struct xlnx_rtc_dev *xrtcdev = id;
 	unsigned int status;
 
 	status = readl(xrtcdev->reg_base + RTC_INT_STS);
-- 
2.7.4

^ permalink raw reply related


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