* [PATCH 8/10] arm64: dts: marvell: add eMMC support for Armada 37xx
From: Gregory CLEMENT @ 2016-10-07 15:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.990e3503c30c18ecf50dd48bce3d52811f03ca22.1475853198.git-series.gregory.clement@free-electrons.com>
Add the eMMC support for Armada 37xx SoC and enable it in the Armada 3720
DB board.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-3720-db.dts | 7 +++++++
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 11 +++++++++++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
index 1372e9a6aaa4..5b9cff4d5d7a 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -72,6 +72,13 @@
status = "okay";
};
+&sdhci0 {
+ non-removable;
+ bus-width = <8>;
+ xenon,pad-type = "fixed-1-8v";
+ status = "okay";
+};
+
/* CON31 */
&usb3 {
status = "okay";
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index c4762538ec01..0c4cafe92e66 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -161,6 +161,17 @@
};
};
+ sdhci0: sdhci at d8000 {
+ compatible = "marvell,armada-3700-sdhci",
+ "marvell,sdhci-xenon";
+ reg = <0xd8000 0x300
+ 0x17808 0x4>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&nb_perih_clk 0>;
+ clock-names = "core";
+ status = "disabled";
+ };
+
sata: sata at e0000 {
compatible = "marvell,armada-3700-ahci";
reg = <0xe0000 0x2000>;
--
git-series 0.8.10
^ permalink raw reply related
* [PATCH 9/10] arm64: dts: marvell: add sdhci support for Armada 7K/8K
From: Gregory CLEMENT @ 2016-10-07 15:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.990e3503c30c18ecf50dd48bce3d52811f03ca22.1475853198.git-series.gregory.clement@free-electrons.com>
Also enable it on the Armada 7040 DB board
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-7040-db.dts | 7 +++++++
arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 9 +++++++++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-7040-db.dts b/arch/arm64/boot/dts/marvell/armada-7040-db.dts
index 070b589680c5..f7f978a12a49 100644
--- a/arch/arm64/boot/dts/marvell/armada-7040-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-7040-db.dts
@@ -146,3 +146,10 @@
&cpm_usb3_1 {
status = "okay";
};
+
+&sdhci0 {
+ status = "okay";
+ bus-width = <4>;
+ no-1-8-v;
+ non-removable;
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index 7b6136182ad0..ef2ce6be7205 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -229,6 +229,15 @@
};
+ sdhci0: sdhci at 6e0000 {
+ compatible = "marvell,sdhci-xenon";
+ reg = <0x6e0000 0x300>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "core";
+ clocks = <&cpm_syscon0 1 4>;
+ status = "disabled";
+ };
+
ap_syscon: system-controller at 6f4000 {
compatible = "marvell,ap806-system-controller",
"syscon";
--
git-series 0.8.10
^ permalink raw reply related
* [PATCH 10/10] arm64: configs: enable SDHCI driver for Xenon
From: Gregory CLEMENT @ 2016-10-07 15:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.990e3503c30c18ecf50dd48bce3d52811f03ca22.1475853198.git-series.gregory.clement@free-electrons.com>
This patch enables the driver for the SDHCI controller found on the
Marvell Armada 3700 and 7K/8K ARM64 SoCs.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+), 0 deletions(-)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index dab2cb0c1f1c..2d1f5ee62b18 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -353,6 +353,7 @@ CONFIG_MMC_DW=y
CONFIG_MMC_DW_EXYNOS=y
CONFIG_MMC_DW_K3=y
CONFIG_MMC_SUNXI=y
+CONFIG_MMC_SDHCI_XENON=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
--
git-series 0.8.10
^ permalink raw reply related
* [PATCHv4 2/3] tty/serial: at91: fix hardware handshake with GPIOs
From: Richard Genoud @ 2016-10-07 15:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161004072525.josgoglunmvufcn2@pengutronix.de>
Le Tue, 4 Oct 2016 09:25:25 +0200,
Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de> a ?crit :
> On Fri, Sep 30, 2016 at 01:04:28PM +0200, Richard Genoud wrote:
> > 2016-09-30 11:12 GMT+02:00 Uwe Kleine-K?nig
> > <u.kleine-koenig@pengutronix.de>:
> > > Hello Richard,
> > >
> > > On Fri, Sep 30, 2016 at 10:58:00AM +0200, Richard Genoud wrote:
> > >> Commit 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management
> > >> when hardware handshake is enabled") broke the hardware
> > >> handshake when GPIOs were used.
> > >>
> > >> Hardware handshake with GPIOs used to work before this commit
> > >> because the CRTSCTS flag (termios->c_cflag) was set, but not the
> > >> ATMEL_US_USMODE_HWHS flag (controller register) ; so hardware
> > >> handshake enabled, but not handled by the controller.
> > >
> > > What does the HWHS flag control? What if only RTS is a gpio and
> > > CTS is not? Or the other way round?
> > First, HWHS flag is used only in SAMA5D2. (if I correctly understood
> > Atmel HW guys,
> > all other platforms (sam9, sam9x5, sama5d3...) have this flag, but
> > it is unusable,
> > because they don't have Fifos nor PDC).
> > So, on SAMA5D2, the HWHS flag tells the controller to drive the RTS
> > pin according to
> > the number of char present in the rx fifo (cf Figure 44-29
> > ?44.7.3.15 p.1438 of
> > http://www.atmel.com/Images/Atmel-11267-32-bit-Cortex-A5-Microcontroller-SAMA5D2_Datasheet.pdf).
> > The controller will also start/stop the transmission on CTS
> > changes. But, as I haven't got this hard, I couldn't test it. (but
> > Cyrille did I guess). With this flag set, It's mandatory to have
> > CTS and RTS not handled via GPIO, because if they were, the
> > controller couldn't, well, control them.
>
> Assuming the respective pin doesn't reach the hardware both are no
> problem though. And it would keep the driver simpler to just ignore
> this. There would be no need for patch 1 and also this patch could be
> dropped. So I guess there is really something to fix, otherwise you
> wouldn't start patching the driver. But I don't understand the issue,
> so I'd like to have a better picture.
>
> Best regards
> Uwe
>
Ok, so I'll try to explain what's going on.
I'm sure you're familiar with hardware handshaking (aka flow control),
but anyway, it doesn't hurt to explain it for the big picture
understanding.
On RS232, flow control is handled by 2 pins: RTS and CTS.
CTS is an input. When it's high (ttl), it indicates that we should stop
transmitting.
RTS is an output, we drive it at high level (ttl) to indicate that we
can't receive anymore data for now (because the rx buffer is full, or
the device is closed for instance).
The RTS and CTS management is done in serial_core.c which calls
atmel_set/get_mctrl to set/get RTS/CTS pin state.
And CTS changes are detected via an interrupt in atmel_interrupt().
Now, the atmel USART controller has a feature that can handle part of
the flow control job:
- disabling the transmitter when the CTS pin gets high
- drive the RTS pin high when the DMA buffer transfer is completed or
PDC rx buffer full or rx FIFO is beyond threshold. (depending on the
controller version).
This feature is enabled by setting the flag ATMEL_US_USMODE_HWHS.
And to be clear, this feature is *not* mandatory for the flow control to
work !
[ The fun part is that according to atmel designers, this feature is
broken for platforms with no PDC and no FIFO.
(source: https://lkml.org/lkml/2016/9/7/598 ) ]
Before commit 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management
when hardware handshake is enabled"), this flag was never set.
Thus, the CTS/RTS where only handled by serial_core (and everything
worked just fine).
This commit introduced the use of the ATMEL_US_USMODE_HWHS (among other
things).
The logic introduced was to set the flag ATMEL_US_USMODE_HWHS for all
boards when the user space enables flow control.
This was clearly wrong because this feature can only be used when PDC
or FIFO are in use.
If ATMEL_US_USMODE_HWHS is enabled and PDC/FIFO/DMA are not used, the
RTS pin stays at high level no matter what, preventing any data to be
received.
Then, commit 5be605ac9af9 ("tty/serial: atmel: fix hardware handshake
selection") did something completely wrong:
Instead of removing the flag ATMEL_US_USMODE_HWHS for platforms with
no PDC nor FIFOs, and let serial_core happily handle the CTS/RTS, it
refused to set the flow control when the user space asked for it.
This was because of a misunderstanding:
It's not that platforms without PDC and FIFO can't do flow control at
all, they just can't enable the USART controller feature relative to
flag ATMEL_US_USMODE_HWHS.
And, again, this feature is *not* mandatory for the flow control to
work.
So, now, all atmel platforms with no PDC and no FIFO (SAM9G35, SAMA5D3,
etc.) can't use flow control anymore.
That's the reason of this patch series.
And as the controller flow control feature only works with PDC and
FIFOs, the logic would be to set the ATMEL_US_USMODE_HWHS like that:
if ((termios->c_cflag & CRTSCTS) &&
!mctrl_gpio_use_rtscts(atmel_port->gpios) &&
(atmel_use_pdc_rx(port) || atmel_use_fifo(port))) {
mode |= ATMEL_US_USMODE_HWHS;
}
I added the mctrl_gpio_use_rtscts() test, because:
- There's no point using the ATMEL_US_USMODE_HWHS feature when CTS/RTS
are driven by GPIOs, it doesn't make any sense.
- And it simply doesn't work because the transmitter is shut down.
(and that's the other reason of this patch series)
For the mctrl_gpio_use_rtscts() function, I agree that it may be atmel
specific, and I could implement as something like
atmel_use_{c,r}ts_gpio().
I'll have soon other hardware to test this on, and I'll resend a series
after that.
regards,
Richard
^ permalink raw reply
* [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate
From: Fabio Estevam @ 2016-10-07 15:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007141224.GA18011@lime>
Hi Emil,
On Fri, Oct 7, 2016 at 11:12 AM, Emil Lundmark <emil@limesaudio.com> wrote:
> I realize that the two patches in this series does not actually depend on
> each other. This is my first contribution to Linux so I wonder if I should
> resubmit these as two separate patches instead?
>
> For example, what if the second patch in the series is not needed? Do you
> only accept the first patch then? Or what if I need to revise the second
> patch? It seems unnecessary to include the first patch in that case.
>
> I also got the threading wrong, but thats another story.
It is better to resend these two patches and mark them as v2:
[PATCH v2 1/2]
[PATCH v2 2/2]
Then put below the --- line what has changed from the previous one. If
nothing changed just put "None".
I am wondering if your patch series tries to fix the regression
reported by Ken Lin or is it unrelated?
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-October/460451.html
^ permalink raw reply
* [PATCH V3 8/8] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops
From: Sricharan @ 2016-10-07 15:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475600632-21289-9-git-send-email-sricharan@codeaurora.org>
Hi,
>-----Original Message-----
>From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org] On Behalf Of Sricharan R
>Sent: Tuesday, October 04, 2016 10:34 PM
>To: will.deacon at arm.com; robin.murphy at arm.com; joro at 8bytes.org; iommu at lists.linux-foundation.org; linux-arm-
>kernel at lists.infradead.org; linux-arm-msm at vger.kernel.org; laurent.pinchart at ideasonboard.com; m.szyprowski at samsung.com;
>tfiga at chromium.org; srinivas.kandagatla at linaro.org
>Cc: sricharan at codeaurora.org
>Subject: [PATCH V3 8/8] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops
>
>With arch_setup_dma_ops now being called late during device's probe after the
>device's iommu is probed, the notifier trick required to handle the early
>setup of dma_ops before the iommu group gets created is not required.
>So removing the notifier's here.
>
>Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>---
> arch/arm64/mm/dma-mapping.c | 100 ++------------------------------------------
> 1 file changed, 3 insertions(+), 97 deletions(-)
>
>diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
>index faf4b92..eb593af 100644
>--- a/arch/arm64/mm/dma-mapping.c
>+++ b/arch/arm64/mm/dma-mapping.c
>@@ -799,24 +799,6 @@ static struct dma_map_ops iommu_dma_ops = {
> .mapping_error = iommu_dma_mapping_error,
> };
>
>-/*
>- * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
>- * everything it needs to - the device is only partially created and the
>- * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
>- * need this delayed attachment dance. Once IOMMU probe ordering is sorted
>- * to move the arch_setup_dma_ops() call later, all the notifier bits below
>- * become unnecessary, and will go away.
>- */
>-struct iommu_dma_notifier_data {
>- struct list_head list;
>- struct device *dev;
>- const struct iommu_ops *ops;
>- u64 dma_base;
>- u64 size;
>-};
>-static LIST_HEAD(iommu_dma_masters);
>-static DEFINE_MUTEX(iommu_dma_notifier_lock);
>-
> static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
> u64 dma_base, u64 size)
> {
>@@ -837,79 +819,9 @@ static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
> return true;
> }
>
>-static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
>- u64 dma_base, u64 size)
>-{
>- struct iommu_dma_notifier_data *iommudata;
>-
>- iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
>- if (!iommudata)
>- return;
>-
>- iommudata->dev = dev;
>- iommudata->ops = ops;
>- iommudata->dma_base = dma_base;
>- iommudata->size = size;
>-
>- mutex_lock(&iommu_dma_notifier_lock);
>- list_add(&iommudata->list, &iommu_dma_masters);
>- mutex_unlock(&iommu_dma_notifier_lock);
>-}
>-
>-static int __iommu_attach_notifier(struct notifier_block *nb,
>- unsigned long action, void *data)
>-{
>- struct iommu_dma_notifier_data *master, *tmp;
>-
>- if (action != BUS_NOTIFY_BIND_DRIVER)
>- return 0;
>-
>- mutex_lock(&iommu_dma_notifier_lock);
>- list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
>- if (data == master->dev && do_iommu_attach(master->dev,
>- master->ops, master->dma_base, master->size)) {
>- list_del(&master->list);
>- kfree(master);
>- break;
>- }
>- }
>- mutex_unlock(&iommu_dma_notifier_lock);
>- return 0;
>-}
>-
>-static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
>-{
>- struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
>- int ret;
>-
>- if (!nb)
>- return -ENOMEM;
>-
>- nb->notifier_call = __iommu_attach_notifier;
>-
>- ret = bus_register_notifier(bus, nb);
>- if (ret) {
>- pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops unavailable on bus '%s'\n",
>- bus->name);
>- kfree(nb);
>- }
>- return ret;
>-}
>-
> static int __init __iommu_dma_init(void)
> {
>- int ret;
>-
>- ret = iommu_dma_init();
>- if (!ret)
>- ret = register_iommu_dma_ops_notifier(&platform_bus_type);
>- if (!ret)
>- ret = register_iommu_dma_ops_notifier(&amba_bustype);
>-#ifdef CONFIG_PCI
>- if (!ret)
>- ret = register_iommu_dma_ops_notifier(&pci_bus_type);
>-#endif
>- return ret;
>+ return iommu_dma_init();
> }
> arch_initcall(__iommu_dma_init);
>
>@@ -920,18 +832,12 @@ static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>
> if (!ops)
> return;
>- /*
>- * TODO: As a concession to the future, we're ready to handle being
>- * called both early and late (i.e. after bus_add_device). Once all
>- * the platform bus code is reworked to call us late and the notifier
>- * junk above goes away, move the body of do_iommu_attach here.
>- */
>+
> group = iommu_group_get(dev);
>+
> if (group) {
> do_iommu_attach(dev, ops, dma_base, size);
> iommu_group_put(group);
>- } else {
>- queue_iommu_attach(dev, ops, dma_base, size);
> }
> }
>
I should have has this as well for being removed,
From: Sricharan R <sricharan@codeaurora.org>
Date: Fri, 7 Oct 2016 19:20:21 +0530
Subject: [PATCH] iommu:/arm-smmu: Avoid early iommu device registration
of_platform_device_create was called early in the init
to have the smmu probed before the master. But now with
the probe deferral, this is not needed.
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
drivers/iommu/arm-smmu.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index c841eb7..083489e4 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2066,9 +2066,6 @@ static int __init arm_smmu_of_init(struct device_node *np)
if (ret)
return ret;
- if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
- return -ENODEV;
-
return 0;
}
IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", arm_smmu_of_init);
--
1.8.2.1
Regards,
Sricharan
^ permalink raw reply related
* [PATCH 1/3] mtd: s3c2410: make ecc mode configurable via platform data
From: Krzysztof Kozlowski @ 2016-10-07 15:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475711217-974-2-git-send-email-sergio.prado@e-labworks.com>
On Wed, Oct 05, 2016 at 08:46:55PM -0300, Sergio Prado wrote:
> Removing CONFIG_MTD_NAND_S3C2410_HWECC option and adding a ecc_mode
> field in the drivers's platform data structure so it can be selectable
> via platform data.
>
> Also setting this field to NAND_ECC_SOFT in all boards using this
> driver since none of them had CONFIG_MTD_NAND_S3C2410_HWECC enabled.
>
> Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
> ---
> arch/arm/mach-s3c24xx/common-smdk.c | 1 +
> arch/arm/mach-s3c24xx/mach-anubis.c | 1 +
> arch/arm/mach-s3c24xx/mach-at2440evb.c | 1 +
> arch/arm/mach-s3c24xx/mach-bast.c | 1 +
> arch/arm/mach-s3c24xx/mach-gta02.c | 1 +
> arch/arm/mach-s3c24xx/mach-jive.c | 1 +
> arch/arm/mach-s3c24xx/mach-mini2440.c | 1 +
> arch/arm/mach-s3c24xx/mach-osiris.c | 1 +
> arch/arm/mach-s3c24xx/mach-qt2410.c | 1 +
> arch/arm/mach-s3c24xx/mach-rx1950.c | 1 +
> arch/arm/mach-s3c24xx/mach-rx3715.c | 1 +
> arch/arm/mach-s3c24xx/mach-vstms.c | 1 +
> arch/arm/mach-s3c64xx/mach-hmt.c | 1 +
> arch/arm/mach-s3c64xx/mach-mini6410.c | 1 +
> arch/arm/mach-s3c64xx/mach-real6410.c | 1 +
> drivers/mtd/nand/Kconfig | 9 --
> drivers/mtd/nand/s3c2410.c | 119 +++++++++++++------------
> include/linux/platform_data/mtd-nand-s3c2410.h | 6 +-
> 18 files changed, 79 insertions(+), 70 deletions(-)
>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate
From: Emil Lundmark @ 2016-10-07 16:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOMZO5CYST3fw1q11RidmSMepsUpaHg91T5gD_c6XA6vsAsJLQ@mail.gmail.com>
On Fri, Oct 07, 2016 at 12:34:42PM -0300, Fabio Estevam wrote:
> Hi Emil,
>
> On Fri, Oct 7, 2016 at 11:12 AM, Emil Lundmark <emil@limesaudio.com> wrote:
> > I realize that the two patches in this series does not actually depend on
> > each other. This is my first contribution to Linux so I wonder if I should
> > resubmit these as two separate patches instead?
> >
> > For example, what if the second patch in the series is not needed? Do you
> > only accept the first patch then? Or what if I need to revise the second
> > patch? It seems unnecessary to include the first patch in that case.
> >
> > I also got the threading wrong, but thats another story.
>
> It is better to resend these two patches and mark them as v2:
> [PATCH v2 1/2]
> [PATCH v2 2/2]
>
> Then put below the --- line what has changed from the previous one. If
> nothing changed just put "None".
>
> I am wondering if your patch series tries to fix the regression
> reported by Ken Lin or is it unrelated?
> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-October/460451.html
I was not aware of that issue before but it seems related. Only the first
patch in the series is relevant for solving the issue I was experiencing.
I can't tell if it also solves theirs, but it's probable.
The second part is really only nitpicking I discovered when debugging. Its
intention is to allow a precision of 1 Hz instead of (most likely) 24 Hz.
But when is that important for MHz clocks anyway?
--
Emil Lundmark
^ permalink raw reply
* [PATCH 1/5] PCI: aardvark: Name private struct pointer "advk" consistently
From: Bjorn Helgaas @ 2016-10-07 16:20 UTC (permalink / raw)
To: linux-arm-kernel
Use a device-specific name, "advk", for struct advk_pcie pointers to hint
that this is device-specific information. No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/host/pci-aardvark.c | 370 +++++++++++++++++++--------------------
1 file changed, 183 insertions(+), 187 deletions(-)
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
index e4a5b7e..fd0e6af 100644
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -209,40 +209,40 @@ struct advk_pcie {
int root_bus_nr;
};
-static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg)
+static inline void advk_writel(struct advk_pcie *advk, u32 val, u64 reg)
{
- writel(val, pcie->base + reg);
+ writel(val, advk->base + reg);
}
-static inline u32 advk_readl(struct advk_pcie *pcie, u64 reg)
+static inline u32 advk_readl(struct advk_pcie *advk, u64 reg)
{
- return readl(pcie->base + reg);
+ return readl(advk->base + reg);
}
-static int advk_pcie_link_up(struct advk_pcie *pcie)
+static int advk_pcie_link_up(struct advk_pcie *advk)
{
u32 val, ltssm_state;
- val = advk_readl(pcie, CFG_REG);
+ val = advk_readl(advk, CFG_REG);
ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK;
return ltssm_state >= LTSSM_L0;
}
-static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
+static int advk_pcie_wait_for_link(struct advk_pcie *advk)
{
int retries;
/* check if the link is up or not */
for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
- if (advk_pcie_link_up(pcie)) {
- dev_info(&pcie->pdev->dev, "link up\n");
+ if (advk_pcie_link_up(advk)) {
+ dev_info(&advk->pdev->dev, "link up\n");
return 0;
}
usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
}
- dev_err(&pcie->pdev->dev, "link never came up\n");
+ dev_err(&advk->pdev->dev, "link never came up\n");
return -ETIMEDOUT;
}
@@ -251,136 +251,136 @@ static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
* Set PCIe address window register which could be used for memory
* mapping.
*/
-static void advk_pcie_set_ob_win(struct advk_pcie *pcie,
+static void advk_pcie_set_ob_win(struct advk_pcie *advk,
u32 win_num, u32 match_ms,
u32 match_ls, u32 mask_ms,
u32 mask_ls, u32 remap_ms,
u32 remap_ls, u32 action)
{
- advk_writel(pcie, match_ls, OB_WIN_MATCH_LS(win_num));
- advk_writel(pcie, match_ms, OB_WIN_MATCH_MS(win_num));
- advk_writel(pcie, mask_ms, OB_WIN_MASK_MS(win_num));
- advk_writel(pcie, mask_ls, OB_WIN_MASK_LS(win_num));
- advk_writel(pcie, remap_ms, OB_WIN_REMAP_MS(win_num));
- advk_writel(pcie, remap_ls, OB_WIN_REMAP_LS(win_num));
- advk_writel(pcie, action, OB_WIN_ACTIONS(win_num));
- advk_writel(pcie, match_ls | BIT(0), OB_WIN_MATCH_LS(win_num));
+ advk_writel(advk, match_ls, OB_WIN_MATCH_LS(win_num));
+ advk_writel(advk, match_ms, OB_WIN_MATCH_MS(win_num));
+ advk_writel(advk, mask_ms, OB_WIN_MASK_MS(win_num));
+ advk_writel(advk, mask_ls, OB_WIN_MASK_LS(win_num));
+ advk_writel(advk, remap_ms, OB_WIN_REMAP_MS(win_num));
+ advk_writel(advk, remap_ls, OB_WIN_REMAP_LS(win_num));
+ advk_writel(advk, action, OB_WIN_ACTIONS(win_num));
+ advk_writel(advk, match_ls | BIT(0), OB_WIN_MATCH_LS(win_num));
}
-static void advk_pcie_setup_hw(struct advk_pcie *pcie)
+static void advk_pcie_setup_hw(struct advk_pcie *advk)
{
u32 reg;
int i;
/* Point PCIe unit MBUS decode windows to DRAM space */
for (i = 0; i < 8; i++)
- advk_pcie_set_ob_win(pcie, i, 0, 0, 0, 0, 0, 0, 0);
+ advk_pcie_set_ob_win(advk, i, 0, 0, 0, 0, 0, 0, 0);
/* Set to Direct mode */
- reg = advk_readl(pcie, CTRL_CONFIG_REG);
+ reg = advk_readl(advk, CTRL_CONFIG_REG);
reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT);
reg |= ((PCIE_CORE_MODE_DIRECT & CTRL_MODE_MASK) << CTRL_MODE_SHIFT);
- advk_writel(pcie, reg, CTRL_CONFIG_REG);
+ advk_writel(advk, reg, CTRL_CONFIG_REG);
/* Set PCI global control register to RC mode */
- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
+ reg = advk_readl(advk, PCIE_CORE_CTRL0_REG);
reg |= (IS_RC_MSK << IS_RC_SHIFT);
- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+ advk_writel(advk, reg, PCIE_CORE_CTRL0_REG);
/* Set Advanced Error Capabilities and Control PF0 register */
reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX |
PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN |
PCIE_CORE_ERR_CAPCTL_ECRC_CHCK |
PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV;
- advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG);
+ advk_writel(advk, reg, PCIE_CORE_ERR_CAPCTL_REG);
/* Set PCIe Device Control and Status 1 PF0 register */
reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
(7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE |
PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT;
- advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
+ advk_writel(advk, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
/* Program PCIe Control 2 to disable strict ordering */
reg = PCIE_CORE_CTRL2_RESERVED |
PCIE_CORE_CTRL2_TD_ENABLE;
- advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
+ advk_writel(advk, reg, PCIE_CORE_CTRL2_REG);
/* Set GEN2 */
- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
+ reg = advk_readl(advk, PCIE_CORE_CTRL0_REG);
reg &= ~PCIE_GEN_SEL_MSK;
reg |= SPEED_GEN_2;
- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+ advk_writel(advk, reg, PCIE_CORE_CTRL0_REG);
/* Set lane X1 */
- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
+ reg = advk_readl(advk, PCIE_CORE_CTRL0_REG);
reg &= ~LANE_CNT_MSK;
reg |= LANE_COUNT_1;
- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+ advk_writel(advk, reg, PCIE_CORE_CTRL0_REG);
/* Enable link training */
- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
+ reg = advk_readl(advk, PCIE_CORE_CTRL0_REG);
reg |= LINK_TRAINING_EN;
- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+ advk_writel(advk, reg, PCIE_CORE_CTRL0_REG);
/* Enable MSI */
- reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG);
+ reg = advk_readl(advk, PCIE_CORE_CTRL2_REG);
reg |= PCIE_CORE_CTRL2_MSI_ENABLE;
- advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
+ advk_writel(advk, reg, PCIE_CORE_CTRL2_REG);
/* Clear all interrupts */
- advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG);
- advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG);
- advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
+ advk_writel(advk, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG);
+ advk_writel(advk, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG);
+ advk_writel(advk, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
/* Disable All ISR0/1 Sources */
reg = PCIE_ISR0_ALL_MASK;
reg &= ~PCIE_ISR0_MSI_INT_PENDING;
- advk_writel(pcie, reg, PCIE_ISR0_MASK_REG);
+ advk_writel(advk, reg, PCIE_ISR0_MASK_REG);
- advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG);
+ advk_writel(advk, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG);
/* Unmask all MSI's */
- advk_writel(pcie, 0, PCIE_MSI_MASK_REG);
+ advk_writel(advk, 0, PCIE_MSI_MASK_REG);
/* Enable summary interrupt for GIC SPI source */
reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK);
- advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG);
+ advk_writel(advk, reg, HOST_CTRL_INT_MASK_REG);
- reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG);
+ reg = advk_readl(advk, PCIE_CORE_CTRL2_REG);
reg |= PCIE_CORE_CTRL2_OB_WIN_ENABLE;
- advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
+ advk_writel(advk, reg, PCIE_CORE_CTRL2_REG);
/* Bypass the address window mapping for PIO */
- reg = advk_readl(pcie, PIO_CTRL);
+ reg = advk_readl(advk, PIO_CTRL);
reg |= PIO_CTRL_ADDR_WIN_DISABLE;
- advk_writel(pcie, reg, PIO_CTRL);
+ advk_writel(advk, reg, PIO_CTRL);
/* Start link training */
- reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
+ reg = advk_readl(advk, PCIE_CORE_LINK_CTRL_STAT_REG);
reg |= PCIE_CORE_LINK_TRAINING;
- advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
+ advk_writel(advk, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
- advk_pcie_wait_for_link(pcie);
+ advk_pcie_wait_for_link(advk);
reg = PCIE_CORE_LINK_L0S_ENTRY |
(1 << PCIE_CORE_LINK_WIDTH_SHIFT);
- advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
+ advk_writel(advk, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
- reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
+ reg = advk_readl(advk, PCIE_CORE_CMD_STATUS_REG);
reg |= PCIE_CORE_CMD_MEM_ACCESS_EN |
PCIE_CORE_CMD_IO_ACCESS_EN |
PCIE_CORE_CMD_MEM_IO_REQ_EN;
- advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG);
+ advk_writel(advk, reg, PCIE_CORE_CMD_STATUS_REG);
}
-static void advk_pcie_check_pio_status(struct advk_pcie *pcie)
+static void advk_pcie_check_pio_status(struct advk_pcie *advk)
{
u32 reg;
unsigned int status;
char *strcomp_status, *str_posted;
- reg = advk_readl(pcie, PIO_STAT);
+ reg = advk_readl(advk, PIO_STAT);
status = (reg & PIO_COMPLETION_STATUS_MASK) >>
PIO_COMPLETION_STATUS_SHIFT;
@@ -407,11 +407,11 @@ static void advk_pcie_check_pio_status(struct advk_pcie *pcie)
else
str_posted = "Posted";
- dev_err(&pcie->pdev->dev, "%s PIO Response Status: %s, %#x @ %#x\n",
- str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS));
+ dev_err(&advk->pdev->dev, "%s PIO Response Status: %s, %#x @ %#x\n",
+ str_posted, strcomp_status, reg, advk_readl(advk, PIO_ADDR_LS));
}
-static int advk_pcie_wait_pio(struct advk_pcie *pcie)
+static int advk_pcie_wait_pio(struct advk_pcie *advk)
{
unsigned long timeout;
@@ -420,20 +420,20 @@ static int advk_pcie_wait_pio(struct advk_pcie *pcie)
while (time_before(jiffies, timeout)) {
u32 start, isr;
- start = advk_readl(pcie, PIO_START);
- isr = advk_readl(pcie, PIO_ISR);
+ start = advk_readl(advk, PIO_START);
+ isr = advk_readl(advk, PIO_ISR);
if (!start && isr)
return 0;
}
- dev_err(&pcie->pdev->dev, "config read/write timed out\n");
+ dev_err(&advk->pdev->dev, "config read/write timed out\n");
return -ETIMEDOUT;
}
static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 *val)
{
- struct advk_pcie *pcie = bus->sysdata;
+ struct advk_pcie *advk = bus->sysdata;
u32 reg;
int ret;
@@ -443,37 +443,37 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
}
/* Start PIO */
- advk_writel(pcie, 0, PIO_START);
- advk_writel(pcie, 1, PIO_ISR);
+ advk_writel(advk, 0, PIO_START);
+ advk_writel(advk, 1, PIO_ISR);
/* Program the control register */
- reg = advk_readl(pcie, PIO_CTRL);
+ reg = advk_readl(advk, PIO_CTRL);
reg &= ~PIO_CTRL_TYPE_MASK;
- if (bus->number == pcie->root_bus_nr)
+ if (bus->number == advk->root_bus_nr)
reg |= PCIE_CONFIG_RD_TYPE0;
else
reg |= PCIE_CONFIG_RD_TYPE1;
- advk_writel(pcie, reg, PIO_CTRL);
+ advk_writel(advk, reg, PIO_CTRL);
/* Program the address registers */
reg = PCIE_BDF(devfn) | PCIE_CONF_REG(where);
- advk_writel(pcie, reg, PIO_ADDR_LS);
- advk_writel(pcie, 0, PIO_ADDR_MS);
+ advk_writel(advk, reg, PIO_ADDR_LS);
+ advk_writel(advk, 0, PIO_ADDR_MS);
/* Program the data strobe */
- advk_writel(pcie, 0xf, PIO_WR_DATA_STRB);
+ advk_writel(advk, 0xf, PIO_WR_DATA_STRB);
/* Start the transfer */
- advk_writel(pcie, 1, PIO_START);
+ advk_writel(advk, 1, PIO_START);
- ret = advk_pcie_wait_pio(pcie);
+ ret = advk_pcie_wait_pio(advk);
if (ret < 0)
return PCIBIOS_SET_FAILED;
- advk_pcie_check_pio_status(pcie);
+ advk_pcie_check_pio_status(advk);
/* Get the read result */
- *val = advk_readl(pcie, PIO_RD_DATA);
+ *val = advk_readl(advk, PIO_RD_DATA);
if (size == 1)
*val = (*val >> (8 * (where & 3))) & 0xff;
else if (size == 2)
@@ -485,7 +485,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 val)
{
- struct advk_pcie *pcie = bus->sysdata;
+ struct advk_pcie *advk = bus->sysdata;
u32 reg;
u32 data_strobe = 0x0;
int offset;
@@ -498,22 +498,22 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
return PCIBIOS_SET_FAILED;
/* Start PIO */
- advk_writel(pcie, 0, PIO_START);
- advk_writel(pcie, 1, PIO_ISR);
+ advk_writel(advk, 0, PIO_START);
+ advk_writel(advk, 1, PIO_ISR);
/* Program the control register */
- reg = advk_readl(pcie, PIO_CTRL);
+ reg = advk_readl(advk, PIO_CTRL);
reg &= ~PIO_CTRL_TYPE_MASK;
- if (bus->number == pcie->root_bus_nr)
+ if (bus->number == advk->root_bus_nr)
reg |= PCIE_CONFIG_WR_TYPE0;
else
reg |= PCIE_CONFIG_WR_TYPE1;
- advk_writel(pcie, reg, PIO_CTRL);
+ advk_writel(advk, reg, PIO_CTRL);
/* Program the address registers */
reg = PCIE_CONF_ADDR(bus->number, devfn, where);
- advk_writel(pcie, reg, PIO_ADDR_LS);
- advk_writel(pcie, 0, PIO_ADDR_MS);
+ advk_writel(advk, reg, PIO_ADDR_LS);
+ advk_writel(advk, 0, PIO_ADDR_MS);
/* Calculate the write strobe */
offset = where & 0x3;
@@ -521,19 +521,19 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
data_strobe = GENMASK(size - 1, 0) << offset;
/* Program the data register */
- advk_writel(pcie, reg, PIO_WR_DATA);
+ advk_writel(advk, reg, PIO_WR_DATA);
/* Program the data strobe */
- advk_writel(pcie, data_strobe, PIO_WR_DATA_STRB);
+ advk_writel(advk, data_strobe, PIO_WR_DATA_STRB);
/* Start the transfer */
- advk_writel(pcie, 1, PIO_START);
+ advk_writel(advk, 1, PIO_START);
- ret = advk_pcie_wait_pio(pcie);
+ ret = advk_pcie_wait_pio(advk);
if (ret < 0)
return PCIBIOS_SET_FAILED;
- advk_pcie_check_pio_status(pcie);
+ advk_pcie_check_pio_status(advk);
return PCIBIOS_SUCCESSFUL;
}
@@ -543,37 +543,37 @@ static struct pci_ops advk_pcie_ops = {
.write = advk_pcie_wr_conf,
};
-static int advk_pcie_alloc_msi(struct advk_pcie *pcie)
+static int advk_pcie_alloc_msi(struct advk_pcie *advk)
{
int hwirq;
- mutex_lock(&pcie->msi_used_lock);
- hwirq = find_first_zero_bit(pcie->msi_irq_in_use, MSI_IRQ_NUM);
+ mutex_lock(&advk->msi_used_lock);
+ hwirq = find_first_zero_bit(advk->msi_irq_in_use, MSI_IRQ_NUM);
if (hwirq >= MSI_IRQ_NUM)
hwirq = -ENOSPC;
else
- set_bit(hwirq, pcie->msi_irq_in_use);
- mutex_unlock(&pcie->msi_used_lock);
+ set_bit(hwirq, advk->msi_irq_in_use);
+ mutex_unlock(&advk->msi_used_lock);
return hwirq;
}
-static void advk_pcie_free_msi(struct advk_pcie *pcie, int hwirq)
+static void advk_pcie_free_msi(struct advk_pcie *advk, int hwirq)
{
- mutex_lock(&pcie->msi_used_lock);
- if (!test_bit(hwirq, pcie->msi_irq_in_use))
- dev_err(&pcie->pdev->dev, "trying to free unused MSI#%d\n",
+ mutex_lock(&advk->msi_used_lock);
+ if (!test_bit(hwirq, advk->msi_irq_in_use))
+ dev_err(&advk->pdev->dev, "trying to free unused MSI#%d\n",
hwirq);
else
- clear_bit(hwirq, pcie->msi_irq_in_use);
- mutex_unlock(&pcie->msi_used_lock);
+ clear_bit(hwirq, advk->msi_irq_in_use);
+ mutex_unlock(&advk->msi_used_lock);
}
static int advk_pcie_setup_msi_irq(struct msi_controller *chip,
struct pci_dev *pdev,
struct msi_desc *desc)
{
- struct advk_pcie *pcie = pdev->bus->sysdata;
+ struct advk_pcie *advk = pdev->bus->sysdata;
struct msi_msg msg;
int virq, hwirq;
phys_addr_t msi_msg_phys;
@@ -582,19 +582,19 @@ static int advk_pcie_setup_msi_irq(struct msi_controller *chip,
if (desc->msi_attrib.is_msix)
return -EINVAL;
- hwirq = advk_pcie_alloc_msi(pcie);
+ hwirq = advk_pcie_alloc_msi(advk);
if (hwirq < 0)
return hwirq;
- virq = irq_create_mapping(pcie->msi_domain, hwirq);
+ virq = irq_create_mapping(advk->msi_domain, hwirq);
if (!virq) {
- advk_pcie_free_msi(pcie, hwirq);
+ advk_pcie_free_msi(advk, hwirq);
return -EINVAL;
}
irq_set_msi_desc(virq, desc);
- msi_msg_phys = virt_to_phys(&pcie->msi_msg);
+ msi_msg_phys = virt_to_phys(&advk->msi_msg);
msg.address_lo = lower_32_bits(msi_msg_phys);
msg.address_hi = upper_32_bits(msi_msg_phys);
@@ -610,19 +610,19 @@ static void advk_pcie_teardown_msi_irq(struct msi_controller *chip,
{
struct irq_data *d = irq_get_irq_data(irq);
struct msi_desc *msi = irq_data_get_msi_desc(d);
- struct advk_pcie *pcie = msi_desc_to_pci_sysdata(msi);
+ struct advk_pcie *advk = msi_desc_to_pci_sysdata(msi);
unsigned long hwirq = d->hwirq;
irq_dispose_mapping(irq);
- advk_pcie_free_msi(pcie, hwirq);
+ advk_pcie_free_msi(advk, hwirq);
}
static int advk_pcie_msi_map(struct irq_domain *domain,
unsigned int virq, irq_hw_number_t hw)
{
- struct advk_pcie *pcie = domain->host_data;
+ struct advk_pcie *advk = domain->host_data;
- irq_set_chip_and_handler(virq, &pcie->msi_irq_chip,
+ irq_set_chip_and_handler(virq, &advk->msi_irq_chip,
handle_simple_irq);
return 0;
@@ -634,36 +634,35 @@ static const struct irq_domain_ops advk_pcie_msi_irq_ops = {
static void advk_pcie_irq_mask(struct irq_data *d)
{
- struct advk_pcie *pcie = d->domain->host_data;
+ struct advk_pcie *advk = d->domain->host_data;
irq_hw_number_t hwirq = irqd_to_hwirq(d);
u32 mask;
- mask = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+ mask = advk_readl(advk, PCIE_ISR0_MASK_REG);
mask |= PCIE_ISR0_INTX_ASSERT(hwirq);
- advk_writel(pcie, mask, PCIE_ISR0_MASK_REG);
+ advk_writel(advk, mask, PCIE_ISR0_MASK_REG);
}
static void advk_pcie_irq_unmask(struct irq_data *d)
{
- struct advk_pcie *pcie = d->domain->host_data;
+ struct advk_pcie *advk = d->domain->host_data;
irq_hw_number_t hwirq = irqd_to_hwirq(d);
u32 mask;
- mask = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+ mask = advk_readl(advk, PCIE_ISR0_MASK_REG);
mask &= ~PCIE_ISR0_INTX_ASSERT(hwirq);
- advk_writel(pcie, mask, PCIE_ISR0_MASK_REG);
+ advk_writel(advk, mask, PCIE_ISR0_MASK_REG);
}
static int advk_pcie_irq_map(struct irq_domain *h,
unsigned int virq, irq_hw_number_t hwirq)
{
- struct advk_pcie *pcie = h->host_data;
+ struct advk_pcie *advk = h->host_data;
advk_pcie_irq_mask(irq_get_irq_data(virq));
irq_set_status_flags(virq, IRQ_LEVEL);
- irq_set_chip_and_handler(virq, &pcie->irq_chip,
- handle_level_irq);
- irq_set_chip_data(virq, pcie);
+ irq_set_chip_and_handler(virq, &advk->irq_chip, handle_level_irq);
+ irq_set_chip_data(virq, advk);
return 0;
}
@@ -673,16 +672,16 @@ static const struct irq_domain_ops advk_pcie_irq_domain_ops = {
.xlate = irq_domain_xlate_onecell,
};
-static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
+static int advk_pcie_init_msi_irq_domain(struct advk_pcie *advk)
{
- struct device *dev = &pcie->pdev->dev;
+ struct device *dev = &advk->pdev->dev;
struct device_node *node = dev->of_node;
struct irq_chip *msi_irq_chip;
struct msi_controller *msi;
phys_addr_t msi_msg_phys;
int ret;
- msi_irq_chip = &pcie->msi_irq_chip;
+ msi_irq_chip = &advk->msi_irq_chip;
msi_irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-msi",
dev_name(dev));
@@ -694,45 +693,43 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
msi_irq_chip->irq_mask = pci_msi_mask_irq;
msi_irq_chip->irq_unmask = pci_msi_unmask_irq;
- msi = &pcie->msi;
+ msi = &advk->msi;
msi->setup_irq = advk_pcie_setup_msi_irq;
msi->teardown_irq = advk_pcie_teardown_msi_irq;
msi->of_node = node;
- mutex_init(&pcie->msi_used_lock);
+ mutex_init(&advk->msi_used_lock);
- msi_msg_phys = virt_to_phys(&pcie->msi_msg);
+ msi_msg_phys = virt_to_phys(&advk->msi_msg);
- advk_writel(pcie, lower_32_bits(msi_msg_phys),
- PCIE_MSI_ADDR_LOW_REG);
- advk_writel(pcie, upper_32_bits(msi_msg_phys),
- PCIE_MSI_ADDR_HIGH_REG);
+ advk_writel(advk, lower_32_bits(msi_msg_phys), PCIE_MSI_ADDR_LOW_REG);
+ advk_writel(advk, upper_32_bits(msi_msg_phys), PCIE_MSI_ADDR_HIGH_REG);
- pcie->msi_domain =
+ advk->msi_domain =
irq_domain_add_linear(NULL, MSI_IRQ_NUM,
- &advk_pcie_msi_irq_ops, pcie);
- if (!pcie->msi_domain)
+ &advk_pcie_msi_irq_ops, advk);
+ if (!advk->msi_domain)
return -ENOMEM;
ret = of_pci_msi_chip_add(msi);
if (ret < 0) {
- irq_domain_remove(pcie->msi_domain);
+ irq_domain_remove(advk->msi_domain);
return ret;
}
return 0;
}
-static void advk_pcie_remove_msi_irq_domain(struct advk_pcie *pcie)
+static void advk_pcie_remove_msi_irq_domain(struct advk_pcie *advk)
{
- of_pci_msi_chip_remove(&pcie->msi);
- irq_domain_remove(pcie->msi_domain);
+ of_pci_msi_chip_remove(&advk->msi);
+ irq_domain_remove(advk->msi_domain);
}
-static int advk_pcie_init_irq_domain(struct advk_pcie *pcie)
+static int advk_pcie_init_irq_domain(struct advk_pcie *advk)
{
- struct device *dev = &pcie->pdev->dev;
+ struct device *dev = &advk->pdev->dev;
struct device_node *node = dev->of_node;
struct device_node *pcie_intc_node;
struct irq_chip *irq_chip;
@@ -743,7 +740,7 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie)
return -ENODEV;
}
- irq_chip = &pcie->irq_chip;
+ irq_chip = &advk->irq_chip;
irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq",
dev_name(dev));
@@ -756,10 +753,10 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie)
irq_chip->irq_mask_ack = advk_pcie_irq_mask;
irq_chip->irq_unmask = advk_pcie_irq_unmask;
- pcie->irq_domain =
+ advk->irq_domain =
irq_domain_add_linear(pcie_intc_node, LEGACY_IRQ_NUM,
- &advk_pcie_irq_domain_ops, pcie);
- if (!pcie->irq_domain) {
+ &advk_pcie_irq_domain_ops, advk);
+ if (!advk->irq_domain) {
dev_err(dev, "Failed to get a INTx IRQ domain\n");
of_node_put(pcie_intc_node);
return -ENOMEM;
@@ -768,106 +765,105 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie)
return 0;
}
-static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie)
+static void advk_pcie_remove_irq_domain(struct advk_pcie *advk)
{
- irq_domain_remove(pcie->irq_domain);
+ irq_domain_remove(advk->irq_domain);
}
-static void advk_pcie_handle_msi(struct advk_pcie *pcie)
+static void advk_pcie_handle_msi(struct advk_pcie *advk)
{
u32 msi_val, msi_mask, msi_status, msi_idx;
u16 msi_data;
- msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
- msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG);
+ msi_mask = advk_readl(advk, PCIE_MSI_MASK_REG);
+ msi_val = advk_readl(advk, PCIE_MSI_STATUS_REG);
msi_status = msi_val & ~msi_mask;
for (msi_idx = 0; msi_idx < MSI_IRQ_NUM; msi_idx++) {
if (!(BIT(msi_idx) & msi_status))
continue;
- advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG);
- msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & 0xFF;
+ advk_writel(advk, BIT(msi_idx), PCIE_MSI_STATUS_REG);
+ msi_data = advk_readl(advk, PCIE_MSI_PAYLOAD_REG) & 0xFF;
generic_handle_irq(msi_data);
}
- advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING,
- PCIE_ISR0_REG);
+ advk_writel(advk, PCIE_ISR0_MSI_INT_PENDING, PCIE_ISR0_REG);
}
-static void advk_pcie_handle_int(struct advk_pcie *pcie)
+static void advk_pcie_handle_int(struct advk_pcie *advk)
{
u32 val, mask, status;
int i, virq;
- val = advk_readl(pcie, PCIE_ISR0_REG);
- mask = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+ val = advk_readl(advk, PCIE_ISR0_REG);
+ mask = advk_readl(advk, PCIE_ISR0_MASK_REG);
status = val & ((~mask) & PCIE_ISR0_ALL_MASK);
if (!status) {
- advk_writel(pcie, val, PCIE_ISR0_REG);
+ advk_writel(advk, val, PCIE_ISR0_REG);
return;
}
/* Process MSI interrupts */
if (status & PCIE_ISR0_MSI_INT_PENDING)
- advk_pcie_handle_msi(pcie);
+ advk_pcie_handle_msi(advk);
/* Process legacy interrupts */
for (i = 0; i < LEGACY_IRQ_NUM; i++) {
if (!(status & PCIE_ISR0_INTX_ASSERT(i)))
continue;
- advk_writel(pcie, PCIE_ISR0_INTX_ASSERT(i),
+ advk_writel(advk, PCIE_ISR0_INTX_ASSERT(i),
PCIE_ISR0_REG);
- virq = irq_find_mapping(pcie->irq_domain, i);
+ virq = irq_find_mapping(advk->irq_domain, i);
generic_handle_irq(virq);
}
}
static irqreturn_t advk_pcie_irq_handler(int irq, void *arg)
{
- struct advk_pcie *pcie = arg;
+ struct advk_pcie *advk = arg;
u32 status;
- status = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG);
+ status = advk_readl(advk, HOST_CTRL_INT_STATUS_REG);
if (!(status & PCIE_IRQ_CORE_INT))
return IRQ_NONE;
- advk_pcie_handle_int(pcie);
+ advk_pcie_handle_int(advk);
/* Clear interrupt */
- advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG);
+ advk_writel(advk, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG);
return IRQ_HANDLED;
}
-static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
+static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *advk)
{
int err, res_valid = 0;
- struct device *dev = &pcie->pdev->dev;
+ struct device *dev = &advk->pdev->dev;
struct device_node *np = dev->of_node;
struct resource_entry *win, *tmp;
resource_size_t iobase;
- INIT_LIST_HEAD(&pcie->resources);
+ INIT_LIST_HEAD(&advk->resources);
- err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources,
+ err = of_pci_get_host_bridge_resources(np, 0, 0xff, &advk->resources,
&iobase);
if (err)
return err;
- err = devm_request_pci_bus_resources(dev, &pcie->resources);
+ err = devm_request_pci_bus_resources(dev, &advk->resources);
if (err)
goto out_release_res;
- resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
+ resource_list_for_each_entry_safe(win, tmp, &advk->resources) {
struct resource *res = win->res;
switch (resource_type(res)) {
case IORESOURCE_IO:
- advk_pcie_set_ob_win(pcie, 1,
+ advk_pcie_set_ob_win(advk, 1,
upper_32_bits(res->start),
lower_32_bits(res->start),
0, 0xF8000000, 0,
@@ -881,7 +877,7 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
}
break;
case IORESOURCE_MEM:
- advk_pcie_set_ob_win(pcie, 0,
+ advk_pcie_set_ob_win(advk, 0,
upper_32_bits(res->start),
lower_32_bits(res->start),
0x0, 0xF8000000, 0,
@@ -890,7 +886,7 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
res_valid |= !(res->flags & IORESOURCE_PREFETCH);
break;
case IORESOURCE_BUS:
- pcie->root_bus_nr = res->start;
+ advk->root_bus_nr = res->start;
break;
}
}
@@ -904,59 +900,59 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
return 0;
out_release_res:
- pci_free_resource_list(&pcie->resources);
+ pci_free_resource_list(&advk->resources);
return err;
}
static int advk_pcie_probe(struct platform_device *pdev)
{
- struct advk_pcie *pcie;
+ struct advk_pcie *advk;
struct resource *res;
struct pci_bus *bus, *child;
struct msi_controller *msi;
struct device_node *msi_node;
int ret, irq;
- pcie = devm_kzalloc(&pdev->dev, sizeof(struct advk_pcie),
+ advk = devm_kzalloc(&pdev->dev, sizeof(struct advk_pcie),
GFP_KERNEL);
- if (!pcie)
+ if (!advk)
return -ENOMEM;
- pcie->pdev = pdev;
- platform_set_drvdata(pdev, pcie);
+ advk->pdev = pdev;
+ platform_set_drvdata(pdev, advk);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pcie->base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(pcie->base))
- return PTR_ERR(pcie->base);
+ advk->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(advk->base))
+ return PTR_ERR(advk->base);
irq = platform_get_irq(pdev, 0);
ret = devm_request_irq(&pdev->dev, irq, advk_pcie_irq_handler,
IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie",
- pcie);
+ advk);
if (ret) {
dev_err(&pdev->dev, "Failed to register interrupt\n");
return ret;
}
- ret = advk_pcie_parse_request_of_pci_ranges(pcie);
+ ret = advk_pcie_parse_request_of_pci_ranges(advk);
if (ret) {
dev_err(&pdev->dev, "Failed to parse resources\n");
return ret;
}
- advk_pcie_setup_hw(pcie);
+ advk_pcie_setup_hw(advk);
- ret = advk_pcie_init_irq_domain(pcie);
+ ret = advk_pcie_init_irq_domain(advk);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize irq\n");
return ret;
}
- ret = advk_pcie_init_msi_irq_domain(pcie);
+ ret = advk_pcie_init_msi_irq_domain(advk);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize irq\n");
- advk_pcie_remove_irq_domain(pcie);
+ advk_pcie_remove_irq_domain(advk);
return ret;
}
@@ -967,10 +963,10 @@ static int advk_pcie_probe(struct platform_device *pdev)
msi = NULL;
bus = pci_scan_root_bus_msi(&pdev->dev, 0, &advk_pcie_ops,
- pcie, &pcie->resources, &pcie->msi);
+ advk, &advk->resources, &advk->msi);
if (!bus) {
- advk_pcie_remove_msi_irq_domain(pcie);
- advk_pcie_remove_irq_domain(pcie);
+ advk_pcie_remove_msi_irq_domain(advk);
+ advk_pcie_remove_irq_domain(advk);
return -ENOMEM;
}
^ permalink raw reply related
* [PATCH 2/5] PCI: aardvark: Reorder accessor functions
From: Bjorn Helgaas @ 2016-10-07 16:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007162053.22668.91420.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Reorder the accessors so the reader is first, as most other drivers do.
Uninline them. No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/host/pci-aardvark.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
index fd0e6af..3d629d4 100644
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -209,14 +209,14 @@ struct advk_pcie {
int root_bus_nr;
};
-static inline void advk_writel(struct advk_pcie *advk, u32 val, u64 reg)
+static u32 advk_readl(struct advk_pcie *advk, u64 reg)
{
- writel(val, advk->base + reg);
+ return readl(advk->base + reg);
}
-static inline u32 advk_readl(struct advk_pcie *advk, u64 reg)
+static void advk_writel(struct advk_pcie *advk, u32 val, u64 reg)
{
- return readl(advk->base + reg);
+ writel(val, advk->base + reg);
}
static int advk_pcie_link_up(struct advk_pcie *advk)
^ permalink raw reply related
* [PATCH 3/5] PCI: aardvark: Swap order of advk_write() reg/val arguments
From: Bjorn Helgaas @ 2016-10-07 16:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007162053.22668.91420.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Swap order of advk_writel() arguments to match the "dev, pos, val" order
used by pci_write_config_word() and other drivers. No functional change
intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/host/pci-aardvark.c | 109 +++++++++++++++++++--------------------
1 file changed, 54 insertions(+), 55 deletions(-)
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
index 3d629d4..af6312a 100644
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -214,7 +214,7 @@ static u32 advk_readl(struct advk_pcie *advk, u64 reg)
return readl(advk->base + reg);
}
-static void advk_writel(struct advk_pcie *advk, u32 val, u64 reg)
+static void advk_writel(struct advk_pcie *advk, u64 reg, u32 val)
{
writel(val, advk->base + reg);
}
@@ -257,14 +257,14 @@ static void advk_pcie_set_ob_win(struct advk_pcie *advk,
u32 mask_ls, u32 remap_ms,
u32 remap_ls, u32 action)
{
- advk_writel(advk, match_ls, OB_WIN_MATCH_LS(win_num));
- advk_writel(advk, match_ms, OB_WIN_MATCH_MS(win_num));
- advk_writel(advk, mask_ms, OB_WIN_MASK_MS(win_num));
- advk_writel(advk, mask_ls, OB_WIN_MASK_LS(win_num));
- advk_writel(advk, remap_ms, OB_WIN_REMAP_MS(win_num));
- advk_writel(advk, remap_ls, OB_WIN_REMAP_LS(win_num));
- advk_writel(advk, action, OB_WIN_ACTIONS(win_num));
- advk_writel(advk, match_ls | BIT(0), OB_WIN_MATCH_LS(win_num));
+ advk_writel(advk, OB_WIN_MATCH_LS(win_num), match_ls);
+ advk_writel(advk, OB_WIN_MATCH_MS(win_num), match_ms);
+ advk_writel(advk, OB_WIN_MASK_MS(win_num), mask_ms);
+ advk_writel(advk, OB_WIN_MASK_LS(win_num), mask_ls);
+ advk_writel(advk, OB_WIN_REMAP_MS(win_num), remap_ms);
+ advk_writel(advk, OB_WIN_REMAP_LS(win_num), remap_ls);
+ advk_writel(advk, OB_WIN_ACTIONS(win_num), action);
+ advk_writel(advk, OB_WIN_MATCH_LS(win_num), match_ls | BIT(0));
}
static void advk_pcie_setup_hw(struct advk_pcie *advk)
@@ -280,98 +280,98 @@ static void advk_pcie_setup_hw(struct advk_pcie *advk)
reg = advk_readl(advk, CTRL_CONFIG_REG);
reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT);
reg |= ((PCIE_CORE_MODE_DIRECT & CTRL_MODE_MASK) << CTRL_MODE_SHIFT);
- advk_writel(advk, reg, CTRL_CONFIG_REG);
+ advk_writel(advk, CTRL_CONFIG_REG, reg);
/* Set PCI global control register to RC mode */
reg = advk_readl(advk, PCIE_CORE_CTRL0_REG);
reg |= (IS_RC_MSK << IS_RC_SHIFT);
- advk_writel(advk, reg, PCIE_CORE_CTRL0_REG);
+ advk_writel(advk, PCIE_CORE_CTRL0_REG, reg);
/* Set Advanced Error Capabilities and Control PF0 register */
reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX |
PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN |
PCIE_CORE_ERR_CAPCTL_ECRC_CHCK |
PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV;
- advk_writel(advk, reg, PCIE_CORE_ERR_CAPCTL_REG);
+ advk_writel(advk, PCIE_CORE_ERR_CAPCTL_REG, reg);
/* Set PCIe Device Control and Status 1 PF0 register */
reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
(7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE |
PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT;
- advk_writel(advk, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
+ advk_writel(advk, PCIE_CORE_DEV_CTRL_STATS_REG, reg);
/* Program PCIe Control 2 to disable strict ordering */
reg = PCIE_CORE_CTRL2_RESERVED |
PCIE_CORE_CTRL2_TD_ENABLE;
- advk_writel(advk, reg, PCIE_CORE_CTRL2_REG);
+ advk_writel(advk, PCIE_CORE_CTRL2_REG, reg);
/* Set GEN2 */
reg = advk_readl(advk, PCIE_CORE_CTRL0_REG);
reg &= ~PCIE_GEN_SEL_MSK;
reg |= SPEED_GEN_2;
- advk_writel(advk, reg, PCIE_CORE_CTRL0_REG);
+ advk_writel(advk, PCIE_CORE_CTRL0_REG, reg);
/* Set lane X1 */
reg = advk_readl(advk, PCIE_CORE_CTRL0_REG);
reg &= ~LANE_CNT_MSK;
reg |= LANE_COUNT_1;
- advk_writel(advk, reg, PCIE_CORE_CTRL0_REG);
+ advk_writel(advk, PCIE_CORE_CTRL0_REG, reg);
/* Enable link training */
reg = advk_readl(advk, PCIE_CORE_CTRL0_REG);
reg |= LINK_TRAINING_EN;
- advk_writel(advk, reg, PCIE_CORE_CTRL0_REG);
+ advk_writel(advk, PCIE_CORE_CTRL0_REG, reg);
/* Enable MSI */
reg = advk_readl(advk, PCIE_CORE_CTRL2_REG);
reg |= PCIE_CORE_CTRL2_MSI_ENABLE;
- advk_writel(advk, reg, PCIE_CORE_CTRL2_REG);
+ advk_writel(advk, PCIE_CORE_CTRL2_REG, reg);
/* Clear all interrupts */
- advk_writel(advk, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG);
- advk_writel(advk, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG);
- advk_writel(advk, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
+ advk_writel(advk, PCIE_ISR0_REG, PCIE_ISR0_ALL_MASK);
+ advk_writel(advk, PCIE_ISR1_REG, PCIE_ISR1_ALL_MASK);
+ advk_writel(advk, HOST_CTRL_INT_STATUS_REG, PCIE_IRQ_ALL_MASK);
/* Disable All ISR0/1 Sources */
reg = PCIE_ISR0_ALL_MASK;
reg &= ~PCIE_ISR0_MSI_INT_PENDING;
- advk_writel(advk, reg, PCIE_ISR0_MASK_REG);
+ advk_writel(advk, PCIE_ISR0_MASK_REG, reg);
- advk_writel(advk, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG);
+ advk_writel(advk, PCIE_ISR1_MASK_REG, PCIE_ISR1_ALL_MASK);
/* Unmask all MSI's */
- advk_writel(advk, 0, PCIE_MSI_MASK_REG);
+ advk_writel(advk, PCIE_MSI_MASK_REG, 0);
/* Enable summary interrupt for GIC SPI source */
reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK);
- advk_writel(advk, reg, HOST_CTRL_INT_MASK_REG);
+ advk_writel(advk, HOST_CTRL_INT_MASK_REG, reg);
reg = advk_readl(advk, PCIE_CORE_CTRL2_REG);
reg |= PCIE_CORE_CTRL2_OB_WIN_ENABLE;
- advk_writel(advk, reg, PCIE_CORE_CTRL2_REG);
+ advk_writel(advk, PCIE_CORE_CTRL2_REG, reg);
/* Bypass the address window mapping for PIO */
reg = advk_readl(advk, PIO_CTRL);
reg |= PIO_CTRL_ADDR_WIN_DISABLE;
- advk_writel(advk, reg, PIO_CTRL);
+ advk_writel(advk, PIO_CTRL, reg);
/* Start link training */
reg = advk_readl(advk, PCIE_CORE_LINK_CTRL_STAT_REG);
reg |= PCIE_CORE_LINK_TRAINING;
- advk_writel(advk, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
+ advk_writel(advk, PCIE_CORE_LINK_CTRL_STAT_REG, reg);
advk_pcie_wait_for_link(advk);
reg = PCIE_CORE_LINK_L0S_ENTRY |
(1 << PCIE_CORE_LINK_WIDTH_SHIFT);
- advk_writel(advk, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
+ advk_writel(advk, PCIE_CORE_LINK_CTRL_STAT_REG, reg);
reg = advk_readl(advk, PCIE_CORE_CMD_STATUS_REG);
reg |= PCIE_CORE_CMD_MEM_ACCESS_EN |
PCIE_CORE_CMD_IO_ACCESS_EN |
PCIE_CORE_CMD_MEM_IO_REQ_EN;
- advk_writel(advk, reg, PCIE_CORE_CMD_STATUS_REG);
+ advk_writel(advk, PCIE_CORE_CMD_STATUS_REG, reg);
}
static void advk_pcie_check_pio_status(struct advk_pcie *advk)
@@ -443,8 +443,8 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
}
/* Start PIO */
- advk_writel(advk, 0, PIO_START);
- advk_writel(advk, 1, PIO_ISR);
+ advk_writel(advk, PIO_START, 0);
+ advk_writel(advk, PIO_ISR, 1);
/* Program the control register */
reg = advk_readl(advk, PIO_CTRL);
@@ -453,18 +453,18 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
reg |= PCIE_CONFIG_RD_TYPE0;
else
reg |= PCIE_CONFIG_RD_TYPE1;
- advk_writel(advk, reg, PIO_CTRL);
+ advk_writel(advk, PIO_CTRL, reg);
/* Program the address registers */
reg = PCIE_BDF(devfn) | PCIE_CONF_REG(where);
- advk_writel(advk, reg, PIO_ADDR_LS);
- advk_writel(advk, 0, PIO_ADDR_MS);
+ advk_writel(advk, PIO_ADDR_LS, reg);
+ advk_writel(advk, PIO_ADDR_MS, 0);
/* Program the data strobe */
- advk_writel(advk, 0xf, PIO_WR_DATA_STRB);
+ advk_writel(advk, PIO_WR_DATA_STRB, 0xf);
/* Start the transfer */
- advk_writel(advk, 1, PIO_START);
+ advk_writel(advk, PIO_START, 1);
ret = advk_pcie_wait_pio(advk);
if (ret < 0)
@@ -498,8 +498,8 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
return PCIBIOS_SET_FAILED;
/* Start PIO */
- advk_writel(advk, 0, PIO_START);
- advk_writel(advk, 1, PIO_ISR);
+ advk_writel(advk, PIO_START, 0);
+ advk_writel(advk, PIO_ISR, 1);
/* Program the control register */
reg = advk_readl(advk, PIO_CTRL);
@@ -508,12 +508,12 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
reg |= PCIE_CONFIG_WR_TYPE0;
else
reg |= PCIE_CONFIG_WR_TYPE1;
- advk_writel(advk, reg, PIO_CTRL);
+ advk_writel(advk, PIO_CTRL, reg);
/* Program the address registers */
reg = PCIE_CONF_ADDR(bus->number, devfn, where);
- advk_writel(advk, reg, PIO_ADDR_LS);
- advk_writel(advk, 0, PIO_ADDR_MS);
+ advk_writel(advk, PIO_ADDR_LS, reg);
+ advk_writel(advk, PIO_ADDR_MS, 0);
/* Calculate the write strobe */
offset = where & 0x3;
@@ -521,13 +521,13 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
data_strobe = GENMASK(size - 1, 0) << offset;
/* Program the data register */
- advk_writel(advk, reg, PIO_WR_DATA);
+ advk_writel(advk, PIO_WR_DATA, reg);
/* Program the data strobe */
- advk_writel(advk, data_strobe, PIO_WR_DATA_STRB);
+ advk_writel(advk, PIO_WR_DATA_STRB, data_strobe);
/* Start the transfer */
- advk_writel(advk, 1, PIO_START);
+ advk_writel(advk, PIO_START, 1);
ret = advk_pcie_wait_pio(advk);
if (ret < 0)
@@ -640,7 +640,7 @@ static void advk_pcie_irq_mask(struct irq_data *d)
mask = advk_readl(advk, PCIE_ISR0_MASK_REG);
mask |= PCIE_ISR0_INTX_ASSERT(hwirq);
- advk_writel(advk, mask, PCIE_ISR0_MASK_REG);
+ advk_writel(advk, PCIE_ISR0_MASK_REG, mask);
}
static void advk_pcie_irq_unmask(struct irq_data *d)
@@ -651,7 +651,7 @@ static void advk_pcie_irq_unmask(struct irq_data *d)
mask = advk_readl(advk, PCIE_ISR0_MASK_REG);
mask &= ~PCIE_ISR0_INTX_ASSERT(hwirq);
- advk_writel(advk, mask, PCIE_ISR0_MASK_REG);
+ advk_writel(advk, PCIE_ISR0_MASK_REG, mask);
}
static int advk_pcie_irq_map(struct irq_domain *h,
@@ -703,8 +703,8 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *advk)
msi_msg_phys = virt_to_phys(&advk->msi_msg);
- advk_writel(advk, lower_32_bits(msi_msg_phys), PCIE_MSI_ADDR_LOW_REG);
- advk_writel(advk, upper_32_bits(msi_msg_phys), PCIE_MSI_ADDR_HIGH_REG);
+ advk_writel(advk, PCIE_MSI_ADDR_LOW_REG, lower_32_bits(msi_msg_phys));
+ advk_writel(advk, PCIE_MSI_ADDR_HIGH_REG, upper_32_bits(msi_msg_phys));
advk->msi_domain =
irq_domain_add_linear(NULL, MSI_IRQ_NUM,
@@ -783,12 +783,12 @@ static void advk_pcie_handle_msi(struct advk_pcie *advk)
if (!(BIT(msi_idx) & msi_status))
continue;
- advk_writel(advk, BIT(msi_idx), PCIE_MSI_STATUS_REG);
+ advk_writel(advk, PCIE_MSI_STATUS_REG, BIT(msi_idx));
msi_data = advk_readl(advk, PCIE_MSI_PAYLOAD_REG) & 0xFF;
generic_handle_irq(msi_data);
}
- advk_writel(advk, PCIE_ISR0_MSI_INT_PENDING, PCIE_ISR0_REG);
+ advk_writel(advk, PCIE_ISR0_REG, PCIE_ISR0_MSI_INT_PENDING);
}
static void advk_pcie_handle_int(struct advk_pcie *advk)
@@ -801,7 +801,7 @@ static void advk_pcie_handle_int(struct advk_pcie *advk)
status = val & ((~mask) & PCIE_ISR0_ALL_MASK);
if (!status) {
- advk_writel(advk, val, PCIE_ISR0_REG);
+ advk_writel(advk, PCIE_ISR0_REG, val);
return;
}
@@ -814,8 +814,7 @@ static void advk_pcie_handle_int(struct advk_pcie *advk)
if (!(status & PCIE_ISR0_INTX_ASSERT(i)))
continue;
- advk_writel(advk, PCIE_ISR0_INTX_ASSERT(i),
- PCIE_ISR0_REG);
+ advk_writel(advk, PCIE_ISR0_REG, PCIE_ISR0_INTX_ASSERT(i));
virq = irq_find_mapping(advk->irq_domain, i);
generic_handle_irq(virq);
@@ -834,7 +833,7 @@ static irqreturn_t advk_pcie_irq_handler(int irq, void *arg)
advk_pcie_handle_int(advk);
/* Clear interrupt */
- advk_writel(advk, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG);
+ advk_writel(advk, HOST_CTRL_INT_STATUS_REG, PCIE_IRQ_CORE_INT);
return IRQ_HANDLED;
}
^ permalink raw reply related
* [PATCH 4/5] PCI: aardvark: Add local struct device pointers
From: Bjorn Helgaas @ 2016-10-07 16:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007162053.22668.91420.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Use a local "struct device *dev" for brevity and consistency with other
drivers. No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/host/pci-aardvark.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
index af6312a..b255a08 100644
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -230,19 +230,20 @@ static int advk_pcie_link_up(struct advk_pcie *advk)
static int advk_pcie_wait_for_link(struct advk_pcie *advk)
{
+ struct device *dev = &advk->pdev->dev;
int retries;
/* check if the link is up or not */
for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
if (advk_pcie_link_up(advk)) {
- dev_info(&advk->pdev->dev, "link up\n");
+ dev_info(dev, "link up\n");
return 0;
}
usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
}
- dev_err(&advk->pdev->dev, "link never came up\n");
+ dev_err(dev, "link never came up\n");
return -ETIMEDOUT;
}
@@ -376,6 +377,7 @@ static void advk_pcie_setup_hw(struct advk_pcie *advk)
static void advk_pcie_check_pio_status(struct advk_pcie *advk)
{
+ struct device *dev = &advk->pdev->dev;
u32 reg;
unsigned int status;
char *strcomp_status, *str_posted;
@@ -407,12 +409,13 @@ static void advk_pcie_check_pio_status(struct advk_pcie *advk)
else
str_posted = "Posted";
- dev_err(&advk->pdev->dev, "%s PIO Response Status: %s, %#x @ %#x\n",
+ dev_err(dev, "%s PIO Response Status: %s, %#x @ %#x\n",
str_posted, strcomp_status, reg, advk_readl(advk, PIO_ADDR_LS));
}
static int advk_pcie_wait_pio(struct advk_pcie *advk)
{
+ struct device *dev = &advk->pdev->dev;
unsigned long timeout;
timeout = jiffies + msecs_to_jiffies(PIO_TIMEOUT_MS);
@@ -426,7 +429,7 @@ static int advk_pcie_wait_pio(struct advk_pcie *advk)
return 0;
}
- dev_err(&advk->pdev->dev, "config read/write timed out\n");
+ dev_err(dev, "config read/write timed out\n");
return -ETIMEDOUT;
}
@@ -560,10 +563,11 @@ static int advk_pcie_alloc_msi(struct advk_pcie *advk)
static void advk_pcie_free_msi(struct advk_pcie *advk, int hwirq)
{
+ struct device *dev = &advk->pdev->dev;
+
mutex_lock(&advk->msi_used_lock);
if (!test_bit(hwirq, advk->msi_irq_in_use))
- dev_err(&advk->pdev->dev, "trying to free unused MSI#%d\n",
- hwirq);
+ dev_err(dev, "trying to free unused MSI#%d\n", hwirq);
else
clear_bit(hwirq, advk->msi_irq_in_use);
mutex_unlock(&advk->msi_used_lock);
@@ -905,6 +909,7 @@ out_release_res:
static int advk_pcie_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct advk_pcie *advk;
struct resource *res;
struct pci_bus *bus, *child;
@@ -912,8 +917,7 @@ static int advk_pcie_probe(struct platform_device *pdev)
struct device_node *msi_node;
int ret, irq;
- advk = devm_kzalloc(&pdev->dev, sizeof(struct advk_pcie),
- GFP_KERNEL);
+ advk = devm_kzalloc(dev, sizeof(struct advk_pcie), GFP_KERNEL);
if (!advk)
return -ENOMEM;
@@ -921,22 +925,22 @@ static int advk_pcie_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, advk);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- advk->base = devm_ioremap_resource(&pdev->dev, res);
+ advk->base = devm_ioremap_resource(dev, res);
if (IS_ERR(advk->base))
return PTR_ERR(advk->base);
irq = platform_get_irq(pdev, 0);
- ret = devm_request_irq(&pdev->dev, irq, advk_pcie_irq_handler,
+ ret = devm_request_irq(dev, irq, advk_pcie_irq_handler,
IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie",
advk);
if (ret) {
- dev_err(&pdev->dev, "Failed to register interrupt\n");
+ dev_err(dev, "Failed to register interrupt\n");
return ret;
}
ret = advk_pcie_parse_request_of_pci_ranges(advk);
if (ret) {
- dev_err(&pdev->dev, "Failed to parse resources\n");
+ dev_err(dev, "Failed to parse resources\n");
return ret;
}
@@ -944,24 +948,24 @@ static int advk_pcie_probe(struct platform_device *pdev)
ret = advk_pcie_init_irq_domain(advk);
if (ret) {
- dev_err(&pdev->dev, "Failed to initialize irq\n");
+ dev_err(dev, "Failed to initialize irq\n");
return ret;
}
ret = advk_pcie_init_msi_irq_domain(advk);
if (ret) {
- dev_err(&pdev->dev, "Failed to initialize irq\n");
+ dev_err(dev, "Failed to initialize irq\n");
advk_pcie_remove_irq_domain(advk);
return ret;
}
- msi_node = of_parse_phandle(pdev->dev.of_node, "msi-parent", 0);
+ msi_node = of_parse_phandle(dev->of_node, "msi-parent", 0);
if (msi_node)
msi = of_pci_find_msi_chip_by_node(msi_node);
else
msi = NULL;
- bus = pci_scan_root_bus_msi(&pdev->dev, 0, &advk_pcie_ops,
+ bus = pci_scan_root_bus_msi(dev, 0, &advk_pcie_ops,
advk, &advk->resources, &advk->msi);
if (!bus) {
advk_pcie_remove_msi_irq_domain(advk);
^ permalink raw reply related
* [PATCH 5/5] PCI: aardvark: Remove unused platform data
From: Bjorn Helgaas @ 2016-10-07 16:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007162053.22668.91420.stgit@bhelgaas-glaptop2.roam.corp.google.com>
The aardvark driver never uses the platform drvdata pointer, so don't
bother setting it. No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/host/pci-aardvark.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
index b255a08..5b12199 100644
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -922,7 +922,6 @@ static int advk_pcie_probe(struct platform_device *pdev)
return -ENOMEM;
advk->pdev = pdev;
- platform_set_drvdata(pdev, advk);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
advk->base = devm_ioremap_resource(dev, res);
^ permalink raw reply related
* [PATCH 3/3] mtd: s3c2410: parse the device configuration from OF node
From: Krzysztof Kozlowski @ 2016-10-07 16:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475711217-974-4-git-send-email-sergio.prado@e-labworks.com>
On Wed, Oct 05, 2016 at 08:46:57PM -0300, Sergio Prado wrote:
> Allows configuring Samsung's s3c2410 memory controller using a
> devicetree.
>
> Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
> ---
> drivers/mtd/nand/s3c2410.c | 171 ++++++++++++++++++++++---
> include/linux/platform_data/mtd-nand-s3c2410.h | 1 +
> 2 files changed, 156 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
> index 174ac9dc4265..352cf2656bc8 100644
> --- a/drivers/mtd/nand/s3c2410.c
> +++ b/drivers/mtd/nand/s3c2410.c
> @@ -39,6 +39,8 @@
> #include <linux/slab.h>
> #include <linux/clk.h>
> #include <linux/cpufreq.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
>
> #include <linux/mtd/mtd.h>
> #include <linux/mtd/nand.h>
> @@ -185,6 +187,26 @@ struct s3c2410_nand_info {
> #endif
> };
>
> +struct s3c24XX_nand_devtype_data {
> + enum s3c_cpu_type type;
> +};
> +
> +struct s3c24XX_nand_devtype_data s3c2410_nand_devtype_data = {
> + .type = TYPE_S3C2410,
> +};
> +
> +struct s3c24XX_nand_devtype_data s3c2412_nand_devtype_data = {
> + .type = TYPE_S3C2412,
> +};
> +
> +struct s3c24XX_nand_devtype_data s3c2440_nand_devtype_data = {
> + .type = TYPE_S3C2440,
> +};
> +
> +struct s3c24XX_nand_devtype_data s3c6400_nand_devtype_data = {
> + .type = TYPE_S3C2412,
All of these look like candidate for static const.
Additionally you are not actually differentiating between s3c2412 and
s3c64xx so I think there is not need of samsung,s3c6400-nand compatible.
Just use existing one.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH 0/2] ARM: at91: properly handle LPDDR poweroff
From: Alexandre Belloni @ 2016-10-07 16:34 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This patch set improves LPDDR support on SoCs using the Atmel MPDDR controller.
LPDDR memoris can only handle up to 400 uncontrolled power offs in their
life. The proper power off sequence has to be applied before shutting down the SoC.
I'm not too happy with the code duplication but this is a design choice
that has been made before because both shitdown controler are really
different appart from the shutdown itself.
I guess it is still better than slowly killing the LPDDR.
Alexandre Belloni (2):
ARM: at91: define LPDDR types
power/reset: at91-poweroff: timely shitdown LPDDR memories
drivers/power/reset/at91-poweroff.c | 52 +++++++++++++++++++++++++++++++-
drivers/power/reset/at91-sama5d2_shdwc.c | 48 ++++++++++++++++++++++++++++-
include/soc/at91/at91sam9_ddrsdr.h | 3 ++
3 files changed, 101 insertions(+), 2 deletions(-)
--
2.9.3
^ permalink raw reply
* [PATCH 1/2] ARM: at91: define LPDDR types
From: Alexandre Belloni @ 2016-10-07 16:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007163427.11454-1-alexandre.belloni@free-electrons.com>
The Atmel MPDDR controller support LPDDR2 and LPDDR3 memories, add their
types.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
include/soc/at91/at91sam9_ddrsdr.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/soc/at91/at91sam9_ddrsdr.h b/include/soc/at91/at91sam9_ddrsdr.h
index dc10c52e0e91..393362bdb860 100644
--- a/include/soc/at91/at91sam9_ddrsdr.h
+++ b/include/soc/at91/at91sam9_ddrsdr.h
@@ -81,6 +81,7 @@
#define AT91_DDRSDRC_LPCB_POWER_DOWN 2
#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3
#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */
+#define AT91_DDRSDRC_LPDDR2_PWOFF (1 << 3) /* LPDDR Power Off */
#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */
#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */
#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */
@@ -96,7 +97,9 @@
#define AT91_DDRSDRC_MD_SDR 0
#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
+#define AT91_DDRSDRC_MD_LPDDR3 5
#define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */
+#define AT91_DDRSDRC_MD_LPDDR2 7
#define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */
#define AT91_DDRSDRC_DBW_32BITS (0 << 4)
#define AT91_DDRSDRC_DBW_16BITS (1 << 4)
--
2.9.3
^ permalink raw reply related
* [PATCH 2/2] power/reset: at91-poweroff: timely shitdown LPDDR memories
From: Alexandre Belloni @ 2016-10-07 16:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007163427.11454-1-alexandre.belloni@free-electrons.com>
LPDDR memories can only handle up to 400 uncontrolled power off. Ensure the
proper power off sequence is used before shutting down the platform.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
drivers/power/reset/at91-poweroff.c | 52 +++++++++++++++++++++++++++++++-
drivers/power/reset/at91-sama5d2_shdwc.c | 48 ++++++++++++++++++++++++++++-
2 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c
index e9e24df35f26..bf97390e6cd7 100644
--- a/drivers/power/reset/at91-poweroff.c
+++ b/drivers/power/reset/at91-poweroff.c
@@ -14,9 +14,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
+#include <soc/at91/at91sam9_ddrsdr.h>
+
#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
#define AT91_SHDW_SHDW BIT(0) /* Shut Down command */
#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
@@ -50,6 +53,7 @@ static const char *shdwc_wakeup_modes[] = {
static void __iomem *at91_shdwc_base;
static struct clk *sclk;
+static void __iomem *mpddrc_base;
static void __init at91_wakeup_status(void)
{
@@ -73,6 +77,28 @@ static void at91_poweroff(void)
writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR);
}
+static void at91_lpddr_poweroff(void)
+{
+ asm volatile(
+ /* Align to cache lines */
+ ".balign 32\n\t"
+
+ " ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
+
+ /* Power down SDRAM0 */
+ " str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
+ /* Shutdown CPU */
+ " str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
+
+ " b .\n\t"
+ :
+ : "r" (mpddrc_base),
+ "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
+ "r" (at91_shdwc_base),
+ "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
+ : "r0");
+}
+
static int at91_poweroff_get_wakeup_mode(struct device_node *np)
{
const char *pm;
@@ -124,6 +150,8 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
static int __init at91_poweroff_probe(struct platform_device *pdev)
{
struct resource *res;
+ struct device_node *np;
+ u32 ddr_type;
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -150,12 +178,29 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
pm_power_off = at91_poweroff;
+ np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
+ if (!np)
+ return 0;
+
+ mpddrc_base = of_iomap(np, 0);
+ of_node_put(np);
+
+ if (!mpddrc_base)
+ return 0;
+
+ ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD;
+ if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) ||
+ (ddr_type == AT91_DDRSDRC_MD_LPDDR3))
+ else
+ iounmap(mpddrc_base);
+
return 0;
}
static int __exit at91_poweroff_remove(struct platform_device *pdev)
{
- if (pm_power_off == at91_poweroff)
+ if (pm_power_off == at91_poweroff ||
+ pm_power_off == at91_lpddr_poweroff)
pm_power_off = NULL;
clk_disable_unprepare(sclk);
@@ -163,6 +208,11 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id at91_ramc_of_match[] = {
+ { .compatible = "atmel,sama5d3-ddramc", },
+ { /* sentinel */ }
+};
+
static const struct of_device_id at91_poweroff_of_match[] = {
{ .compatible = "atmel,at91sam9260-shdwc", },
{ .compatible = "atmel,at91sam9rl-shdwc", },
diff --git a/drivers/power/reset/at91-sama5d2_shdwc.c b/drivers/power/reset/at91-sama5d2_shdwc.c
index 8a5ac9706c9c..5736f360b374 100644
--- a/drivers/power/reset/at91-sama5d2_shdwc.c
+++ b/drivers/power/reset/at91-sama5d2_shdwc.c
@@ -22,9 +22,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
+#include <soc/at91/at91sam9_ddrsdr.h>
+
#define SLOW_CLOCK_FREQ 32768
#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
@@ -75,6 +78,7 @@ struct shdwc {
*/
static struct shdwc *at91_shdwc;
static struct clk *sclk;
+static void __iomem *mpddrc_base;
static const unsigned long long sdwc_dbc_period[] = {
0, 3, 32, 512, 4096, 32768,
@@ -108,6 +112,28 @@ static void at91_poweroff(void)
at91_shdwc->at91_shdwc_base + AT91_SHDW_CR);
}
+static void at91_lpddr_poweroff(void)
+{
+ asm volatile(
+ /* Align to cache lines */
+ ".balign 32\n\t"
+
+ " ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
+
+ /* Power down SDRAM0 */
+ " str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
+ /* Shutdown CPU */
+ " str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
+
+ " b .\n\t"
+ :
+ : "r" (mpddrc_base),
+ "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
+ "r" (at91_shdwc->at91_shdwc_base),
+ "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
+ : "r0");
+}
+
static u32 at91_shdwc_debouncer_value(struct platform_device *pdev,
u32 in_period_us)
{
@@ -212,6 +238,8 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
{
struct resource *res;
const struct of_device_id *match;
+ struct device_node *np;
+ u32 ddr_type;
int ret;
if (!pdev->dev.of_node)
@@ -249,6 +277,23 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
pm_power_off = at91_poweroff;
+ np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
+ if (!np)
+ return 0;
+
+ mpddrc_base = of_iomap(np, 0);
+ of_node_put(np);
+
+ if (!mpddrc_base)
+ return 0;
+
+ ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD;
+ if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) ||
+ (ddr_type == AT91_DDRSDRC_MD_LPDDR3))
+ pm_power_off = at91_lpddr_poweroff;
+ else
+ iounmap(mpddrc_base);
+
return 0;
}
@@ -256,7 +301,8 @@ static int __exit at91_shdwc_remove(struct platform_device *pdev)
{
struct shdwc *shdw = platform_get_drvdata(pdev);
- if (pm_power_off == at91_poweroff)
+ if (pm_power_off == at91_poweroff ||
+ pm_power_off == at91_lpddr_poweroff)
pm_power_off = NULL;
/* Reset values to disable wake-up features */
--
2.9.3
^ permalink raw reply related
* [PATCH 2/3] arm64: hw_breakpoint: Handle inexact watchpoint addresses
From: Pratyush Anand @ 2016-10-07 16:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474643941-109020-2-git-send-email-labath@google.com>
On Fri, Sep 23, 2016 at 8:49 PM, Pavel Labath
<test.tberghammer@gmail.com> wrote:
> Arm64 hardware does not always report a watchpoint hit address that
> matches one of the watchpoints set. It can also report an address
> "near" the watchpoint if a single instruction access both watched and
> unwatched addresses. There is no straight-forward way, short of
> disassembling the offending instruction, to map that address back to
> the watchpoint.
>
> Previously, when the hardware reported a watchpoint hit on an address
> that did not match our watchpoint (this happens in case of instructions
> which access large chunks of memory such as "stp") the process would
> enter a loop where we would be continually resuming it (because we did
> not recognise that watchpoint hit) and it would keep hitting the
> watchpoint again and again. The tracing process would never get
> notified of the watchpoint hit.
>
> This commit fixes the problem by looking at the watchpoints near the
> address reported by the hardware. If the address does not exactly match
> one of the watchpoints we have set, it attributes the hit to the
> nearest watchpoint we have. This heuristic is a bit dodgy, but I don't
> think we can do much more, given the hardware limitations.
IIUC, then you see an issue when an address watched is not the base
address accessed by the instruction. For example, if an address 'a+8'
is watched and an instruction accesses instruction from a to a +16. I
tried to reproduce the issue with mustang using your test-case in
patch3 (after couple of syntax modifcations for resolving compilation
issue with gcc). All the test case did pass with existing code in
v4.8. I noticed that, watchpoint exception is generated if any of the
sub-location accessed from a single instruction is watched, provided
watchdpoint watches either a byte, half word, word or double word
from the base.
So, either I must be missing something or the problem is not related
to all arm64 platform.
However, I did notice that it does not work if we watch an address
which is at some offset from address programmed. For example, it works
when byte_mask is 0x3, but it does not work if byte_mask if 0x2 (which
is supported by hardware).
I do have some patches to resolve that.
https://github.com/pratyushanand/linux/commits/perf/upstream_arm64_devel
I will send them for review comment after some testing.
~Pratyush
>
> Signed-off-by: Pavel Labath <labath@google.com>
> ---
> arch/arm64/kernel/hw_breakpoint.c | 98 +++++++++++++++++++++++++--------------
> 1 file changed, 64 insertions(+), 34 deletions(-)
>
> diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
> index 14562ae..3ce27ea 100644
> --- a/arch/arm64/kernel/hw_breakpoint.c
> +++ b/arch/arm64/kernel/hw_breakpoint.c
> @@ -664,49 +664,63 @@ unlock:
> }
> NOKPROBE_SYMBOL(breakpoint_handler);
>
> +/*
> + * Arm64 hardware does not always report a watchpoint hit address that matches
> + * one of the watchpoints set. It can also report an address "near" the
> + * watchpoint if a single instruction access both watched and unwatched
> + * addresses. There is no straight-forward way, short of disassembling the
> + * offending instruction, to map that address back to the watchpoint. This
> + * function computes the distance of the memory access from the watchpoint as a
> + * heuristic for the likelyhood that a given access triggered the watchpoint.
> + *
> + * See Section D2.10.5 "Determining the memory location that caused a Watchpoint
> + * exception" of ARMv8 Architecture Reference Manual for details.
> + *
> + * The function returns the distance of the address from the bytes watched by
> + * the watchpoint. In case of an exact match, it returns 0.
> + */
> +static u64 get_distance_from_watchpoint(unsigned long addr, int i,
> + struct arch_hw_breakpoint *info)
> +{
> + u64 wp_low, wp_high;
> + int first_bit;
> +
> + first_bit = ffs(info->ctrl.len);
> + if (first_bit == 0)
> + return -1;
> +
> + wp_low = info->address + first_bit - 1;
> + wp_high = info->address + fls(info->ctrl.len) - 1;
> + if (addr < wp_low)
> + return wp_low - addr;
> + else if (addr > wp_high)
> + return addr - wp_high;
> + else
> + return 0;
> +
> +}
> +
> static int watchpoint_handler(unsigned long addr, unsigned int esr,
> struct pt_regs *regs)
> {
> - int i, step = 0, *kernel_step, access;
> - u32 ctrl_reg;
> - u64 val, alignment_mask;
> + int i, step = 0, *kernel_step, access, closest_match = 0;
> + u64 min_dist = -1, dist;
> struct perf_event *wp, **slots;
> struct debug_info *debug_info;
> struct arch_hw_breakpoint *info;
> - struct arch_hw_breakpoint_ctrl ctrl;
>
> slots = this_cpu_ptr(wp_on_reg);
> debug_info = ¤t->thread.debug;
>
> + /*
> + * Find all watchpoints that match the reported address. If no exact
> + * match is found. Attribute the hit to the closest watchpoint.
> + */
> + rcu_read_lock();
> for (i = 0; i < core_num_wrps; ++i) {
> - rcu_read_lock();
> -
> wp = slots[i];
> -
> if (wp == NULL)
> - goto unlock;
> -
> - info = counter_arch_bp(wp);
> - /* AArch32 watchpoints are either 4 or 8 bytes aligned. */
> - if (is_compat_task()) {
> - if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
> - alignment_mask = 0x7;
> - else
> - alignment_mask = 0x3;
> - } else {
> - alignment_mask = 0x7;
> - }
> -
> - /* Check if the watchpoint value matches. */
> - val = read_wb_reg(AARCH64_DBG_REG_WVR, i);
> - if (val != (addr & ~alignment_mask))
> - goto unlock;
> -
> - /* Possible match, check the byte address select to confirm. */
> - ctrl_reg = read_wb_reg(AARCH64_DBG_REG_WCR, i);
> - decode_ctrl_reg(ctrl_reg, &ctrl);
> - if (!((1 << (addr & alignment_mask)) & ctrl.len))
> - goto unlock;
> + continue;
>
> /*
> * Check that the access type matches.
> @@ -715,7 +729,18 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
> access = (esr & AARCH64_ESR_ACCESS_MASK) ? HW_BREAKPOINT_W :
> HW_BREAKPOINT_R;
> if (!(access & hw_breakpoint_type(wp)))
> - goto unlock;
> + continue;
> +
> + info = counter_arch_bp(wp);
> +
> + dist = get_distance_from_watchpoint(addr, i, info);
> + if (dist < min_dist) {
> + min_dist = dist;
> + closest_match = i;
> + }
> + /* Is this an exact match? */
> + if (dist != 0)
> + continue;
>
> info->trigger = addr;
> perf_bp_event(wp, regs);
> @@ -723,10 +748,15 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
> /* Do we need to handle the stepping? */
> if (is_default_overflow_handler(wp))
> step = 1;
> -
> -unlock:
> - rcu_read_unlock();
> }
> + if (min_dist > 0 && min_dist != -1) {
> + /* No exact match found. */
> + wp = slots[closest_match];
> + info = counter_arch_bp(wp);
> + info->trigger = addr;
> + perf_bp_event(wp, regs);
> + }
> + rcu_read_unlock();
>
> if (!step)
> return 0;
> --
> 2.8.0.rc3.226.g39d4020
>
^ permalink raw reply
* [PATCH v3 0/11] Add R8A7743/SK-RZG1M board support
From: Sergei Shtylyov @ 2016-10-07 16:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2056698.ncAHq8vRQ3@wasted.cogentembedded.com>
On 10/06/2016 12:23 AM, Sergei Shtylyov wrote:
> Here's the set of 11 patches against Simon Horman's 'renesas.git' repo's
> 'renesas-devel-20161003-v4.8' tag. I'm adding the device tree support for
> the R8A7743-based SK-RZG1M board. The SoC is close to R8A7791 and the board
> seems identical to the R8A7791/Porter board. The device tree patches depend on
> the R8A7743 CPG/MSSR driver series just posted in order to compile and work.
Forgot to mention that this version causes a regression with the sh_eth
driver (well, actually with phylib): since IRQC now gets a deferred probing,
PHY IRQ doesn't work anymore -- phylib falls back to polling.
MBR, Sergei
^ permalink raw reply
* [PATCH/RFT 00/12] Add DT support for ohci-da8xx
From: ahaslam at baylibre.com @ 2016-10-07 16:42 UTC (permalink / raw)
To: linux-arm-kernel
From: Axel Haslam <ahaslam@baylibre.com>
The purpose of this patch series is to add DT support to the ohci-da8xx
glue driver without breaking the non-DT boot, which is still used in
unconverted davinci devices.
To Achieve this, the first 8 patches make sure that the non-DT based
enumeration works, and prepares the stage for a DT migration by removing
dependencies on the board files (moving VBUS, and over current
handling to the driver). The last 4 patches actually add the DT
documentation and bindings for the ohci-da8xx driver.
Testing was done on a omap138-lcdk board, using DT, and non-DT boot,
and checking that in both cases the hub, usb mass storage and an input
device are correctly enumerated and working.
Since there have been some recent and ongoing efforts from David Lechner
to clean up davinci-mach code and the ochi-da8xx driver, this series
builds upon that work. Specifically:
* the accepted but soon to be reposted patch to remove mach code form
the ohci driver[1].
* The patch series to add phy nodes, and move usb clocks to a common
file [2].
A git branch based on tag: next-20161004 with the dependencies patches is
available in my github here [3].
The omap138-lcdk does not have gpios to control vbus and get over current
interrupt notifications, hence i was not able to test these and added
the RFT tag. If anyone has a da830-evm based board and could
confirm that ohci is correctly working, i would appreciate it.
(the OHCI option needs to be enabled in menuconfig)
P.D: It seems that the davinci-gpio driver is broken for DT based boot
and any gpio > 32. (luckly none of the DT based boards use gpios yet)
The probelm is that we have 144 gpios in the gpio controller as correctly
declared on the DT (they are not separate gpio controllers as in am3xx),
but the driver creates several gpio chips of 32 pins each, confusing the
"gpio chip to pin" matching logic of gpiolib-of. I think we might need to
fix this by creating a single gpio chip in gpio-davinci.c
[1] [PATCH v6 1/3] usb: ohci-da8xx: Remove code that references mach
http://www.gossamer-threads.com/lists/linux/kernel/2518807
[2] [PATCH v5 0/5] da8xx USB PHY platform devices and clocks (was "da8xx UBS clocks")
http://www.spinics.net/lists/linux-usb/msg140568.html
[3] github branch with all dependante patches
https://github.com/axelhaslamx/linux-axel/commits/ohci-da8xx-dt
Axel Haslam (12):
ARM: davinci: da8xx: Enable the usb20 "per" clk on phy_clk_enable
ARM: davinci: hawk: add full constraints for ohci plat boot
ARM: davinci: rename root_hub to platform_data
USB: ohci-da8xx: Divide power up time in the ohci driver
USB: ohci-da8xx: Fix probe for devices with no vbus/oci gpio
ARM: davinci: hawk: Remove oci and vbus gpios
USB: ohci-da8xx: Request gpios and handle interrupt in the driver
ARM: davinci: register the usb20_phy clock on the SoC file
usb: host: ohci-da8xx: Add devicetree bindings documentation
USB: ohci-da8xx: Add device tree support
ARM: dts: da850: Add the usb ohci device node
ARM: dts: da850-lcdk: enable ohci usb
.../devicetree/bindings/usb/ohci-da8xx.txt | 32 +++++
arch/arm/boot/dts/da850-lcdk.dts | 9 ++
arch/arm/boot/dts/da850.dtsi | 8 ++
arch/arm/mach-davinci/board-da830-evm.c | 75 +---------
arch/arm/mach-davinci/board-omapl138-hawk.c | 105 +-------------
arch/arm/mach-davinci/da850.c | 2 +
arch/arm/mach-davinci/include/mach/da8xx.h | 2 +-
arch/arm/mach-davinci/usb-da8xx.c | 15 +-
drivers/usb/host/ohci-da8xx.c | 158 +++++++++++++++++----
include/linux/platform_data/usb-davinci.h | 22 ++-
10 files changed, 218 insertions(+), 210 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/ohci-da8xx.txt
--
2.7.1
^ permalink raw reply
* [PATCH/RFT 01/12] ARM: davinci: da8xx: Enable the usb20 "per" clk on phy_clk_enable
From: ahaslam at baylibre.com @ 2016-10-07 16:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475858577-10366-1-git-send-email-ahaslam@baylibre.com>
From: Axel Haslam <ahaslam@baylibre.com>
While probing ochi phy with usb20 phy as a parent clock for usb11_phy,
the usb20_phy clock enable would time out. This is because the usb20
module clock needs to enabled while trying to lock the usb20_phy PLL.
Call clk enable and get for the usb20 peripheral before trying to
enable the phy PLL.
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
arch/arm/mach-davinci/usb-da8xx.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index 9e41a7f..982e105 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -53,11 +53,19 @@ int __init da8xx_register_usb_refclkin(int rate)
static void usb20_phy_clk_enable(struct clk *clk)
{
+ struct clk *usb20_clk;
u32 val;
u32 timeout = 500000; /* 500 msec */
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+ usb20_clk = clk_get(NULL, "usb20");
+ if (IS_ERR(usb20_clk)) {
+ pr_err("could not get usb20 clk\n");
+ return;
+ }
+
+ clk_prepare_enable(usb20_clk);
/*
* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
* host may use the PLL clock without USB 2.0 OTG being used.
@@ -70,11 +78,14 @@ static void usb20_phy_clk_enable(struct clk *clk)
while (--timeout) {
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
if (val & CFGCHIP2_PHYCLKGD)
- return;
+ goto done;
udelay(1);
}
pr_err("Timeout waiting for USB 2.0 PHY clock good.\n");
+done:
+ clk_disable_unprepare(usb20_clk);
+ clk_put(usb20_clk);
}
static void usb20_phy_clk_disable(struct clk *clk)
--
2.7.1
^ permalink raw reply related
* [PATCH/RFT 02/12] ARM: davinci: hawk: add full constraints for ohci plat boot
From: ahaslam at baylibre.com @ 2016-10-07 16:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475858577-10366-1-git-send-email-ahaslam@baylibre.com>
From: Axel Haslam <ahaslam@baylibre.com>
The phy framework requests an optional "phy" regulator. If it does
not find one, it returns -EPROBE_DEFER. In the case of non-DT based boot
for the omap138-lcdk board, this would prevent the usb11 phy to probe
correctly and ohci would not enumerate.
By calling "regulator_has_full_constraints", An error would be returned
instead of DEFER for the "optional" regulator, and the probe of
the phy driver can continue normally without a regulator.
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
arch/arm/mach-davinci/board-omapl138-hawk.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index c5cb8d9..1dc6112 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -14,6 +14,7 @@
#include <linux/console.h>
#include <linux/gpio.h>
#include <linux/platform_data/gpio-davinci.h>
+#include <linux/regulator/machine.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -328,6 +329,7 @@ static __init void omapl138_hawk_init(void)
if (ret)
pr_warn("%s: dsp/rproc registration failed: %d\n",
__func__, ret);
+ regulator_has_full_constraints();
}
#ifdef CONFIG_SERIAL_8250_CONSOLE
--
2.7.1
^ permalink raw reply related
* [PATCH/RFT 03/12] ARM: davinci: rename root_hub to platform_data
From: ahaslam at baylibre.com @ 2016-10-07 16:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475858577-10366-1-git-send-email-ahaslam@baylibre.com>
From: Axel Haslam <ahaslam@baylibre.com>
To prepare for DT support we will remove the usb callback function
pointers. Since this structure will only pass data to the driver, It
seems better to rename the structure root_hub structure to platform_data
There is no functional change.
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
arch/arm/mach-davinci/board-da830-evm.c | 2 +-
arch/arm/mach-davinci/board-omapl138-hawk.c | 2 +-
arch/arm/mach-davinci/include/mach/da8xx.h | 2 +-
arch/arm/mach-davinci/usb-da8xx.c | 2 +-
drivers/usb/host/ohci-da8xx.c | 36 ++++++++++++++---------------
include/linux/platform_data/usb-davinci.h | 6 ++---
6 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index c62766e..18d2b10 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -87,7 +87,7 @@ static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler)
return error;
}
-static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = {
+static struct da8xx_ohci_platform_data da830_evm_usb11_pdata = {
.set_power = da830_evm_usb_set_power,
.get_power = da830_evm_usb_get_power,
.get_oci = da830_evm_usb_get_oci,
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 1dc6112..a2bf3eb 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -226,7 +226,7 @@ static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler)
return error;
}
-static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = {
+static struct da8xx_ohci_platform_data omapl138_hawk_usb11_pdata = {
.set_power = hawk_usb_set_power,
.get_power = hawk_usb_get_power,
.get_oci = hawk_usb_get_oci,
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 38d932e..f7d6fd9 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -94,7 +94,7 @@ int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
int da8xx_register_usb_phy(void);
int da8xx_register_usb20(unsigned mA, unsigned potpgt);
-int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
+int da8xx_register_usb11(struct da8xx_ohci_platform_data *pdata);
int da8xx_register_emac(void);
int da8xx_register_uio_pruss(void);
int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index 982e105..36e3460 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -337,7 +337,7 @@ static struct platform_device da8xx_usb11_device = {
.resource = da8xx_usb11_resources,
};
-int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
+int __init da8xx_register_usb11(struct da8xx_ohci_platform_data *pdata)
{
da8xx_usb11_device.dev.platform_data = pdata;
return platform_device_register(&da8xx_usb11_device);
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 3656d7c..8ed9a52 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -64,20 +64,20 @@ static void ohci_da8xx_disable(void)
/*
* Handle the port over-current indicator change.
*/
-static void ohci_da8xx_ocic_handler(struct da8xx_ohci_root_hub *hub,
+static void ohci_da8xx_ocic_handler(struct da8xx_ohci_platform_data *pdata,
unsigned port)
{
ocic_mask |= 1 << port;
/* Once over-current is detected, the port needs to be powered down */
- if (hub->get_oci(port) > 0)
- hub->set_power(port, 0);
+ if (pdata->get_oci(port) > 0)
+ pdata->set_power(port, 0);
}
static int ohci_da8xx_init(struct usb_hcd *hcd)
{
struct device *dev = hcd->self.controller;
- struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+ struct da8xx_ohci_platform_data *pdata = dev_get_platdata(dev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int result;
u32 rh_a;
@@ -107,16 +107,16 @@ static int ohci_da8xx_init(struct usb_hcd *hcd)
* the correct hub descriptor...
*/
rh_a = ohci_readl(ohci, &ohci->regs->roothub.a);
- if (hub->set_power) {
+ if (pdata->set_power) {
rh_a &= ~RH_A_NPS;
rh_a |= RH_A_PSM;
}
- if (hub->get_oci) {
+ if (pdata->get_oci) {
rh_a &= ~RH_A_NOCP;
rh_a |= RH_A_OCPM;
}
rh_a &= ~RH_A_POTPGT;
- rh_a |= hub->potpgt << 24;
+ rh_a |= pdata->potpgt << 24;
ohci_writel(ohci, rh_a, &ohci->regs->roothub.a);
return result;
@@ -167,7 +167,7 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
u16 wIndex, char *buf, u16 wLength)
{
struct device *dev = hcd->self.controller;
- struct da8xx_ohci_root_hub *hub = dev_get_platdata(dev);
+ struct da8xx_ohci_platform_data *pdata = dev_get_platdata(dev);
int temp;
switch (typeReq) {
@@ -181,11 +181,11 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = roothub_portstatus(hcd_to_ohci(hcd), wIndex - 1);
/* The port power status (PPS) bit defaults to 1 */
- if (hub->get_power && hub->get_power(wIndex) == 0)
+ if (pdata->get_power && pdata->get_power(wIndex) == 0)
temp &= ~RH_PS_PPS;
/* The port over-current indicator (POCI) bit is always 0 */
- if (hub->get_oci && hub->get_oci(wIndex) > 0)
+ if (pdata->get_oci && pdata->get_oci(wIndex) > 0)
temp |= RH_PS_POCI;
/* The over-current indicator change (OCIC) bit is 0 too */
@@ -210,10 +210,10 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
dev_dbg(dev, "%sPortFeature(%u): %s\n",
temp ? "Set" : "Clear", wIndex, "POWER");
- if (!hub->set_power)
+ if (!pdata->set_power)
return -EPIPE;
- return hub->set_power(wIndex, temp) ? -EPIPE : 0;
+ return pdata->set_power(wIndex, temp) ? -EPIPE : 0;
case USB_PORT_FEAT_C_OVER_CURRENT:
dev_dbg(dev, "%sPortFeature(%u): %s\n",
temp ? "Set" : "Clear", wIndex,
@@ -288,12 +288,12 @@ static const struct hc_driver ohci_da8xx_hc_driver = {
static int usb_hcd_da8xx_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
- struct da8xx_ohci_root_hub *hub = dev_get_platdata(&pdev->dev);
+ struct da8xx_ohci_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct usb_hcd *hcd;
struct resource *mem;
int error, irq;
- if (hub == NULL)
+ if (pdata == NULL)
return -ENODEV;
usb11_clk = devm_clk_get(&pdev->dev, "usb11");
@@ -337,8 +337,8 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver,
device_wakeup_enable(hcd->self.controller);
- if (hub->ocic_notify) {
- error = hub->ocic_notify(ohci_da8xx_ocic_handler);
+ if (pdata->ocic_notify) {
+ error = pdata->ocic_notify(ohci_da8xx_ocic_handler);
if (!error)
return 0;
}
@@ -361,9 +361,9 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver,
static inline void
usb_hcd_da8xx_remove(struct usb_hcd *hcd, struct platform_device *pdev)
{
- struct da8xx_ohci_root_hub *hub = dev_get_platdata(&pdev->dev);
+ struct da8xx_ohci_platform_data *pdata = dev_get_platdata(&pdev->dev);
- hub->ocic_notify(NULL);
+ pdata->ocic_notify(NULL);
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
}
diff --git a/include/linux/platform_data/usb-davinci.h b/include/linux/platform_data/usb-davinci.h
index e0bc4ab..dffe3bf 100644
--- a/include/linux/platform_data/usb-davinci.h
+++ b/include/linux/platform_data/usb-davinci.h
@@ -34,13 +34,13 @@
#define CFGCHIP2_REFFREQ_24MHZ (2 << 0)
#define CFGCHIP2_REFFREQ_48MHZ (3 << 0)
-struct da8xx_ohci_root_hub;
+struct da8xx_ohci_platform_data;
-typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_root_hub *hub,
+typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_platform_data *pdata,
unsigned port);
/* Passed as the platform data to the OHCI driver */
-struct da8xx_ohci_root_hub {
+struct da8xx_ohci_platform_data {
/* Switch the port power on/off */
int (*set_power)(unsigned port, int on);
/* Read the port power status */
--
2.7.1
^ permalink raw reply related
* [PATCH/RFT 04/12] USB: ohci-da8xx: Divide power up time in the ohci driver
From: ahaslam at baylibre.com @ 2016-10-07 16:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475858577-10366-1-git-send-email-ahaslam@baylibre.com>
From: Axel Haslam <ahaslam@baylibre.com>
Instead of requiring platform data to know that the effective time
should be diveded by two, Make that operation in the driver so that
users (platform board files/Device tree) dont have to worry about it.
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
arch/arm/mach-davinci/board-da830-evm.c | 2 +-
arch/arm/mach-davinci/board-omapl138-hawk.c | 2 +-
drivers/usb/host/ohci-da8xx.c | 8 ++++++--
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index 18d2b10..8d126e4 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -94,7 +94,7 @@ static struct da8xx_ohci_platform_data da830_evm_usb11_pdata = {
.ocic_notify = da830_evm_usb_ocic_notify,
/* TPS2065 switch @ 5V */
- .potpgt = (3 + 1) / 2, /* 3 ms max */
+ .potpgt = 3, /* 3 ms max */
};
static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id)
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index a2bf3eb..f9cd388 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -232,7 +232,7 @@ static struct da8xx_ohci_platform_data omapl138_hawk_usb11_pdata = {
.get_oci = hawk_usb_get_oci,
.ocic_notify = hawk_usb_ocic_notify,
/* TPS2087 switch @ 5V */
- .potpgt = (3 + 1) / 2, /* 3 ms max */
+ .potpgt = 3 /* 3 ms max */
};
static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id)
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 8ed9a52..3c85d6c 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -115,8 +115,12 @@ static int ohci_da8xx_init(struct usb_hcd *hcd)
rh_a &= ~RH_A_NOCP;
rh_a |= RH_A_OCPM;
}
- rh_a &= ~RH_A_POTPGT;
- rh_a |= pdata->potpgt << 24;
+
+ if (pdata->potpgt) {
+ rh_a &= ~RH_A_POTPGT;
+ rh_a |= (DIV_ROUND_UP(pdata->potpgt, 2) << 24);
+ }
+
ohci_writel(ohci, rh_a, &ohci->regs->roothub.a);
return result;
--
2.7.1
^ permalink raw reply related
* [PATCH/RFT 05/12] USB: ohci-da8xx: Fix probe for devices with no vbus/oci gpio
From: ahaslam at baylibre.com @ 2016-10-07 16:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475858577-10366-1-git-send-email-ahaslam@baylibre.com>
From: Axel Haslam <ahaslam@baylibre.com>
Some boards dont have gpios assigened for vbus or oci.
Allow these boards to enumerate usb without declaring the set_power
and/or the ocic_notify callbacks in platform data.
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
---
drivers/usb/host/ohci-da8xx.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 3c85d6c..9d9f8e3 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -215,7 +215,7 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp ? "Set" : "Clear", wIndex, "POWER");
if (!pdata->set_power)
- return -EPIPE;
+ return 0;
return pdata->set_power(wIndex, temp) ? -EPIPE : 0;
case USB_PORT_FEAT_C_OVER_CURRENT:
@@ -343,10 +343,12 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver,
if (pdata->ocic_notify) {
error = pdata->ocic_notify(ohci_da8xx_ocic_handler);
- if (!error)
- return 0;
+ if (error)
+ goto err_notify;
}
+ return 0;
+err_notify:
usb_remove_hcd(hcd);
err:
usb_put_hcd(hcd);
--
2.7.1
^ permalink raw reply related
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