* Re: [v12, 7/8] base: soc: introduce soc_device_match() interface
From: Alexander Shiyan @ 2016-09-21 7:56 UTC (permalink / raw)
To: Yangbo Lu
Cc: Mark Rutland, ulf.hansson, Xiaobo Xie, Minghuan Lian, linux-i2c,
linux-clk, Qiang Zhao, Russell King, Bhupesh Sharma, Joerg Roedel,
Jochen Friedrich, Claudiu Manoil, devicetree, Arnd Bergmann,
Scott Wood, Rob Herring, Santosh Shilimkar, linux-arm-kernel,
netdev
In-Reply-To: <1474441040-11946-8-git-send-email-yangbo.lu@nxp.com>
>Среда, 21 сентября 2016, 9:57 +03:00 от Yangbo Lu <yangbo.lu@nxp.com>:
>
>From: Arnd Bergmann < arnd@arndb.de >
>
>We keep running into cases where device drivers want to know the exact
>version of the a SoC they are currently running on. In the past, this has
>usually been done through a vendor specific API that can be called by a
>driver, or by directly accessing some kind of version register that is
>not part of the device itself but that belongs to a global register area
>of the chip.
...
>+const struct soc_device_attribute *soc_device_match(
>+const struct soc_device_attribute *matches)
>+{
>+int ret = 0;
>+
>+if (!matches)
>+return NULL;
>+
>+while (!ret) {
>+if (!(matches->machine || matches->family ||
>+ matches->revision || matches->soc_id))
>+break;
>+ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches,
>+ soc_device_match_one);
>+if (!ret)
>+matches++;
So, what happen if next "matches" (after increment) will be NULL?
I think you should use while(matches) at the start of this procedure.
---
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [v12, 8/8] mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0
From: Yangbo Lu @ 2016-09-21 6:57 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Scott Wood, Arnd Bergmann
Cc: Mark Rutland, Xiaobo Xie, Minghuan Lian,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Jochen Friedrich, Claudiu Manoil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kumar Gala, Rob Herring,
Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
The eSDHC of T4240-R1.0-R2.0 has incorrect vender version and spec version.
Acturally the right version numbers should be VVN=0x13 and SVN = 0x1.
This patch adds the GUTS driver support for eSDHC driver to match SoC.
And fix host version to avoid that incorrect version numbers break down
the ADMA data transfer.
Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Acked-by: Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Acked-by: Scott Wood <oss-fOR+EgIDQEHk1uMJSBkQmQ@public.gmane.org>
---
Changes for v2:
- Got SVR through iomap instead of dts
Changes for v3:
- Managed GUTS through syscon instead of iomap in eSDHC driver
Changes for v4:
- Got SVR by GUTS driver instead of SYSCON
Changes for v5:
- Changed to get SVR through API fsl_guts_get_svr()
- Combined patch 4, patch 5 and patch 6 into one
Changes for v6:
- Added 'Acked-by: Ulf Hansson'
Changes for v7:
- None
Changes for v8:
- Added 'Acked-by: Scott Wood'
Changes for v9:
- None
Changes for v10:
- None
Changes for v11:
- Changed to use soc_device_match
Changes for v12:
- Matched soc through .family field instead of .soc_id
---
drivers/mmc/host/Kconfig | 1 +
drivers/mmc/host/sdhci-of-esdhc.c | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 5274f50..a1135a9 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -144,6 +144,7 @@ config MMC_SDHCI_OF_ESDHC
depends on MMC_SDHCI_PLTFM
depends on PPC || ARCH_MXC || ARCH_LAYERSCAPE
select MMC_SDHCI_IO_ACCESSORS
+ select FSL_GUTS
help
This selects the Freescale eSDHC controller support.
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index fb71c86..57bdb9e 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -18,6 +18,7 @@
#include <linux/of.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/sys_soc.h>
#include <linux/mmc/host.h>
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
@@ -28,6 +29,7 @@
struct sdhci_esdhc {
u8 vendor_ver;
u8 spec_ver;
+ bool quirk_incorrect_hostver;
};
/**
@@ -73,6 +75,8 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,
static u16 esdhc_readw_fixup(struct sdhci_host *host,
int spec_reg, u32 value)
{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
u16 ret;
int shift = (spec_reg & 0x2) * 8;
@@ -80,6 +84,12 @@ static u16 esdhc_readw_fixup(struct sdhci_host *host,
ret = value & 0xffff;
else
ret = (value >> shift) & 0xffff;
+ /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect
+ * vendor version and spec version information.
+ */
+ if ((spec_reg == SDHCI_HOST_VERSION) &&
+ (esdhc->quirk_incorrect_hostver))
+ ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200;
return ret;
}
@@ -558,6 +568,12 @@ static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = {
.ops = &sdhci_esdhc_le_ops,
};
+static struct soc_device_attribute soc_incorrect_hostver[] = {
+ { .family = "QorIQ T4240", .revision = "1.0", },
+ { .family = "QorIQ T4240", .revision = "2.0", },
+ { },
+};
+
static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host;
@@ -571,6 +587,10 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >>
SDHCI_VENDOR_VER_SHIFT;
esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK;
+ if (soc_device_match(soc_incorrect_hostver))
+ esdhc->quirk_incorrect_hostver = true;
+ else
+ esdhc->quirk_incorrect_hostver = false;
}
static int sdhci_esdhc_probe(struct platform_device *pdev)
--
2.1.0.27.g96db324
^ permalink raw reply related
* [v12, 7/8] base: soc: introduce soc_device_match() interface
From: Yangbo Lu @ 2016-09-21 6:57 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Scott Wood, Arnd Bergmann
Cc: Mark Rutland, Xiaobo Xie, Minghuan Lian,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Jochen Friedrich, Claudiu Manoil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kumar Gala, Rob Herring,
Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
From: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
We keep running into cases where device drivers want to know the exact
version of the a SoC they are currently running on. In the past, this has
usually been done through a vendor specific API that can be called by a
driver, or by directly accessing some kind of version register that is
not part of the device itself but that belongs to a global register area
of the chip.
Common reasons for doing this include:
- A machine is not using devicetree or similar for passing data about
on-chip devices, but just announces their presence using boot-time
platform devices, and the machine code itself does not care about the
revision.
- There is existing firmware or boot loaders with existing DT binaries
with generic compatible strings that do not identify the particular
revision of each device, but the driver knows which SoC revisions
include which part.
- A prerelease version of a chip has some quirks and we are using the same
version of the bootloader and the DT blob on both the prerelease and the
final version. An update of the DT binding seems inappropriate because
that would involve maintaining multiple copies of the dts and/or
bootloader.
This patch introduces the soc_device_match() interface that is meant to
work like of_match_node() but instead of identifying the version of a
device, it identifies the SoC itself using a vendor-agnostic interface.
Unlike of_match_node(), we do not do an exact string compare but instead
use glob_match() to allow wildcards in strings.
Signed-off-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
---
Changes for v11:
- Added this patch for soc match
Changes for v12:
- Corrected the author
- Rewrited soc_device_match with while loop
---
drivers/base/Kconfig | 1 +
drivers/base/soc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/sys_soc.h | 3 +++
3 files changed, 70 insertions(+)
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 98504ec..f1591ad2 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -225,6 +225,7 @@ config GENERIC_CPU_AUTOPROBE
config SOC_BUS
bool
+ select GLOB
source "drivers/base/regmap/Kconfig"
diff --git a/drivers/base/soc.c b/drivers/base/soc.c
index 75b98aa..d2fd1ad 100644
--- a/drivers/base/soc.c
+++ b/drivers/base/soc.c
@@ -14,6 +14,7 @@
#include <linux/spinlock.h>
#include <linux/sys_soc.h>
#include <linux/err.h>
+#include <linux/glob.h>
static DEFINE_IDA(soc_ida);
@@ -168,3 +169,68 @@ static void __exit soc_bus_unregister(void)
bus_unregister(&soc_bus_type);
}
module_exit(soc_bus_unregister);
+
+static int soc_device_match_one(struct device *dev, void *arg)
+{
+ struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
+ const struct soc_device_attribute *match = arg;
+
+ if (match->machine &&
+ !glob_match(match->machine, soc_dev->attr->machine))
+ return 0;
+
+ if (match->family &&
+ !glob_match(match->family, soc_dev->attr->family))
+ return 0;
+
+ if (match->revision &&
+ !glob_match(match->revision, soc_dev->attr->revision))
+ return 0;
+
+ if (match->soc_id &&
+ !glob_match(match->soc_id, soc_dev->attr->soc_id))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * soc_device_match - identify the SoC in the machine
+ * @matches: zero-terminated array of possible matches
+ *
+ * returns the first matching entry of the argument array, or NULL
+ * if none of them match.
+ *
+ * This function is meant as a helper in place of of_match_node()
+ * in cases where either no device tree is available or the information
+ * in a device node is insufficient to identify a particular variant
+ * by its compatible strings or other properties. For new devices,
+ * the DT binding should always provide unique compatible strings
+ * that allow the use of of_match_node() instead.
+ *
+ * The calling function can use the .data entry of the
+ * soc_device_attribute to pass a structure or function pointer for
+ * each entry.
+ */
+const struct soc_device_attribute *soc_device_match(
+ const struct soc_device_attribute *matches)
+{
+ int ret = 0;
+
+ if (!matches)
+ return NULL;
+
+ while (!ret) {
+ if (!(matches->machine || matches->family ||
+ matches->revision || matches->soc_id))
+ break;
+ ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches,
+ soc_device_match_one);
+ if (!ret)
+ matches++;
+ else
+ return matches;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(soc_device_match);
diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h
index 2739ccb..9f5eb06 100644
--- a/include/linux/sys_soc.h
+++ b/include/linux/sys_soc.h
@@ -13,6 +13,7 @@ struct soc_device_attribute {
const char *family;
const char *revision;
const char *soc_id;
+ const void *data;
};
/**
@@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_device *soc_dev);
*/
struct device *soc_device_to_device(struct soc_device *soc);
+const struct soc_device_attribute *soc_device_match(
+ const struct soc_device_attribute *matches);
#endif /* __SOC_BUS_H */
--
2.1.0.27.g96db324
^ permalink raw reply related
* [v12, 6/8] MAINTAINERS: add entry for Freescale SoC drivers
From: Yangbo Lu @ 2016-09-21 6:57 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Scott Wood, Arnd Bergmann
Cc: Mark Rutland, Xiaobo Xie, Minghuan Lian,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Jochen Friedrich, Claudiu Manoil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kumar Gala, Rob Herring,
Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Add maintainer entry for Freescale SoC drivers including
the QE library and the GUTS driver now. Also add maintainer
for QE library.
Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Acked-by: Scott Wood <oss-fOR+EgIDQEHk1uMJSBkQmQ@public.gmane.org>
Acked-by: Qiang Zhao <qiang.zhao-3arQi8VN3Tc@public.gmane.org>
---
Changes for v8:
- Added this patch
Changes for v9:
- Added linux-arm mail list
- Removed GUTS driver entry
Changes for v10:
- Changed 'DRIVER' to 'DRIVERS'
- Added 'Acked-by' of Scott and Qiang
Changes for v11:
- None
Changes for v12:
- None
---
MAINTAINERS | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 644ff65..33d3683 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4971,9 +4971,18 @@ F: drivers/net/ethernet/freescale/fec_ptp.c
F: drivers/net/ethernet/freescale/fec.h
F: Documentation/devicetree/bindings/net/fsl-fec.txt
+FREESCALE SOC DRIVERS
+M: Scott Wood <oss-fOR+EgIDQEHk1uMJSBkQmQ@public.gmane.org>
+L: linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
+L: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
+S: Maintained
+F: drivers/soc/fsl/
+F: include/linux/fsl/
+
FREESCALE QUICC ENGINE LIBRARY
+M: Qiang Zhao <qiang.zhao-3arQi8VN3Tc@public.gmane.org>
L: linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
-S: Orphan
+S: Maintained
F: drivers/soc/fsl/qe/
F: include/soc/fsl/*qe*.h
F: include/soc/fsl/*ucc*.h
--
2.1.0.27.g96db324
^ permalink raw reply related
* [v12, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
From: Yangbo Lu @ 2016-09-21 6:57 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Scott Wood, Arnd Bergmann
Cc: Mark Rutland, Xiaobo Xie, Minghuan Lian,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Jochen Friedrich, Claudiu Manoil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kumar Gala, Rob Herring,
Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
The global utilities block controls power management, I/O device
enabling, power-onreset(POR) configuration monitoring, alternate
function selection for multiplexed signals,and clock control.
This patch adds a driver to manage and access global utilities block.
Initially only reading SVR and registering soc device are supported.
Other guts accesses, such as reading RCW, should eventually be moved
into this driver as well.
Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
---
Changes for v4:
- Added this patch
Changes for v5:
- Modified copyright info
- Changed MODULE_LICENSE to GPL
- Changed EXPORT_SYMBOL_GPL to EXPORT_SYMBOL
- Made FSL_GUTS user-invisible
- Added a complete compatible list for GUTS
- Stored guts info in file-scope variable
- Added mfspr() getting SVR
- Redefined GUTS APIs
- Called fsl_guts_init rather than using platform driver
- Removed useless parentheses
- Removed useless 'extern' key words
Changes for v6:
- Made guts thread safe in fsl_guts_init
Changes for v7:
- Removed 'ifdef' for function declaration in guts.h
Changes for v8:
- Fixes lines longer than 80 characters checkpatch issue
- Added 'Acked-by: Scott Wood'
Changes for v9:
- None
Changes for v10:
- None
Changes for v11:
- Changed to platform driver
Changes for v12:
- Removed "signed-off-by: Scott"
- Defined fsl_soc_die_attr struct array instead of
soc_device_attribute
- Re-designed soc_device_attribute for QorIQ SoC
- Other minor fixes
---
drivers/soc/Kconfig | 2 +-
drivers/soc/fsl/Kconfig | 19 ++++
drivers/soc/fsl/Makefile | 1 +
drivers/soc/fsl/guts.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fsl/guts.h | 125 ++++++++++++++---------
5 files changed, 355 insertions(+), 49 deletions(-)
create mode 100644 drivers/soc/fsl/Kconfig
create mode 100644 drivers/soc/fsl/guts.c
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index fe42a2f..f31bceb 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,7 +1,7 @@
menu "SOC (System On Chip) specific Drivers"
source "drivers/soc/bcm/Kconfig"
-source "drivers/soc/fsl/qe/Kconfig"
+source "drivers/soc/fsl/Kconfig"
source "drivers/soc/mediatek/Kconfig"
source "drivers/soc/qcom/Kconfig"
source "drivers/soc/rockchip/Kconfig"
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 0000000..b99764c
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,19 @@
+#
+# Freescale SOC drivers
+#
+
+source "drivers/soc/fsl/qe/Kconfig"
+
+config FSL_GUTS
+ bool "Freescale QorIQ GUTS driver"
+ select SOC_BUS
+ help
+ The global utilities block controls power management, I/O device
+ enabling, power-onreset(POR) configuration monitoring, alternate
+ function selection for multiplexed signals,and clock control.
+ This driver is to manage and access global utilities block.
+ Initially only reading SVR and registering soc device are supported.
+ Other guts accesses, such as reading RCW, should eventually be moved
+ into this driver as well.
+
+ If you want GUTS driver support, you should say Y here.
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 203307f..02afb7f 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -4,3 +4,4 @@
obj-$(CONFIG_QUICC_ENGINE) += qe/
obj-$(CONFIG_CPM) += qe/
+obj-$(CONFIG_FSL_GUTS) += guts.o
diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
new file mode 100644
index 0000000..2a0e52c
--- /dev/null
+++ b/drivers/soc/fsl/guts.c
@@ -0,0 +1,257 @@
+/*
+ * Freescale QorIQ Platforms GUTS Driver
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/sys_soc.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/fsl/guts.h>
+#include <linux/fsl/svr.h>
+
+struct guts {
+ struct ccsr_guts __iomem *regs;
+ bool little_endian;
+};
+
+struct fsl_soc_die_attr {
+ char *die;
+ u32 svr;
+ u32 mask;
+};
+
+static struct guts *guts;
+static struct soc_device_attribute soc_dev_attr;
+static struct soc_device *soc_dev;
+
+
+/* SoC die attribute definition for QorIQ platform */
+static const struct fsl_soc_die_attr fsl_soc_die[] = {
+#ifdef CONFIG_PPC
+ /*
+ * Power Architecture-based SoCs T Series
+ */
+
+ /* Die: T4240, SoC: T4240/T4160/T4080 */
+ { .die = "T4240",
+ .svr = 0x82400000,
+ .mask = 0xfff00000,
+ },
+ /* Die: T1040, SoC: T1040/T1020/T1042/T1022 */
+ { .die = "T1040",
+ .svr = 0x85200000,
+ .mask = 0xfff00000,
+ },
+ /* Die: T2080, SoC: T2080/T2081 */
+ { .die = "T2080",
+ .svr = 0x85300000,
+ .mask = 0xfff00000,
+ },
+ /* Die: T1024, SoC: T1024/T1014/T1023/T1013 */
+ { .die = "T1024",
+ .svr = 0x85400000,
+ .mask = 0xfff00000,
+ },
+#endif /* CONFIG_PPC */
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_ARCH_LAYERSCAPE)
+ /*
+ * ARM-based SoCs LS Series
+ */
+
+ /* Die: LS1043A, SoC: LS1043A/LS1023A */
+ { .die = "LS1043A",
+ .svr = 0x87920000,
+ .mask = 0xffff0000,
+ },
+ /* Die: LS2080A, SoC: LS2080A/LS2040A/LS2085A */
+ { .die = "LS2080A",
+ .svr = 0x87010000,
+ .mask = 0xff3f0000,
+ },
+ /* Die: LS1088A, SoC: LS1088A/LS1048A/LS1084A/LS1044A */
+ { .die = "LS1088A",
+ .svr = 0x87030000,
+ .mask = 0xff3f0000,
+ },
+ /* Die: LS1012A, SoC: LS1012A */
+ { .die = "LS1012A",
+ .svr = 0x87040000,
+ .mask = 0xffff0000,
+ },
+ /* Die: LS1046A, SoC: LS1046A/LS1026A */
+ { .die = "LS1046A",
+ .svr = 0x87070000,
+ .mask = 0xffff0000,
+ },
+ /* Die: LS2088A, SoC: LS2088A/LS2048A/LS2084A/LS2044A */
+ { .die = "LS2088A",
+ .svr = 0x87090000,
+ .mask = 0xff3f0000,
+ },
+ /* Die: LS1021A, SoC: LS1021A/LS1020A/LS1022A
+ * Note: Put this die at the end in cause of incorrect identification
+ */
+ { .die = "LS1021A",
+ .svr = 0x87000000,
+ .mask = 0xfff00000,
+ },
+#endif /* CONFIG_ARCH_MXC || CONFIG_ARCH_LAYERSCAPE */
+ { },
+};
+
+static const struct fsl_soc_die_attr *fsl_soc_die_match(
+ u32 svr, const struct fsl_soc_die_attr *matches)
+{
+ while (matches->svr) {
+ if (matches->svr == (svr & matches->mask))
+ return matches;
+ matches++;
+ };
+ return NULL;
+}
+
+u32 fsl_guts_get_svr(void)
+{
+ u32 svr = 0;
+
+ if (!guts || !guts->regs)
+ return svr;
+
+ if (guts->little_endian)
+ svr = ioread32(&guts->regs->svr);
+ else
+ svr = ioread32be(&guts->regs->svr);
+
+ return svr;
+}
+EXPORT_SYMBOL(fsl_guts_get_svr);
+
+static int fsl_guts_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ const struct fsl_soc_die_attr *soc_die;
+ const char *machine;
+ u32 svr;
+ int ret = 0;
+
+ /* Initialize guts */
+ guts = kzalloc(sizeof(*guts), GFP_KERNEL);
+ if (!guts)
+ return -ENOMEM;
+
+ guts->little_endian = of_property_read_bool(np, "little-endian");
+
+ guts->regs = of_iomap(np, 0);
+ if (!guts->regs) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+
+ /* Register soc device */
+ machine = of_flat_dt_get_machine_name();
+ if (machine)
+ soc_dev_attr.machine = kstrdup(machine, GFP_KERNEL);
+
+ svr = fsl_guts_get_svr();
+ soc_die = fsl_soc_die_match(svr, fsl_soc_die);
+ if (soc_die) {
+ soc_dev_attr.family = kasprintf(GFP_KERNEL, "QorIQ %s",
+ soc_die->die);
+ } else {
+ soc_dev_attr.family = kasprintf(GFP_KERNEL, "QorIQ");
+ }
+ soc_dev_attr.soc_id = kasprintf(GFP_KERNEL, "svr:0x%08x", svr);
+ soc_dev_attr.revision = kasprintf(GFP_KERNEL, "%d.%d",
+ SVR_MAJ(svr), SVR_MIN(svr));
+
+ soc_dev = soc_device_register(&soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ ret = PTR_ERR(soc_dev);
+ goto out;
+ }
+ pr_info("Machine: %s\n", soc_dev_attr.machine);
+ pr_info("SoC family: %s\n", soc_dev_attr.family);
+ pr_info("SoC ID: %s, Revision: %s\n",
+ soc_dev_attr.soc_id, soc_dev_attr.revision);
+ return 0;
+out:
+ kfree(soc_dev_attr.machine);
+ kfree(soc_dev_attr.family);
+ kfree(soc_dev_attr.soc_id);
+ kfree(soc_dev_attr.revision);
+ iounmap(guts->regs);
+out_free:
+ kfree(guts);
+ return ret;
+}
+
+static int fsl_guts_remove(struct platform_device *dev)
+{
+ soc_device_unregister(soc_dev);
+ kfree(soc_dev_attr.machine);
+ kfree(soc_dev_attr.family);
+ kfree(soc_dev_attr.soc_id);
+ kfree(soc_dev_attr.revision);
+ iounmap(guts->regs);
+ kfree(guts);
+ return 0;
+}
+
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Freescale QorIQ SOCs.
+ */
+static const struct of_device_id fsl_guts_of_match[] = {
+ { .compatible = "fsl,qoriq-device-config-1.0", },
+ { .compatible = "fsl,qoriq-device-config-2.0", },
+ { .compatible = "fsl,p1010-guts", },
+ { .compatible = "fsl,p1020-guts", },
+ { .compatible = "fsl,p1021-guts", },
+ { .compatible = "fsl,p1022-guts", },
+ { .compatible = "fsl,p1023-guts", },
+ { .compatible = "fsl,p2020-guts", },
+ { .compatible = "fsl,bsc9131-guts", },
+ { .compatible = "fsl,bsc9132-guts", },
+ { .compatible = "fsl,mpc8536-guts", },
+ { .compatible = "fsl,mpc8544-guts", },
+ { .compatible = "fsl,mpc8548-guts", },
+ { .compatible = "fsl,mpc8568-guts", },
+ { .compatible = "fsl,mpc8569-guts", },
+ { .compatible = "fsl,mpc8572-guts", },
+ { .compatible = "fsl,ls1021a-dcfg", },
+ { .compatible = "fsl,ls1043a-dcfg", },
+ { .compatible = "fsl,ls2080a-dcfg", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_guts_of_match);
+
+static struct platform_driver fsl_guts_driver = {
+ .driver = {
+ .name = "fsl-guts",
+ .of_match_table = fsl_guts_of_match,
+ },
+ .probe = fsl_guts_probe,
+ .remove = fsl_guts_remove,
+};
+
+static int __init fsl_guts_init(void)
+{
+ return platform_driver_register(&fsl_guts_driver);
+}
+core_initcall(fsl_guts_init);
+
+static void __exit fsl_guts_exit(void)
+{
+ platform_driver_unregister(&fsl_guts_driver);
+}
+module_exit(fsl_guts_exit);
diff --git a/include/linux/fsl/guts.h b/include/linux/fsl/guts.h
index 649e917..3efa3b8 100644
--- a/include/linux/fsl/guts.h
+++ b/include/linux/fsl/guts.h
@@ -29,83 +29,112 @@
* #ifdefs.
*/
struct ccsr_guts {
- __be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
- __be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
- __be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */
- __be32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
- __be32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
- __be32 pordevsr2; /* 0x.0014 - POR device status register 2 */
+ u32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
+ u32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
+ u32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and
+ * Control Register
+ */
+ u32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
+ u32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
+ u32 pordevsr2; /* 0x.0014 - POR device status register 2 */
u8 res018[0x20 - 0x18];
- __be32 porcir; /* 0x.0020 - POR Configuration Information Register */
+ u32 porcir; /* 0x.0020 - POR Configuration Information
+ * Register
+ */
u8 res024[0x30 - 0x24];
- __be32 gpiocr; /* 0x.0030 - GPIO Control Register */
+ u32 gpiocr; /* 0x.0030 - GPIO Control Register */
u8 res034[0x40 - 0x34];
- __be32 gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */
+ u32 gpoutdr; /* 0x.0040 - General-Purpose Output Data
+ * Register
+ */
u8 res044[0x50 - 0x44];
- __be32 gpindr; /* 0x.0050 - General-Purpose Input Data Register */
+ u32 gpindr; /* 0x.0050 - General-Purpose Input Data
+ * Register
+ */
u8 res054[0x60 - 0x54];
- __be32 pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */
- __be32 pmuxcr2; /* 0x.0064 - Alternate function signal multiplex control 2 */
- __be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
+ u32 pmuxcr; /* 0x.0060 - Alternate Function Signal
+ * Multiplex Control
+ */
+ u32 pmuxcr2; /* 0x.0064 - Alternate function signal
+ * multiplex control 2
+ */
+ u32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
u8 res06c[0x70 - 0x6c];
- __be32 devdisr; /* 0x.0070 - Device Disable Control */
+ u32 devdisr; /* 0x.0070 - Device Disable Control */
#define CCSR_GUTS_DEVDISR_TB1 0x00001000
#define CCSR_GUTS_DEVDISR_TB0 0x00004000
- __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
+ u32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
u8 res078[0x7c - 0x78];
- __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */
- __be32 powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */
- __be32 pmrccr; /* 0x.0084 - Power Management Reset Counter Configuration Register */
- __be32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter Configuration Register */
- __be32 pmcdr; /* 0x.008c - 4Power management clock disable register */
- __be32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
- __be32 rstrscr; /* 0x.0094 - Reset Request Status and Control Register */
- __be32 ectrstcr; /* 0x.0098 - Exception reset control register */
- __be32 autorstsr; /* 0x.009c - Automatic reset status register */
- __be32 pvr; /* 0x.00a0 - Processor Version Register */
- __be32 svr; /* 0x.00a4 - System Version Register */
+ u32 pmjcr; /* 0x.007c - 4 Power Management Jog Control
+ * Register
+ */
+ u32 powmgtcsr; /* 0x.0080 - Power Management Status and
+ * Control Register
+ */
+ u32 pmrccr; /* 0x.0084 - Power Management Reset Counter
+ * Configuration Register
+ */
+ u32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter
+ * Configuration Register
+ */
+ u32 pmcdr; /* 0x.008c - 4Power management clock disable
+ * register
+ */
+ u32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
+ u32 rstrscr; /* 0x.0094 - Reset Request Status and
+ * Control Register
+ */
+ u32 ectrstcr; /* 0x.0098 - Exception reset control register */
+ u32 autorstsr; /* 0x.009c - Automatic reset status register */
+ u32 pvr; /* 0x.00a0 - Processor Version Register */
+ u32 svr; /* 0x.00a4 - System Version Register */
u8 res0a8[0xb0 - 0xa8];
- __be32 rstcr; /* 0x.00b0 - Reset Control Register */
+ u32 rstcr; /* 0x.00b0 - Reset Control Register */
u8 res0b4[0xc0 - 0xb4];
- __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register
+ u32 iovselsr; /* 0x.00c0 - I/O voltage select status register
Called 'elbcvselcr' on 86xx SOCs */
u8 res0c4[0x100 - 0xc4];
- __be32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
+ u32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
There are 16 registers */
u8 res140[0x224 - 0x140];
- __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */
- __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */
+ u32 iodelay1; /* 0x.0224 - IO delay control register 1 */
+ u32 iodelay2; /* 0x.0228 - IO delay control register 2 */
u8 res22c[0x604 - 0x22c];
- __be32 pamubypenr; /* 0x.604 - PAMU bypass enable register */
+ u32 pamubypenr; /* 0x.604 - PAMU bypass enable register */
u8 res608[0x800 - 0x608];
- __be32 clkdvdr; /* 0x.0800 - Clock Divide Register */
+ u32 clkdvdr; /* 0x.0800 - Clock Divide Register */
u8 res804[0x900 - 0x804];
- __be32 ircr; /* 0x.0900 - Infrared Control Register */
+ u32 ircr; /* 0x.0900 - Infrared Control Register */
u8 res904[0x908 - 0x904];
- __be32 dmacr; /* 0x.0908 - DMA Control Register */
+ u32 dmacr; /* 0x.0908 - DMA Control Register */
u8 res90c[0x914 - 0x90c];
- __be32 elbccr; /* 0x.0914 - eLBC Control Register */
+ u32 elbccr; /* 0x.0914 - eLBC Control Register */
u8 res918[0xb20 - 0x918];
- __be32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */
- __be32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */
- __be32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */
+ u32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */
+ u32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */
+ u32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */
u8 resb2c[0xe00 - 0xb2c];
- __be32 clkocr; /* 0x.0e00 - Clock Out Select Register */
+ u32 clkocr; /* 0x.0e00 - Clock Out Select Register */
u8 rese04[0xe10 - 0xe04];
- __be32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
+ u32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
u8 rese14[0xe20 - 0xe14];
- __be32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
- __be32 cpfor; /* 0x.0e24 - L2 charge pump fuse override register */
+ u32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
+ u32 cpfor; /* 0x.0e24 - L2 charge pump fuse override
+ * register
+ */
u8 rese28[0xf04 - 0xe28];
- __be32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
- __be32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
+ u32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
+ u32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
u8 resf0c[0xf2c - 0xf0c];
- __be32 itcr; /* 0x.0f2c - Internal transaction control register */
+ u32 itcr; /* 0x.0f2c - Internal transaction control
+ * register
+ */
u8 resf30[0xf40 - 0xf30];
- __be32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */
- __be32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
+ u32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */
+ u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
} __attribute__ ((packed));
+u32 fsl_guts_get_svr(void);
/* Alternate function signal multiplex control */
#define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))
--
2.1.0.27.g96db324
^ permalink raw reply related
* [v12, 4/8] powerpc/fsl: move mpc85xx.h to include/linux/fsl
From: Yangbo Lu @ 2016-09-21 6:57 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Scott Wood, Arnd Bergmann
Cc: Mark Rutland, Xiaobo Xie, Minghuan Lian,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Jochen Friedrich, Claudiu Manoil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kumar Gala, Rob Herring,
Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Move mpc85xx.h to include/linux/fsl and rename it to svr.h as a common
header file. This SVR numberspace is used on some ARM chips as well as
PPC, and even to check for a PPC SVR multi-arch drivers would otherwise
need to ifdef the header inclusion and all references to the SVR symbols.
Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Acked-by: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
Acked-by: Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Acked-by: Joerg Roedel <jroedel-l3A5Bk7waGM@public.gmane.org>
[scottwood: update description]
Signed-off-by: Scott Wood <oss-fOR+EgIDQEHk1uMJSBkQmQ@public.gmane.org>
---
Changes for v2:
- None
Changes for v3:
- None
Changes for v4:
- None
Changes for v5:
- Changed to Move mpc85xx.h to include/linux/fsl/
- Adjusted '#include <linux/fsl/svr.h>' position in file
Changes for v6:
- None
Changes for v7:
- Added 'Acked-by: Wolfram Sang' for I2C part
- Also applied to arch/powerpc/kernel/cpu_setup_fsl_booke.S
Changes for v8:
- Added 'Acked-by: Stephen Boyd' for clk part
- Added 'Acked-by: Scott Wood'
- Added 'Acked-by: Joerg Roedel' for iommu part
Changes for v9:
- None
Changes for v10:
- None
Changes for v11:
- Updated description by Scott
Changes for v12:
- None
---
arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +-
arch/powerpc/sysdev/fsl_pci.c | 2 +-
drivers/clk/clk-qoriq.c | 3 +--
drivers/i2c/busses/i2c-mpc.c | 2 +-
drivers/iommu/fsl_pamu.c | 3 +--
drivers/net/ethernet/freescale/gianfar.c | 2 +-
arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h | 4 ++--
7 files changed, 8 insertions(+), 10 deletions(-)
rename arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h (97%)
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 462aed9..2b0284e 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -13,13 +13,13 @@
*
*/
+#include <linux/fsl/svr.h>
#include <asm/page.h>
#include <asm/processor.h>
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
#include <asm/mmu-book3e.h>
#include <asm/asm-offsets.h>
-#include <asm/mpc85xx.h>
_GLOBAL(__e500_icache_setup)
mfspr r0, SPRN_L1CSR1
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 0ef9df4..0fd1895 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/fsl/edac.h>
+#include <linux/fsl/svr.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/memblock.h>
@@ -37,7 +38,6 @@
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>
#include <asm/machdep.h>
-#include <asm/mpc85xx.h>
#include <asm/disassemble.h>
#include <asm/ppc-opcode.h>
#include <sysdev/fsl_soc.h>
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 58566a17..4b6c438 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/fsl/guts.h>
+#include <linux/fsl/svr.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -1149,8 +1150,6 @@ bad_args:
}
#ifdef CONFIG_PPC
-#include <asm/mpc85xx.h>
-
static const u32 a4510_svrs[] __initconst = {
(SVR_P2040 << 8) | 0x10, /* P2040 1.0 */
(SVR_P2040 << 8) | 0x11, /* P2040 1.1 */
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 48ecffe..600704c 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -27,9 +27,9 @@
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/fsl/svr.h>
#include <asm/mpc52xx.h>
-#include <asm/mpc85xx.h>
#include <sysdev/fsl_soc.h>
#define DRV_NAME "mpc-i2c"
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
index a34355f..af8fb27 100644
--- a/drivers/iommu/fsl_pamu.c
+++ b/drivers/iommu/fsl_pamu.c
@@ -21,11 +21,10 @@
#include "fsl_pamu.h"
#include <linux/fsl/guts.h>
+#include <linux/fsl/svr.h>
#include <linux/interrupt.h>
#include <linux/genalloc.h>
-#include <asm/mpc85xx.h>
-
/* define indexes for each operation mapping scenario */
#define OMI_QMAN 0x00
#define OMI_FMAN 0x01
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 4b4f5bc..55be5ce 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -86,11 +86,11 @@
#include <linux/udp.h>
#include <linux/in.h>
#include <linux/net_tstamp.h>
+#include <linux/fsl/svr.h>
#include <asm/io.h>
#ifdef CONFIG_PPC
#include <asm/reg.h>
-#include <asm/mpc85xx.h>
#endif
#include <asm/irq.h>
#include <asm/uaccess.h>
diff --git a/arch/powerpc/include/asm/mpc85xx.h b/include/linux/fsl/svr.h
similarity index 97%
rename from arch/powerpc/include/asm/mpc85xx.h
rename to include/linux/fsl/svr.h
index 213f3a8..8d13836 100644
--- a/arch/powerpc/include/asm/mpc85xx.h
+++ b/include/linux/fsl/svr.h
@@ -9,8 +9,8 @@
* (at your option) any later version.
*/
-#ifndef __ASM_PPC_MPC85XX_H
-#define __ASM_PPC_MPC85XX_H
+#ifndef FSL_SVR_H
+#define FSL_SVR_H
#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */
#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/
--
2.1.0.27.g96db324
^ permalink raw reply related
* [v12, 3/8] dt: bindings: move guts devicetree doc out of powerpc directory
From: Yangbo Lu @ 2016-09-21 6:57 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Scott Wood, Arnd Bergmann
Cc: Mark Rutland, Xiaobo Xie, Minghuan Lian,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Jochen Friedrich, Claudiu Manoil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kumar Gala, Rob Herring,
Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Move guts devicetree doc to Documentation/devicetree/bindings/soc/fsl/
since it's used by not only PowerPC but also ARM. And add a specification
for 'little-endian' property.
Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Acked-by: Scott Wood <oss-fOR+EgIDQEHk1uMJSBkQmQ@public.gmane.org>
---
Changes for v4:
- Added this patch
Changes for v5:
- Modified the description for little-endian property
Changes for v6:
- None
Changes for v7:
- None
Changes for v8:
- Added 'Acked-by: Scott Wood'
- Added 'Acked-by: Rob Herring'
Changes for v9:
- None
Changes for v10:
- None
Changes for v11:
- None
Changes for v12:
- None
---
Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt | 3 +++
1 file changed, 3 insertions(+)
rename Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt (91%)
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/guts.txt b/Documentation/devicetree/bindings/soc/fsl/guts.txt
similarity index 91%
rename from Documentation/devicetree/bindings/powerpc/fsl/guts.txt
rename to Documentation/devicetree/bindings/soc/fsl/guts.txt
index b71b203..07adca9 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/guts.txt
+++ b/Documentation/devicetree/bindings/soc/fsl/guts.txt
@@ -25,6 +25,9 @@ Recommended properties:
- fsl,liodn-bits : Indicates the number of defined bits in the LIODN
registers, for those SOCs that have a PAMU device.
+ - little-endian : Indicates that the global utilities block is little
+ endian. The default is big endian.
+
Examples:
global-utilities@e0000 { /* global utilities block */
compatible = "fsl,mpc8548-guts";
--
2.1.0.27.g96db324
^ permalink raw reply related
* [v12, 2/8] ARM64: dts: ls2080a: add device configuration node
From: Yangbo Lu @ 2016-09-21 6:57 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Scott Wood, Arnd Bergmann
Cc: Mark Rutland, Xiaobo Xie, Minghuan Lian,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Jochen Friedrich, Claudiu Manoil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kumar Gala, Rob Herring,
Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Add the dts node for device configuration unit that provides
general purpose configuration and status for the device.
Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Acked-by: Scott Wood <oss-fOR+EgIDQEHk1uMJSBkQmQ@public.gmane.org>
---
Changes for v5:
- Added this patch
Changes for v6:
- None
Changes for v7:
- None
Changes for v8:
- Added 'Acked-by: Scott Wood'
Changes for v9:
- None
Changes for v10:
- None
Changes for v11:
- None
Changes for v12:
- None
---
arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
index e3b6034..f231a14 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
@@ -215,6 +215,12 @@
clocks = <&sysclk>;
};
+ dcfg: dcfg@1e00000 {
+ compatible = "fsl,ls2080a-dcfg", "syscon";
+ reg = <0x0 0x1e00000 0x0 0x10000>;
+ little-endian;
+ };
+
serial0: serial@21c0500 {
compatible = "fsl,ns16550", "ns16550a";
reg = <0x0 0x21c0500 0x0 0x100>;
--
2.1.0.27.g96db324
^ permalink raw reply related
* [v12, 1/8] dt: bindings: update Freescale DCFG compatible
From: Yangbo Lu @ 2016-09-21 6:57 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Scott Wood, Arnd Bergmann
Cc: Mark Rutland, Xiaobo Xie, Minghuan Lian,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Jochen Friedrich, Claudiu Manoil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kumar Gala, Rob Herring,
Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Update Freescale DCFG compatible with 'fsl,<chip>-dcfg' instead
of 'fsl,ls1021a-dcfg' to include more chips such as ls1021a,
ls1043a, and ls2080a.
Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Scott Wood <oss-fOR+EgIDQEHk1uMJSBkQmQ@public.gmane.org>
---
Changes for v8:
- Added this patch
Changes for v9:
- Added a list for the possible compatibles
Changes for v10:
- None
Changes for v11:
- Added 'Acked-by: Rob Herring'
- Updated commit message by Scott
Changes for v12:
- None
---
Documentation/devicetree/bindings/arm/fsl.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
index dbbc095..713c1ae 100644
--- a/Documentation/devicetree/bindings/arm/fsl.txt
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -119,7 +119,11 @@ Freescale DCFG
configuration and status for the device. Such as setting the secondary
core start address and release the secondary core from holdoff and startup.
Required properties:
- - compatible: should be "fsl,ls1021a-dcfg"
+ - compatible: should be "fsl,<chip>-dcfg"
+ Possible compatibles:
+ "fsl,ls1021a-dcfg"
+ "fsl,ls1043a-dcfg"
+ "fsl,ls2080a-dcfg"
- reg : should contain base address and length of DCFG memory-mapped registers
Example:
--
2.1.0.27.g96db324
^ permalink raw reply related
* [v12, 0/8] Fix eSDHC host version register bug
From: Yangbo Lu @ 2016-09-21 6:57 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Scott Wood, Arnd Bergmann
Cc: Mark Rutland, Xiaobo Xie, Minghuan Lian,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
Bhupesh Sharma, Jochen Friedrich, Claudiu Manoil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kumar Gala, Rob Herring,
Santosh Shilimkar,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
This patchset is used to fix a host version register bug in the T4240-R1.0-R2.0
eSDHC controller. To match the SoC version and revision, 10 previous version
patchsets had tried many methods but all of them were rejected by reviewers.
Such as
- dts compatible method
- syscon method
- ifdef PPC method
- GUTS driver getting SVR method
Anrd suggested a soc_device_match method in v10, and this is the only available
method left now. This v11 patchset introduces the soc_device_match interface in
soc driver.
The first six patches of Yangbo are to add the GUTS driver. This is used to
register a soc device which contain soc version and revision information.
The other two patches introduce the soc_device_match method in soc driver
and apply it on esdhc driver to fix this bug.
Arnd Bergmann (1):
base: soc: introduce soc_device_match() interface
Yangbo Lu (7):
dt: bindings: update Freescale DCFG compatible
ARM64: dts: ls2080a: add device configuration node
dt: bindings: move guts devicetree doc out of powerpc directory
powerpc/fsl: move mpc85xx.h to include/linux/fsl
soc: fsl: add GUTS driver for QorIQ platforms
MAINTAINERS: add entry for Freescale SoC drivers
mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0
Documentation/devicetree/bindings/arm/fsl.txt | 6 +-
.../bindings/{powerpc => soc}/fsl/guts.txt | 3 +
MAINTAINERS | 11 +-
arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 6 +
arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +-
arch/powerpc/sysdev/fsl_pci.c | 2 +-
drivers/base/Kconfig | 1 +
drivers/base/soc.c | 66 ++++++
drivers/clk/clk-qoriq.c | 3 +-
drivers/i2c/busses/i2c-mpc.c | 2 +-
drivers/iommu/fsl_pamu.c | 3 +-
drivers/mmc/host/Kconfig | 1 +
drivers/mmc/host/sdhci-of-esdhc.c | 20 ++
drivers/net/ethernet/freescale/gianfar.c | 2 +-
drivers/soc/Kconfig | 2 +-
drivers/soc/fsl/Kconfig | 19 ++
drivers/soc/fsl/Makefile | 1 +
drivers/soc/fsl/guts.c | 257 +++++++++++++++++++++
include/linux/fsl/guts.h | 125 ++++++----
.../asm/mpc85xx.h => include/linux/fsl/svr.h | 4 +-
include/linux/sys_soc.h | 3 +
21 files changed, 478 insertions(+), 61 deletions(-)
rename Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt (91%)
create mode 100644 drivers/soc/fsl/Kconfig
create mode 100644 drivers/soc/fsl/guts.c
rename arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h (97%)
--
2.1.0.27.g96db324
^ permalink raw reply
* [PATCH 5/5] i2c: octeon,thunderx: Limit register access retries
From: Jan Glauber @ 2016-09-21 6:51 UTC (permalink / raw)
To: Wolfram Sang; +Cc: linux-kernel, linux-i2c, Jan Glauber
In-Reply-To: <cover.1474439371.git.jglauber@cavium.com>
Do not infinitely retry register readq and writeq operations
in order to not lock up the CPU in case the TWSI gets stuck.
Return -EIO in case of a failed data read. For all other
cases just return so subsequent operations will fail
and trigger the recovery.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
---
drivers/i2c/busses/i2c-octeon-core.c | 4 +++-
drivers/i2c/busses/i2c-octeon-core.h | 21 ++++++++++++++++-----
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index b21aa3e..6ba0146 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -381,7 +381,9 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
if (result)
return result;
- data[i] = octeon_i2c_data_read(i2c);
+ data[i] = octeon_i2c_data_read(i2c, &result);
+ if (result)
+ return result;
if (recv_len && i == 0) {
if (data[i] > I2C_SMBUS_BLOCK_MAX + 1)
return -EPROTO;
diff --git a/drivers/i2c/busses/i2c-octeon-core.h b/drivers/i2c/busses/i2c-octeon-core.h
index 87151ea..177d4cc 100644
--- a/drivers/i2c/busses/i2c-octeon-core.h
+++ b/drivers/i2c/busses/i2c-octeon-core.h
@@ -141,11 +141,14 @@ static inline void octeon_i2c_writeq_flush(u64 val, void __iomem *addr)
*/
static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
{
+ int tries = 100;
u64 tmp;
__raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c));
do {
tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ if (--tries < 0)
+ return;
} while ((tmp & SW_TWSI_V) != 0);
}
@@ -163,24 +166,32 @@ static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8
*
* The I2C core registers are accessed indirectly via the SW_TWSI CSR.
*/
-static inline u8 octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg)
+static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
+ int *error)
{
+ int tries = 100;
u64 tmp;
__raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c));
do {
tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ if (--tries < 0) {
+ /* signal that the returned data is invalid */
+ if (error)
+ *error = -EIO;
+ return 0;
+ }
} while ((tmp & SW_TWSI_V) != 0);
return tmp & 0xFF;
}
#define octeon_i2c_ctl_read(i2c) \
- octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL)
-#define octeon_i2c_data_read(i2c) \
- octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA)
+ octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL, NULL)
+#define octeon_i2c_data_read(i2c, error) \
+ octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA, error)
#define octeon_i2c_stat_read(i2c) \
- octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT)
+ octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT, NULL)
/**
* octeon_i2c_read_int - read the TWSI_INT register
--
1.9.1
^ permalink raw reply related
* [PATCH 4/5] i2c: octeon,thunderx: Check bus state before starting a transaction
From: Jan Glauber @ 2016-09-21 6:51 UTC (permalink / raw)
To: Wolfram Sang; +Cc: linux-kernel, linux-i2c, Jan Glauber
In-Reply-To: <cover.1474439371.git.jglauber@cavium.com>
Add an additional status check before starting a transaction and,
if required, trigger the recovery if the check fails.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
---
drivers/i2c/busses/i2c-octeon-core.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index 5e63b17..b21aa3e 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -630,6 +630,22 @@ static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msg
return ret;
}
+static int octeon_i2c_check_bus(struct octeon_i2c *i2c)
+{
+ int stat, lines;
+
+ stat = octeon_i2c_stat_read(i2c);
+
+ /* get I2C line state */
+ lines = octeon_i2c_read_int(i2c) & (TWSI_INT_SCL | TWSI_INT_SDA);
+
+ if (stat == STAT_IDLE && lines == (TWSI_INT_SCL | TWSI_INT_SDA))
+ return 0;
+
+ /* bus check failed, try to recover */
+ return octeon_i2c_recovery(i2c);
+}
+
/**
* octeon_i2c_xfer - The driver's master_xfer function
* @adap: Pointer to the i2c_adapter structure
@@ -643,6 +659,10 @@ int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
struct octeon_i2c *i2c = i2c_get_adapdata(adap);
int i, ret = 0;
+ ret = octeon_i2c_check_bus(i2c);
+ if (ret)
+ goto out;
+
if (num == 1) {
if (msgs[0].len > 0 && msgs[0].len <= 8) {
if (msgs[0].flags & I2C_M_RD)
--
1.9.1
^ permalink raw reply related
* [PATCH 3/5] i2c: octeon,thunderx: Fix high-level controller status check
From: Jan Glauber @ 2016-09-21 6:51 UTC (permalink / raw)
To: Wolfram Sang; +Cc: linux-kernel, linux-i2c, Jan Glauber
In-Reply-To: <cover.1474439371.git.jglauber@cavium.com>
In case the high-level controller (HLC) is used the status code is
reported at a different location. Check that location after HLC
write operations if the ready bit is not set and return an appropriate
error code instead of always returning -EAGAIN.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
---
drivers/i2c/busses/i2c-octeon-core.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index 7d4df83..5e63b17 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -215,7 +215,16 @@ static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
{
- u8 stat = octeon_i2c_stat_read(i2c);
+ u8 stat;
+
+ /*
+ * This is ugly... in HLC mode the status is not in the status register
+ * but in the lower 8 bits of SW_TWSI.
+ */
+ if (i2c->hlc_enabled)
+ stat = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ else
+ stat = octeon_i2c_stat_read(i2c);
switch (stat) {
/* Everything is fine */
@@ -453,7 +462,7 @@ static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
if ((cmd & SW_TWSI_R) == 0)
- return -EAGAIN;
+ return octeon_i2c_check_status(i2c, false);
for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--)
msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
@@ -506,9 +515,7 @@ static int octeon_i2c_hlc_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
if ((cmd & SW_TWSI_R) == 0)
- return -EAGAIN;
-
- ret = octeon_i2c_check_status(i2c, false);
+ return octeon_i2c_check_status(i2c, false);
err:
return ret;
@@ -553,7 +560,7 @@ static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs
cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
if ((cmd & SW_TWSI_R) == 0)
- return -EAGAIN;
+ return octeon_i2c_check_status(i2c, false);
for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--)
msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
@@ -617,9 +624,7 @@ static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msg
cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
if ((cmd & SW_TWSI_R) == 0)
- return -EAGAIN;
-
- ret = octeon_i2c_check_status(i2c, false);
+ return octeon_i2c_check_status(i2c, false);
err:
return ret;
--
1.9.1
^ permalink raw reply related
* [PATCH 2/5] i2c: octeon,thunderx: Avoid sending STOP during recovery
From: Jan Glauber @ 2016-09-21 6:51 UTC (permalink / raw)
To: Wolfram Sang; +Cc: linux-kernel, linux-i2c, Dmitry Bazhenov, Jan Glauber
In-Reply-To: <cover.1474439371.git.jglauber@cavium.com>
From: Dmitry Bazhenov <dmitry.bazhenov@auriga.com>
Due to a bug in the ThunderX I2C hardware sending STOP during
a recovery attempt could lock up the hardware. To work around
this problem do not send STOP at the beginning of the recovery
but use the override registers to bring the TWSI including
the high-level controller out of the bad state.
Signed-off-by: Dmitry Bazhenov <dmitry.bazhenov@auriga.com>
Signed-off-by: Jan Glauber <jglauber@cavium.com>
[Changed commit message]
---
drivers/i2c/busses/i2c-octeon-core.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index f322242..7d4df83 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -783,13 +783,14 @@ static void octeon_i2c_prepare_recovery(struct i2c_adapter *adap)
{
struct octeon_i2c *i2c = i2c_get_adapdata(adap);
+ octeon_i2c_hlc_disable(i2c);
+
/*
- * The stop resets the state machine, does not _transmit_ STOP unless
- * engine was active.
+ * Bring control register to a good state regardless
+ * of HLC state.
*/
- octeon_i2c_stop(i2c);
+ octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
- octeon_i2c_hlc_disable(i2c);
octeon_i2c_write_int(i2c, 0);
}
@@ -797,6 +798,15 @@ static void octeon_i2c_unprepare_recovery(struct i2c_adapter *adap)
{
struct octeon_i2c *i2c = i2c_get_adapdata(adap);
+ /*
+ * Generate STOP to finish the unfinished transaction.
+ * Can't generate STOP via the TWSI CTL register
+ * since it could bring the TWSI controller into an inoperable state.
+ */
+ octeon_i2c_write_int(i2c, TWSI_INT_SDA_OVR | TWSI_INT_SCL_OVR);
+ udelay(5);
+ octeon_i2c_write_int(i2c, TWSI_INT_SDA_OVR);
+ udelay(5);
octeon_i2c_write_int(i2c, 0);
}
--
1.9.1
^ permalink raw reply related
* [PATCH 1/5] i2c: octeon,thunderx: Fix set SCL recovery function
From: Jan Glauber @ 2016-09-21 6:51 UTC (permalink / raw)
To: Wolfram Sang; +Cc: linux-kernel, linux-i2c, Dmitry Bazhenov, Jan Glauber
In-Reply-To: <cover.1474439371.git.jglauber@cavium.com>
From: Dmitry Bazhenov <dmitry.bazhenov@auriga.com>
The set SCL recovery function unconditionally pulls the SCL line low.
Only pull SCL line low according to val parameter.
Signed-off-by: Dmitry Bazhenov <dmitry.bazhenov@auriga.com>
Signed-off-by: Jan Glauber <jglauber@cavium.com>
[Changed commit message]
---
drivers/i2c/busses/i2c-octeon-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index f45ea5e..f322242 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -767,7 +767,7 @@ static void octeon_i2c_set_scl(struct i2c_adapter *adap, int val)
{
struct octeon_i2c *i2c = i2c_get_adapdata(adap);
- octeon_i2c_write_int(i2c, TWSI_INT_SCL_OVR);
+ octeon_i2c_write_int(i2c, val ? 0 : TWSI_INT_SCL_OVR);
}
static int octeon_i2c_get_sda(struct i2c_adapter *adap)
--
1.9.1
^ permalink raw reply related
* [PATCH 0/5] i2c: octeon,thunderx: Recovery fixes and improvements
From: Jan Glauber @ 2016-09-21 6:51 UTC (permalink / raw)
To: Wolfram Sang; +Cc: linux-kernel, linux-i2c, Jan Glauber
Hi Wolfram,
the ThunderX i2c driver got more exposure with IPMI/BMC testing and
we've found several issues that I'd like to address with this series.
The patches are all related to recovery or improve stability in
the presence of hardware/firmware bugs.
Patches are against linux-next and were tested on ThunderX and Octeon
(by Steven J. Hill).
thanks,
Jan
--------------
Dmitry Bazhenov (2):
i2c: octeon,thunderx: Fix set SCL recovery function
i2c: octeon,thunderx: Avoid sending STOP during recovery
Jan Glauber (3):
i2c: octeon,thunderx: Fix high-level controller status check
i2c: octeon,thunderx: Check bus state before starting a transaction
i2c: octeon,thunderx: Limit register access retries
drivers/i2c/busses/i2c-octeon-core.c | 67 ++++++++++++++++++++++++++++--------
drivers/i2c/busses/i2c-octeon-core.h | 21 ++++++++---
2 files changed, 68 insertions(+), 20 deletions(-)
--
1.9.1
^ permalink raw reply
* Re: [PATCH v2] i2c / ACPI: Do not touch an I2C device if it belongs to another adapter
From: Wolfram Sang @ 2016-09-21 5:48 UTC (permalink / raw)
To: Mika Westerberg
Cc: Nicolai Stange, Octavian Purdila, Rafael J . Wysocki,
Jarkko Nikula, linux-i2c, linux-kernel
In-Reply-To: <20160920135925.45450-1-mika.westerberg@linux.intel.com>
[-- Attachment #1: Type: text/plain, Size: 1481 bytes --]
On Tue, Sep 20, 2016 at 04:59:25PM +0300, Mika Westerberg wrote:
> When enumerating I2C devices connected to an I2C adapter we scan the whole
> namespace (as it is possible to have devices anywhere in that namespace,
> not just below the I2C adapter device) and add each found device to the I2C
> bus in question.
>
> Now after commit 525e6fabeae2 ("i2c / ACPI: add support for ACPI
> reconfigure notifications") checking of the adapter handle to the one found
> in the I2cSerialBus() resource was moved to happen after resources of the
> I2C device has been parsed. This means that if the I2cSerialBus() resource
> points to an adapter that does not exists in the system we still parse
> those resources. This is problematic in particular because
> acpi_dev_resource_interrupt() tries to configure GSI if the device also has
> an Interrupt() resource. Failing to do that results errrors like this to be
> printed on the console:
>
> [ 10.409490] ERROR: Unable to locate IOAPIC for GSI 37
>
> To fix this we pass the I2C adapter to i2c_acpi_get_info() and make sure
> the handle matches the one in the I2cSerialBus() resource before doing
> anything else to the device.
>
> Reported-and-tested-by: Nicolai Stange <nicstange@gmail.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Considering this for for-current. So shall we add:
Fixes: 525e6fabeae2 ("i2c / ACPI: add support for ACPI reconfigure notifications")
?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH v2 4/4] gpio: pca953x: fix an incorrect lockdep warning
From: Wolfram Sang @ 2016-09-21 5:45 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Linus Walleij, Alexandre Courbot, Andy Shevchenko, Vignesh R,
Yong Li, Geert Uytterhoeven, Peter Zijlstra, Ingo Molnar,
Peter Rosin, linux-i2c, linux-gpio, LKML
In-Reply-To: <1474041765-17818-5-git-send-email-bgolaszewski@baylibre.com>
[-- Attachment #1: Type: text/plain, Size: 2545 bytes --]
On Fri, Sep 16, 2016 at 06:02:45PM +0200, Bartosz Golaszewski wrote:
> If an I2C GPIO multiplexer is driven by a GPIO provided by an expander
> when there's a second expander using the same device driver on one of
> the I2C bus segments, lockdep prints a deadlock warning when trying to
> set the direction or the value of the GPIOs provided by the second
> expander.
>
> The below diagram presents the setup:
>
> - - - - -
> ------- --------- Bus segment 1 | |
> | | | |--------------- Devices
> | | SCL/SDA | | | |
> | Linux |-----------| I2C MUX | - - - - -
> | | | | | Bus segment 2
> | | | | |-------------------
> ------- | --------- |
> | | - - - - -
> ------------ | MUX GPIO | |
> | | | Devices
> | GPIO | | | |
> | Expander 1 |---- - - - - -
> | | |
> ------------ | SCL/SDA
> |
> ------------
> | |
> | GPIO |
> | Expander 2 |
> | |
> ------------
>
> The reason for lockdep warning is that we take the chip->i2c_lock in
> pca953x_gpio_set_value() or pca953x_gpio_direction_output() and then
> come right back to pca953x_gpio_set_value() when the GPIO mux kicks
> in. The locks actually protect different expanders, but for lockdep
> both are of the same class, so it says:
>
> Possible unsafe locking scenario:
>
> CPU0
> ----
> lock(&chip->i2c_lock);
> lock(&chip->i2c_lock);
>
> *** DEADLOCK ***
>
> May be due to missing lock nesting notation
>
> In order to get rid of the warning, retrieve the adapter nesting depth
> and use it as lockdep subclass for chip->i2c_lock.
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Linus, we'd like that in 4.9. Can I get your ack for the gpio part?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH v2 2/2] i2c: aspeed: added documentation for Aspeed I2C driver
From: Brendan Higgins @ 2016-09-20 23:03 UTC (permalink / raw)
To: Rob Herring
Cc: Wolfram Sang, mark.rutland, linux-i2c, devicetree, linux-kernel,
OpenBMC Maillist, Joel Stanley, Jeremy Kerr
In-Reply-To: <CAFd5g46F1reb-d47YBtxOywPObsLWy+L4KEGuXVJPGvL29O+ng@mail.gmail.com>
To be clear, these bus numbers are defined as part of the hardware
specification. I am not sure if that was clear before.
On Tue, Sep 20, 2016 at 11:08 AM, Brendan Higgins
<brendanhiggins@google.com> wrote:
> (sorry if you get a duplicate, I forgot to send plain text)
>
> First off, someone pointed out to me that the mapping that I used
> between addresses and bus numbers is not actually valid for busses
> 8-14.
>
> This could be fixed by checking the offset, but I am wondering if that
> is the right way to do it. It seems like this is not completely
> trivial so maybe this should be specified in the device tree? If that
> is the case, should I do this as another reg entry or go back to the
> way I was doing it before?
>
> On Mon, Sep 19, 2016 at 4:26 PM, Brendan Higgins
> <brendanhiggins@google.com> wrote:
>> Addressed in v3.
>>
>> Thanks!
>>
>> On Mon, Sep 19, 2016 at 2:35 PM, Rob Herring <robh@kernel.org> wrote:
>>> On Fri, Sep 09, 2016 at 06:55:51PM -0700, Brendan Higgins wrote:
>>>> Added device tree binding documentation for Aspeed I2C controller and
>>>> busses.
>>>>
>>>> Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
>>>> ---
>>>> Changes for v2:
>>>> - None
>>>> ---
>>>> .../devicetree/bindings/i2c/i2c-aspeed.txt | 63 ++++++++++++++++++++++
>>>> 1 file changed, 63 insertions(+)
>>>> create mode 100644 Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
>>>> new file mode 100644
>>>> index 0000000..df68f2a
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
>>>> @@ -0,0 +1,63 @@
>>>> +Device tree configuration for the I2C controller and busses on the AST24XX
>>>> +and AST25XX SoCs.
>>>> +
>>>> +Controller:
>>>> +
>>>> + Required Properties:
>>>> + - #address-cells : should be 1
>>>> + - #size-cells : should be 1
>>>> + - #interrupt-cells : should be 1
>>>> + - compatible : should be "aspeed,ast2400-i2c-controller"
>>>> + or "aspeed,ast2500-i2c-controller"
>>>> + - reg : address start and range of controller
>>>> + - ranges : defines address offset and range for busses
>>>> + - interrupts : interrupt number
>>>> + - clocks : root clock of bus, should reference the APB
>>>> + clock
>>>> + - clock-ranges : specifies that child busses can inherit clocks
>>>> + - interrupt-controller : denotes that the controller receives and fires
>>>> + new interrupts for child busses
>>>> +
>>>> +Bus:
>>>> +
>>>> + Required Properties:
>>>> + - #address-cells : should be 1
>>>> + - #size-cells : should be 0
>>>> + - reg : address offset and range of bus
>>>> + - compatible : should be "aspeed,ast2400-i2c-bus"
>>>> + or "aspeed,ast2500-i2c-bus"
>>>> + - bus : the bus's number
>>>
>>> Don't use indexes. The reg property is enough to id which bus is which.
^ permalink raw reply
* Re: [PATCH v2] i2c / ACPI: Do not touch an I2C device if it belongs to another adapter
From: Nicolai Stange @ 2016-09-20 18:49 UTC (permalink / raw)
To: Mika Westerberg
Cc: Wolfram Sang, Nicolai Stange, Octavian Purdila,
Rafael J . Wysocki, Jarkko Nikula, linux-i2c, linux-kernel
In-Reply-To: <20160920135925.45450-1-mika.westerberg@linux.intel.com>
Mika Westerberg <mika.westerberg@linux.intel.com> writes:
> When enumerating I2C devices connected to an I2C adapter we scan the whole
> namespace (as it is possible to have devices anywhere in that namespace,
> not just below the I2C adapter device) and add each found device to the I2C
> bus in question.
>
> Now after commit 525e6fabeae2 ("i2c / ACPI: add support for ACPI
> reconfigure notifications") checking of the adapter handle to the one found
> in the I2cSerialBus() resource was moved to happen after resources of the
> I2C device has been parsed. This means that if the I2cSerialBus() resource
> points to an adapter that does not exists in the system we still parse
> those resources. This is problematic in particular because
> acpi_dev_resource_interrupt() tries to configure GSI if the device also has
> an Interrupt() resource. Failing to do that results errrors like this to be
> printed on the console:
>
> [ 10.409490] ERROR: Unable to locate IOAPIC for GSI 37
>
> To fix this we pass the I2C adapter to i2c_acpi_get_info() and make sure
> the handle matches the one in the I2cSerialBus() resource before doing
> anything else to the device.
>
> Reported-and-tested-by: Nicolai Stange <nicstange@gmail.com>
I've just retested this v2 explicitly and it works like a charm.
Also,
Reviewed-by: Nicolai Stange <nicstange@gmail.com>
if you want.
Thanks,
Nicolai
^ permalink raw reply
* Re: [PATCH v2 2/2] i2c: aspeed: added documentation for Aspeed I2C driver
From: Brendan Higgins @ 2016-09-20 18:08 UTC (permalink / raw)
To: Rob Herring
Cc: Wolfram Sang, mark.rutland, linux-i2c, devicetree, linux-kernel,
OpenBMC Maillist, Joel Stanley, Jeremy Kerr
In-Reply-To: <CAFd5g46WR34A1FLNvuRck84EX1F3gbPDnDuBo2j-SVUEJPvXfg@mail.gmail.com>
(sorry if you get a duplicate, I forgot to send plain text)
First off, someone pointed out to me that the mapping that I used
between addresses and bus numbers is not actually valid for busses
8-14.
This could be fixed by checking the offset, but I am wondering if that
is the right way to do it. It seems like this is not completely
trivial so maybe this should be specified in the device tree? If that
is the case, should I do this as another reg entry or go back to the
way I was doing it before?
On Mon, Sep 19, 2016 at 4:26 PM, Brendan Higgins
<brendanhiggins@google.com> wrote:
> Addressed in v3.
>
> Thanks!
>
> On Mon, Sep 19, 2016 at 2:35 PM, Rob Herring <robh@kernel.org> wrote:
>> On Fri, Sep 09, 2016 at 06:55:51PM -0700, Brendan Higgins wrote:
>>> Added device tree binding documentation for Aspeed I2C controller and
>>> busses.
>>>
>>> Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
>>> ---
>>> Changes for v2:
>>> - None
>>> ---
>>> .../devicetree/bindings/i2c/i2c-aspeed.txt | 63 ++++++++++++++++++++++
>>> 1 file changed, 63 insertions(+)
>>> create mode 100644 Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
>>> new file mode 100644
>>> index 0000000..df68f2a
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
>>> @@ -0,0 +1,63 @@
>>> +Device tree configuration for the I2C controller and busses on the AST24XX
>>> +and AST25XX SoCs.
>>> +
>>> +Controller:
>>> +
>>> + Required Properties:
>>> + - #address-cells : should be 1
>>> + - #size-cells : should be 1
>>> + - #interrupt-cells : should be 1
>>> + - compatible : should be "aspeed,ast2400-i2c-controller"
>>> + or "aspeed,ast2500-i2c-controller"
>>> + - reg : address start and range of controller
>>> + - ranges : defines address offset and range for busses
>>> + - interrupts : interrupt number
>>> + - clocks : root clock of bus, should reference the APB
>>> + clock
>>> + - clock-ranges : specifies that child busses can inherit clocks
>>> + - interrupt-controller : denotes that the controller receives and fires
>>> + new interrupts for child busses
>>> +
>>> +Bus:
>>> +
>>> + Required Properties:
>>> + - #address-cells : should be 1
>>> + - #size-cells : should be 0
>>> + - reg : address offset and range of bus
>>> + - compatible : should be "aspeed,ast2400-i2c-bus"
>>> + or "aspeed,ast2500-i2c-bus"
>>> + - bus : the bus's number
>>
>> Don't use indexes. The reg property is enough to id which bus is which.
^ permalink raw reply
* Re: [PATCH] i2c-eg20t: use dynamically registered adapter number
From: Jean Delvare @ 2016-09-20 15:48 UTC (permalink / raw)
To: Wolfram Sang; +Cc: Yadi Hu, linux-i2c
In-Reply-To: <20160919110247.4e0657fb@endymion>
Hi all,
On Mon, 19 Sep 2016 11:02:47 +0200, Jean Delvare wrote:
> My own proposal was checking __i2c_first_dynamic_bus_num. To be honest
> I can't see the added value of relying on i2c_get_adapter() instead.
> Would the result not be exactly the same? Plus it seems racy, just
> because i2c_get_adapter() returns NULL at one point in time doesn't
> mean the bus numbers will not have been assigned by the time you call
> i2c_add_numbered_adapter().
> (...)
> If you consider it a workaround, what would be the "real fix" for you?
>
> I was wondering if selecting one of these drivers could set a Kconfig
> option to initialize __i2c_first_dynamic_bus_num to a non-zero value.
> Unfortunately there does not seem to be a way to set a numeric value to
> a Kconfig option using select. We would have to do it indirectly as
> with CONFIG_HZ:
>
> choice
> default I2C_RESERVED_BUS_NR_0
> config I2C_RESERVED_BUS_NR_0
> config I2C_RESERVED_BUS_NR_2
> endchoice
>
> config I2C_RESERVED_BUS_NR
> int
> default 0 if I2C_RESERVED_BUS_NR_0
> default 2 if I2C_RESERVED_BUS_NR_2
>
> config I2C_EG20T
> tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) I2C"
> depends on PCI && (X86_32 || MIPS || COMPILE_TEST)
> select I2C_RESERVED_BUS_NR_2
>
> And in i2c-core.c:
>
> __i2c_first_dynamic_bus_num = I2C_RESERVED_BUS_NR;
>
> If that's possible at all... I'm not sure if select works on choice
> config options.
>
> Alternatively we could set the default directly based on driver
> selection:
>
> config I2C_RESERVED_BUS_NR
> int
> default 0
> default 2 if I2C_EG20T
>
> This is more simple but a little harder to maintain. One possible
> problem is if the number of buses isn't known at build time but could
> change depending on the hardware, for example. Also I don't know if
> more than one such driver can be included in the same kernel.
>
> Or we can make it a user-visible option and leave it on whoever
> configures the kernel to get it right. In all cases it would move the
> decision to build-time instead of being set dynamically at run-time.
>
> Note that I am not claiming this is necessarily better than my initial
> proposal. I just wanted to mention the possibility.
I slept over it and start wondering if we aren't trying to address the
problem at the wrong end.
The initial reason why i2c_add_numbered_adapter() was used in the
i2c-eg20t driver (and, I suppose, i2c-pasemi and all other bus drivers)
is because the platform initialization code/data (native or OF-based)
may be declaring slave I2C devices on these buses. This bumps
__i2c_first_dynamic_bus_num, and the bus driver needs to call
i2c_add_numbered_adapter() to get bus numbers below that.
Maybe in that case the bus driver should ALSO get the static bus number
information from the platform initialization code/data. Then the bus
driver would check that information, and use it to call
i2c_add_numbered_adapter() as appropriate if present, or simply call
i2c_add_adapter() if not (or ask i2c_add_numbered_adapter for bus
number -1, which has the same result.)
Looks like drivers i2c-s3c2410, i2c-designware-*, i2c-kempld and
i2c-pxa are already getting this right. So maybe we don't need to
introduce another mechanism, but instead use what is already in place?
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply
* Re: [PATCH v2 0/4] gpio: fix an incorrect lockdep warning
From: Thomas Gleixner @ 2016-09-20 15:33 UTC (permalink / raw)
To: Peter Rosin
Cc: Peter Zijlstra, Bartosz Golaszewski, Wolfram Sang, Linus Walleij,
Alexandre Courbot, Andy Shevchenko, Vignesh R, Yong Li,
Geert Uytterhoeven, Ingo Molnar, linux-i2c, linux-gpio, LKML
In-Reply-To: <e4b4c894-4913-b00f-0a9d-243258f2699b@axentia.se>
On Tue, 20 Sep 2016, Peter Rosin wrote:
> On 2016-09-19 11:03, Peter Zijlstra wrote:
> >
> > Use the -RT kernel and all locks will end up as rt_mutex. Avoiding
> > inversion on one specific lock, while there are then a gazillion other
> > than can equally create inversion doesn't make sense to me.
That's true, but the locking of the i2c stuff is pretty much self contained
and the results of using an rtmutex speak for themself.
One of the issues is that i2c needs to use threaded interrupt handlers and
blocking out the handler thread with a preempted user space task is hurting
performance badly.
I don't think that using a rtmutex there is wrong. It cures at least a very
clear priority inversion issue versus the threaded interrupt handler.
Forcing all i2c users off to RT is not really an option. RT has other
drawbacks vs. throughput which you don't want to impose on everything which
happens to use i2c.
> 2a will cause a lockdep splat if i2c0:mux_lock is in the same
> lockdep class & subclass as i2c1:mux_lock. So, lockdep needs
> separate lockdep classes depending on the i2c root adapter
> (subclasses are needed to handle deeper trees, so they are off
> limits). Great fun. How do I go about creating a new lockdep
> class for every i2c root adapter instance?
lockdep_set_class() .....
Thanks,
tglx
^ permalink raw reply
* [PATCH v2] i2c / ACPI: Do not touch an I2C device if it belongs to another adapter
From: Mika Westerberg @ 2016-09-20 13:59 UTC (permalink / raw)
To: Wolfram Sang
Cc: Nicolai Stange, Octavian Purdila, Rafael J . Wysocki,
Jarkko Nikula, Mika Westerberg, linux-i2c, linux-kernel
In-Reply-To: <874m5ax3o4.fsf@gmail.com>
When enumerating I2C devices connected to an I2C adapter we scan the whole
namespace (as it is possible to have devices anywhere in that namespace,
not just below the I2C adapter device) and add each found device to the I2C
bus in question.
Now after commit 525e6fabeae2 ("i2c / ACPI: add support for ACPI
reconfigure notifications") checking of the adapter handle to the one found
in the I2cSerialBus() resource was moved to happen after resources of the
I2C device has been parsed. This means that if the I2cSerialBus() resource
points to an adapter that does not exists in the system we still parse
those resources. This is problematic in particular because
acpi_dev_resource_interrupt() tries to configure GSI if the device also has
an Interrupt() resource. Failing to do that results errrors like this to be
printed on the console:
[ 10.409490] ERROR: Unable to locate IOAPIC for GSI 37
To fix this we pass the I2C adapter to i2c_acpi_get_info() and make sure
the handle matches the one in the I2cSerialBus() resource before doing
anything else to the device.
Reported-and-tested-by: Nicolai Stange <nicstange@gmail.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
Changes from v1:
* Require that ACPI adapter device is present if !adapter
* Fill in adapter_handle only if not NULL
* Remove passing of adapter_handle in i2c_acpi_add_device()
drivers/i2c/i2c-core.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index c61c961cf8f9..5476f906b9e0 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -168,6 +168,7 @@ static int i2c_acpi_do_lookup(struct acpi_device *adev,
static int i2c_acpi_get_info(struct acpi_device *adev,
struct i2c_board_info *info,
+ struct i2c_adapter *adapter,
acpi_handle *adapter_handle)
{
struct list_head resource_list;
@@ -182,8 +183,24 @@ static int i2c_acpi_get_info(struct acpi_device *adev,
if (ret)
return ret;
+ if (adapter) {
+ /* The adapter must match the one in I2cSerialBus() connector */
+ if (ACPI_HANDLE(&adapter->dev) != lookup.adapter_handle)
+ return -ENODEV;
+ } else {
+ struct acpi_device *adapter_adev;
+
+ /* The adapter must be present */
+ if (acpi_bus_get_device(lookup.adapter_handle, &adapter_adev))
+ return -ENODEV;
+ if (acpi_bus_get_status(adapter_adev) ||
+ !adapter_adev->status.present)
+ return -ENODEV;
+ }
+
info->fwnode = acpi_fwnode_handle(adev);
- *adapter_handle = lookup.adapter_handle;
+ if (adapter_handle)
+ *adapter_handle = lookup.adapter_handle;
/* Then fill IRQ number if any */
INIT_LIST_HEAD(&resource_list);
@@ -225,16 +242,12 @@ static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
{
struct i2c_adapter *adapter = data;
struct acpi_device *adev;
- acpi_handle adapter_handle;
struct i2c_board_info info;
if (acpi_bus_get_device(handle, &adev))
return AE_OK;
- if (i2c_acpi_get_info(adev, &info, &adapter_handle))
- return AE_OK;
-
- if (adapter_handle != ACPI_HANDLE(&adapter->dev))
+ if (i2c_acpi_get_info(adev, &info, adapter, NULL))
return AE_OK;
i2c_acpi_register_device(adapter, adev, &info);
@@ -368,7 +381,7 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
switch (value) {
case ACPI_RECONFIG_DEVICE_ADD:
- if (i2c_acpi_get_info(adev, &info, &adapter_handle))
+ if (i2c_acpi_get_info(adev, &info, NULL, &adapter_handle))
break;
adapter = i2c_acpi_find_adapter_by_handle(adapter_handle);
--
2.9.3
^ permalink raw reply related
* Re: [PATCH v2 0/4] gpio: fix an incorrect lockdep warning
From: Bartosz Golaszewski @ 2016-09-20 12:32 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Peter Rosin, Peter Zijlstra, Wolfram Sang, Linus Walleij,
Alexandre Courbot, Andy Shevchenko, Vignesh R, Yong Li,
Geert Uytterhoeven, Ingo Molnar, linux-i2c, linux-gpio, LKML
In-Reply-To: <CAMuHMdX6otYLuYm9x4BNm-U3gHn5Y_JwBUm5qagWLOU0ucRmcQ@mail.gmail.com>
2016-09-20 13:30 GMT+02:00 Geert Uytterhoeven <geert@linux-m68k.org>:
> On Tue, Sep 20, 2016 at 12:48 PM, Peter Rosin <peda@axentia.se> wrote:
>> On 2016-09-20 12:07, Bartosz Golaszewski wrote:
>>> I feel like it's just wrong to set an arbitrary limit on the number of
>>> i2c branches - and this is what the result of this approach would be.
>>
>> What arbitrary limit would that be? The number of lockdep classes
>> can't be *that* limited? Or?
>>
>> I mean one lockdep class per root adapter and one subclass within that
>> class per mux level doesn't sound too bad. How many root adapters do
>> we need to design for?
>
> 'git grep -c i2c@ -- "*dts*"' told me exynos7 has 12 i2c interfaces.
> And as long as I have gpios (pcf8574?), I can add more using i2c-gpio.
> Hence the upper limit is infinity.
>
Agreed. If you add to that dynamic i2c adapters like hid-cp2112 or
greybus-i2c then it makes infinity plus some more.
Best regards,
Bartosz Golaszewski
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox