* [PATCH 3/5] dt-bindings: spi: Add documentation for the Armada 3700 SPI Controller
From: Romain Perier @ 2016-11-29 14:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129143939.3191-1-romain.perier@free-electrons.com>
This adds the devicetree bindings documentation for the SPI controller
present in the Marvell Armada 3700 SoCs.
Signed-off-by: Romain Perier <romain.perier@free-electrons.com>
---
.../devicetree/bindings/spi/spi-armada-3700.txt | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/spi-armada-3700.txt
diff --git a/Documentation/devicetree/bindings/spi/spi-armada-3700.txt b/Documentation/devicetree/bindings/spi/spi-armada-3700.txt
new file mode 100644
index 0000000..1564aa8
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-armada-3700.txt
@@ -0,0 +1,25 @@
+* Marvell Armada 3700 SPI Controller
+
+Required Properties:
+
+- compatible: should be "marvell,armada-3700-spi"
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- interrupts: The interrupt number. The interrupt specifier format depends on
+ the interrupt controller and of its driver.
+- clocks: Must contain the clock source, usually from the North Bridge clocks.
+- num-cs: The number of chip selects that is supported by this SPI Controller
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+
+Example:
+
+ spi0: spi at 10600 {
+ compatible = "marvell,armada-3700-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10600 0x5d>;
+ clocks = <&nb_perih_clk 7>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ num-cs = <4>;
+ };
--
2.9.3
^ permalink raw reply related
* [PATCH 4/5] arm64: dts: marvell: Add definition of SPI controller for Armada 3700
From: Romain Perier @ 2016-11-29 14:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129143939.3191-1-romain.perier@free-electrons.com>
Armada 3700 SoC has an SPI Controller, this commit adds the definition
of the SPI device node at the SoC level.
Signed-off-by: Romain Perier <romain.perier@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index e9bd587..84e4f57 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -98,6 +98,19 @@
/* 32M internal register @ 0xd000_0000 */
ranges = <0x0 0x0 0xd0000000 0x2000000>;
+ spi0: spi at 10600 {
+ compatible = "marvell,armada-3700-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10600 0x5d>;
+ clocks = <&nb_periph_clk 7>;
+ clock-frequency = <200000000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ max-frequency = <66000000>;
+ num-cs = <4>;
+ status = "disabled";
+ };
+
uart0: serial at 12000 {
compatible = "marvell,armada-3700-uart";
reg = <0x12000 0x400>;
--
2.9.3
^ permalink raw reply related
* [PATCH 5/5] arm64: dts: marvell: Enable spi0 on the board Armada-3720-db
From: Romain Perier @ 2016-11-29 14:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129143939.3191-1-romain.perier@free-electrons.com>
This commit enables the device node spi0 on the official development
board for the Marvell Armada 3700. It also adds sub-node for the 128Mb
SPI-NOR present on the board.
Signed-off-by: Romain Perier <romain.perier@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-3720-db.dts | 30 ++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
index 1372e9a6..0c4eb98 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -67,6 +67,36 @@
status = "okay";
};
+&spi0 {
+ status = "okay";
+
+ m25p80 at 0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <108000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition at 0 {
+ label = "bootloader";
+ reg = <0x0 0x200000>;
+ };
+ partition at 200000 {
+ label = "U-boot Env";
+ reg = <0x200000 0x10000>;
+ };
+ partition at 210000 {
+ label = "Linux";
+ reg = <0x210000 0xDF0000>;
+ };
+ };
+ };
+};
+
/* Exported on the micro USB connector CON32 through an FTDI */
&uart0 {
status = "okay";
--
2.9.3
^ permalink raw reply related
* [RESEND PATCH] drm/exynos: Use VIDEO_SAMSUNG_EXYNOS_GSC=n as GSC Kconfig dependency
From: Javier Martinez Canillas @ 2016-11-29 14:40 UTC (permalink / raw)
To: linux-arm-kernel
Commit aeefb36832e5 ("drm/exynos: gsc: add device tree support and remove
usage of static mappings") made the DRM_EXYNOS_GSC Kconfig symbol to only
be selectable if the exynos-gsc V4L2 driver isn't enabled, since both use
the same HW IP block.
But added the dependency as depends on !VIDEO_SAMSUNG_EXYNOS_GSC which is
not correct since Kconfig expressions are not boolean but tristate. So it
will only evaluate to 'n' if VIDEO_SAMSUNG_EXYNOS_GSC=y but will evaluate
to 'm' if VIDEO_SAMSUNG_EXYNOS_GSC=m.
This means that both the V4L2 and DRM drivers can be enabled if the former
is enabled as a module, which isn't what we want since otherwise 2 drivers
could attempt to use the hardware at the same time.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
drivers/gpu/drm/exynos/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 465d344f3391..d706ca4e2f02 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -114,7 +114,7 @@ config DRM_EXYNOS_ROTATOR
config DRM_EXYNOS_GSC
bool "GScaler"
- depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !VIDEO_SAMSUNG_EXYNOS_GSC
+ depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && VIDEO_SAMSUNG_EXYNOS_GSC=n
help
Choose this option if you want to use Exynos GSC for DRM.
--
2.7.4
^ permalink raw reply related
* [PATCH 4/5] arm64: dts: marvell: Add definition of SPI controller for Armada 3700
From: Thomas Petazzoni @ 2016-11-29 14:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129143939.3191-5-romain.perier@free-electrons.com>
Hello,
On Tue, 29 Nov 2016 15:39:38 +0100, Romain Perier wrote:
> diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> index e9bd587..84e4f57 100644
> --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> @@ -98,6 +98,19 @@
> /* 32M internal register @ 0xd000_0000 */
> ranges = <0x0 0x0 0xd0000000 0x2000000>;
>
> + spi0: spi at 10600 {
> + compatible = "marvell,armada-3700-spi";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x10600 0x5d>;
> + clocks = <&nb_periph_clk 7>;
> + clock-frequency = <200000000>;
This property.
> + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
> + max-frequency = <66000000>;
And this one no longer exist in your DT binding, so I guess they should
be removed from here as well.
(Please wait for other reviews, don't respin just for that issue.)
Thanks!
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH] clocksource/arm_global_timer: reconfigure clockevents after cpufreq change
From: Marc Zyngier @ 2016-11-29 14:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.20.1611291529520.4358@nanos>
On 29/11/16 14:32, Thomas Gleixner wrote:
> On Tue, 29 Nov 2016, Marc Zyngier wrote:
>> On 29/11/16 13:42, Thomas Gleixner wrote:
>>> Assumptions w/o real impact are a perfect reason not to apply that
>>> patch. This want's a proper proof that the global timer really changes and
>>> this hackery is required, which I seriously doubt.
>>
>> Well, let's not underestimate the "creativity" [1] of A5/A9 when it
>> comes to the timer clocks, and it is a very sad fact that both the
>> global timer and the local timers are clocked by PERIPHCLK, which is
>> ticking at a fixed ratio N (N >= 2) of the main CPU clock (CLK):
>>
>> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0407f/CIHGECHJ.html
>>
>> I'm not sure how feasible it is to change this ratio (the TRM seems to
>> be very silent on the subject).
>
> The CRU documentation of the RK3188 suggests that you can adjust it as it
> has a seperate divider, but who knows.
>
>> So short of being able to reconfigure it on the fly, this will probably
>> need some surgery similar to what we already do for the TWD (which this
>> patch mimics).
>>
>> Thankfully, we don't see that anymore on moderately recent HW (anything
>> since A15) and the advent of the arch timer, which is guaranteed to have
>> a fixed frequency.
>
> Can we just disable that global timer on affected SoCs and use something
> else instead?
That'd be my preferred course of action. I've located some documentation
over there [1], and page 1126 seems to indicate a profusion of
additional timers, some of which are in an always-on domain. Seems like
a much better use of someone's time...
Thanks,
M.
[1] http://rockchip.fr/Rockchip%20RK3188%20TRM%20V1.3.pdf
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH] clocksource/arm_global_timer: reconfigure clockevents after cpufreq change
From: Alexander Kochetkov @ 2016-11-29 14:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.20.1611291529520.4358@nanos>
> 29 ????. 2016 ?., ? 17:32, Thomas Gleixner <tglx@linutronix.de> ???????(?):
>
> Can we just disable that global timer on affected SoCs and use something
> else instead?
I?ve sent patch series for fixing that on rockchip SoC.
http://lists.infradead.org/pipermail/linux-rockchip/2016-November/013217.html
But the series contain fix only for rk3188, because I don?t have another rockchip
SoC. rk3288 and other could be easy fixed with dts files.
There are a lot of other platforms what probably use shed_clock and
clocksource form global-timer.
alexander at ubuntu:dts$ grep arm,cortex-a9-global-timer *
am4372.dtsi: compatible = "arm,cortex-a9-global-timer";
artpec6.dtsi: compatible = "arm,cortex-a9-global-timer";
bcm5301x.dtsi: compatible = "arm,cortex-a9-global-timer";
bcm63138.dtsi: compatible = "arm,cortex-a9-global-timer";
bcm-cygnus.dtsi: compatible = "arm,cortex-a9-global-timer";
bcm-nsp.dtsi: compatible = "arm,cortex-a9-global-timer";
hip01.dtsi: compatible = "arm,cortex-a9-global-timer";
rk3xxx.dtsi: compatible = "arm,cortex-a9-global-timer";
stih407-family.dtsi: compatible = "arm,cortex-a9-global-timer";
stih41x.dtsi: compatible = "arm,cortex-a9-global-timer";
uniphier-common32.dtsi: compatible = "arm,cortex-a9-global-timer";
uniphier-ph1-sld3.dtsi: compatible = "arm,cortex-a9-global-timer";
vexpress-v2p-ca5s.dts: "arm,cortex-a9-global-timer";
vf500.dtsi: compatible = "arm,cortex-a9-global-timer";
zx296702.dtsi: compatible = "arm,cortex-a9-global-timer";
zynq-7000.dtsi: compatible = "arm,cortex-a9-global-timer?;
Regards,
Alexander.
^ permalink raw reply
* [PATCH v4 net-next 0/7] Support Armada 37xx SoC (ARMv8 64-bits) in mvneta driver
From: Gregory CLEMENT @ 2016-11-29 14:55 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
The Armada 37xx is a new ARMv8 SoC from Marvell using same network
controller as the older Armada 370/38x/XP SoCs. This series adapts the
driver in order to be able to use it on this new SoC. The main changes
are:
- 64-bits support: the first patches allow using the driver on a 64-bit
architecture.
- MBUS support: the mbus configuration is different on Armada 37xx
from the older SoCs.
- per cpu interrupt: Armada 37xx do not support per cpu interrupt for
the NETA IP, the non-per-CPU behavior was added back.
The first patch is an optimization in the rx path in swbm mode.
The second patch remove unnecessary allocation for HWBM.
The first item is solved by patches 4 and 5.
The 2 last items are solved by patch 6.
In patch 7 the dt support is added.
Beside Armada 37xx, this series have been again tested on Armada XP
and Armada 38x (with Hardware Buffer Management and with Software
Buffer Management).
This is the 4th version of the series:
- 1st version:
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-November/469588.html
- 2nd version:
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-November/470476.html
-3rd version:
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-November/470901.html
Changelog:
v3 -> v4:
- Adding new patch: "net: mvneta: do not allocate buffer in rxq init
with HWBM"
- Simplify the HWBM case in patch 3 as suggested by Marcin
v2 -> v3:
- Adding patch 1 "Optimize rx path for small frame"
- Fix the kbuild error by moving the "phys_addr += pp->rx_offset_correction;"
line from patch 2 to patch 3 where rx_offset_correction is introduced.
- Move the memory allocation of the buf_virt_addr of the rxq to be
called by the probe function in order to avoid a memory leak.
Thanks,
Gregory
Gregory CLEMENT (5):
net: mvneta: Optimize rx path for small frame
net: mvneta: Do not allocate buffer in rxq init with HWBM
net: mvneta: Use cacheable memory to store the rx buffer virtual address
net: mvneta: Only disable mvneta_bm for 64-bits
ARM64: dts: marvell: Add network support for Armada 3700
Marcin Wojtas (2):
net: mvneta: Convert to be 64 bits compatible
net: mvneta: Add network support for Armada 3700 SoC
Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt | 7 +-
arch/arm64/boot/dts/marvell/armada-3720-db.dts | 23 +++++-
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 23 +++++-
drivers/net/ethernet/marvell/Kconfig | 10 +-
drivers/net/ethernet/marvell/mvneta.c | 344 +++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
5 files changed, 305 insertions(+), 102 deletions(-)
base-commit: 436accebb53021ef7c63535f60bda410aa87c136
--
git-series 0.8.10
^ permalink raw reply
* [PATCH v4 net-next 1/7] net: mvneta: Optimize rx path for small frame
From: Gregory CLEMENT @ 2016-11-29 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.654978388d6811b943dd58ecb9a9d9b6cceeaee3.1480431285.git-series.gregory.clement@free-electrons.com>
For small frame reuse the phys_addr variable instead of accessing the
uncacheable value in the rx descriptor.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/net/ethernet/marvell/mvneta.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 87274d4ab102..1b84f746d748 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -1918,7 +1918,7 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo,
goto err_drop_frame;
dma_sync_single_range_for_cpu(dev->dev.parent,
- rx_desc->buf_phys_addr,
+ phys_addr,
MVNETA_MH_SIZE + NET_SKB_PAD,
rx_bytes,
DMA_FROM_DEVICE);
--
git-series 0.8.10
^ permalink raw reply related
* [PATCH v4 net-next 2/7] net: mvneta: Do not allocate buffer in rxq init with HWBM
From: Gregory CLEMENT @ 2016-11-29 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.654978388d6811b943dd58ecb9a9d9b6cceeaee3.1480431285.git-series.gregory.clement@free-electrons.com>
For HWBM all buffers are allocated in mvneta_bm_construct() and in runtime
they are put into descriptors by hardware. There is no need to fill them
at this point.
Suggested-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/net/ethernet/marvell/mvneta.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 1b84f746d748..f5319c50f8d9 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2784,14 +2784,14 @@ static int mvneta_rxq_init(struct mvneta_port *pp,
mvneta_rxq_buf_size_set(pp, rxq,
MVNETA_RX_BUF_SIZE(pp->pkt_size));
mvneta_rxq_bm_disable(pp, rxq);
+ mvneta_rxq_fill(pp, rxq, rxq->size);
} else {
mvneta_rxq_bm_enable(pp, rxq);
mvneta_rxq_long_pool_set(pp, rxq);
mvneta_rxq_short_pool_set(pp, rxq);
+ mvneta_rxq_non_occup_desc_add(pp, rxq, rxq->size);
}
- mvneta_rxq_fill(pp, rxq, rxq->size);
-
return 0;
}
--
git-series 0.8.10
^ permalink raw reply related
* [PATCH v4 net-next 3/7] net: mvneta: Use cacheable memory to store the rx buffer virtual address
From: Gregory CLEMENT @ 2016-11-29 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.654978388d6811b943dd58ecb9a9d9b6cceeaee3.1480431285.git-series.gregory.clement@free-electrons.com>
Until now the virtual address of the received buffer were stored in the
cookie field of the rx descriptor. However, this field is 32-bits only
which prevents to use the driver on a 64-bits architecture.
With this patch the virtual address is stored in an array not shared with
the hardware (no more need to use the DMA API). Thanks to this, it is
possible to use cache contrary to the access of the rx descriptor member.
The change is done in the swbm path only because the hwbm uses the cookie
field, this also means that currently the hwbm is not usable in 64-bits.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/net/ethernet/marvell/mvneta.c | 34 +++++++++++++++++++---------
1 file changed, 24 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index f5319c50f8d9..b4810b0c0ffc 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -561,6 +561,9 @@ struct mvneta_rx_queue {
u32 pkts_coal;
u32 time_coal;
+ /* Virtual address of the RX buffer */
+ void **buf_virt_addr;
+
/* Virtual address of the RX DMA descriptors array */
struct mvneta_rx_desc *descs;
@@ -1573,10 +1576,14 @@ static void mvneta_tx_done_pkts_coal_set(struct mvneta_port *pp,
/* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
static void mvneta_rx_desc_fill(struct mvneta_rx_desc *rx_desc,
- u32 phys_addr, u32 cookie)
+ u32 phys_addr, void *virt_addr,
+ struct mvneta_rx_queue *rxq)
{
- rx_desc->buf_cookie = cookie;
+ int i;
+
rx_desc->buf_phys_addr = phys_addr;
+ i = rx_desc - rxq->descs;
+ rxq->buf_virt_addr[i] = virt_addr;
}
/* Decrement sent descriptors counter */
@@ -1781,7 +1788,8 @@ EXPORT_SYMBOL_GPL(mvneta_frag_free);
/* Refill processing for SW buffer management */
static int mvneta_rx_refill(struct mvneta_port *pp,
- struct mvneta_rx_desc *rx_desc)
+ struct mvneta_rx_desc *rx_desc,
+ struct mvneta_rx_queue *rxq)
{
dma_addr_t phys_addr;
@@ -1799,7 +1807,7 @@ static int mvneta_rx_refill(struct mvneta_port *pp,
return -ENOMEM;
}
- mvneta_rx_desc_fill(rx_desc, phys_addr, (u32)data);
+ mvneta_rx_desc_fill(rx_desc, phys_addr, data, rxq);
return 0;
}
@@ -1861,7 +1869,7 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
for (i = 0; i < rxq->size; i++) {
struct mvneta_rx_desc *rx_desc = rxq->descs + i;
- void *data = (void *)rx_desc->buf_cookie;
+ void *data = rxq->buf_virt_addr[i];
dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
@@ -1894,12 +1902,13 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo,
unsigned char *data;
dma_addr_t phys_addr;
u32 rx_status, frag_size;
- int rx_bytes, err;
+ int rx_bytes, err, index;
rx_done++;
rx_status = rx_desc->status;
rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE);
- data = (unsigned char *)rx_desc->buf_cookie;
+ index = rx_desc - rxq->descs;
+ data = (unsigned char *)rxq->buf_virt_addr[index];
phys_addr = rx_desc->buf_phys_addr;
if (!mvneta_rxq_desc_is_first_last(rx_status) ||
@@ -1938,7 +1947,7 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo,
}
/* Refill processing */
- err = mvneta_rx_refill(pp, rx_desc);
+ err = mvneta_rx_refill(pp, rx_desc, rxq);
if (err) {
netdev_err(dev, "Linux processing - Can't refill\n");
rxq->missed++;
@@ -2020,7 +2029,7 @@ static int mvneta_rx_hwbm(struct mvneta_port *pp, int rx_todo,
rx_done++;
rx_status = rx_desc->status;
rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE);
- data = (unsigned char *)rx_desc->buf_cookie;
+ data = (u8 *)(uintptr_t)rx_desc->buf_cookie;
phys_addr = rx_desc->buf_phys_addr;
pool_id = MVNETA_RX_GET_BM_POOL_ID(rx_desc);
bm_pool = &pp->bm_priv->bm_pools[pool_id];
@@ -2716,7 +2725,7 @@ static int mvneta_rxq_fill(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
for (i = 0; i < num; i++) {
memset(rxq->descs + i, 0, sizeof(struct mvneta_rx_desc));
- if (mvneta_rx_refill(pp, rxq->descs + i) != 0) {
+ if (mvneta_rx_refill(pp, rxq->descs + i, rxq) != 0) {
netdev_err(pp->dev, "%s:rxq %d, %d of %d buffs filled\n",
__func__, rxq->id, i, num);
break;
@@ -3865,6 +3874,11 @@ static int mvneta_init(struct device *dev, struct mvneta_port *pp)
rxq->size = pp->rx_ring_size;
rxq->pkts_coal = MVNETA_RX_COAL_PKTS;
rxq->time_coal = MVNETA_RX_COAL_USEC;
+ rxq->buf_virt_addr = devm_kmalloc(pp->dev->dev.parent,
+ rxq->size * sizeof(void *),
+ GFP_KERNEL);
+ if (!rxq->buf_virt_addr)
+ return -ENOMEM;
}
return 0;
--
git-series 0.8.10
^ permalink raw reply related
* [PATCH v4 net-next 4/7] net: mvneta: Convert to be 64 bits compatible
From: Gregory CLEMENT @ 2016-11-29 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.654978388d6811b943dd58ecb9a9d9b6cceeaee3.1480431285.git-series.gregory.clement@free-electrons.com>
From: Marcin Wojtas <mw@semihalf.com>
Prepare the mvneta driver in order to be usable on the 64 bits platform
such as the Armada 3700.
[gregory.clement at free-electrons.com]: this patch was extract from a larger
one to ease review and maintenance.
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/net/ethernet/marvell/mvneta.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index b4810b0c0ffc..6421402ef394 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -296,6 +296,12 @@
/* descriptor aligned size */
#define MVNETA_DESC_ALIGNED_SIZE 32
+/* Number of bytes to be taken into account by HW when putting incoming data
+ * to the buffers. It is needed in case NET_SKB_PAD exceeds maximum packet
+ * offset supported in MVNETA_RXQ_CONFIG_REG(q) registers.
+ */
+#define MVNETA_RX_PKT_OFFSET_CORRECTION 64
+
#define MVNETA_RX_PKT_SIZE(mtu) \
ALIGN((mtu) + MVNETA_MH_SIZE + MVNETA_VLAN_TAG_LEN + \
ETH_HLEN + ETH_FCS_LEN, \
@@ -416,6 +422,7 @@ struct mvneta_port {
u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)];
u32 indir[MVNETA_RSS_LU_TABLE_SIZE];
+ u16 rx_offset_correction;
};
/* The mvneta_tx_desc and mvneta_rx_desc structures describe the
@@ -1807,6 +1814,7 @@ static int mvneta_rx_refill(struct mvneta_port *pp,
return -ENOMEM;
}
+ phys_addr += pp->rx_offset_correction;
mvneta_rx_desc_fill(rx_desc, phys_addr, data, rxq);
return 0;
}
@@ -2782,7 +2790,7 @@ static int mvneta_rxq_init(struct mvneta_port *pp,
mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), rxq->size);
/* Set Offset */
- mvneta_rxq_offset_set(pp, rxq, NET_SKB_PAD);
+ mvneta_rxq_offset_set(pp, rxq, NET_SKB_PAD - pp->rx_offset_correction);
/* Set coalescing pkts and time */
mvneta_rx_pkts_coal_set(pp, rxq, rxq->pkts_coal);
@@ -4033,6 +4041,13 @@ static int mvneta_probe(struct platform_device *pdev)
pp->rxq_def = rxq_def;
+ /* Set RX packet offset correction for platforms, whose
+ * NET_SKB_PAD, exceeds 64B. It should be 64B for 64-bit
+ * platforms and 0B for 32-bit ones.
+ */
+ pp->rx_offset_correction =
+ max(0, NET_SKB_PAD - MVNETA_RX_PKT_OFFSET_CORRECTION);
+
pp->indir[0] = rxq_def;
pp->clk = devm_clk_get(&pdev->dev, "core");
--
git-series 0.8.10
^ permalink raw reply related
* [PATCH v4 net-next 5/7] net: mvneta: Only disable mvneta_bm for 64-bits
From: Gregory CLEMENT @ 2016-11-29 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.654978388d6811b943dd58ecb9a9d9b6cceeaee3.1480431285.git-series.gregory.clement@free-electrons.com>
Actually only the mvneta_bm support is not 64-bits compatible.
The mvneta code itself can run on 64-bits architecture.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/net/ethernet/marvell/Kconfig | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index 66fd9dbb2ca7..2ccea9dd9248 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -44,6 +44,7 @@ config MVMDIO
config MVNETA_BM_ENABLE
tristate "Marvell Armada 38x/XP network interface BM support"
depends on MVNETA
+ depends on !64BIT
---help---
This driver supports auxiliary block of the network
interface units in the Marvell ARMADA XP and ARMADA 38x SoC
@@ -58,7 +59,6 @@ config MVNETA
tristate "Marvell Armada 370/38x/XP network interface support"
depends on PLAT_ORION || COMPILE_TEST
depends on HAS_DMA
- depends on !64BIT
select MVMDIO
select FIXED_PHY
---help---
@@ -71,6 +71,7 @@ config MVNETA
config MVNETA_BM
tristate
+ depends on !64BIT
default y if MVNETA=y && MVNETA_BM_ENABLE!=n
default MVNETA_BM_ENABLE
select HWBM
--
git-series 0.8.10
^ permalink raw reply related
* [PATCH v4 net-next 6/7] net: mvneta: Add network support for Armada 3700 SoC
From: Gregory CLEMENT @ 2016-11-29 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.654978388d6811b943dd58ecb9a9d9b6cceeaee3.1480431285.git-series.gregory.clement@free-electrons.com>
From: Marcin Wojtas <mw@semihalf.com>
Armada 3700 is a new ARMv8 SoC from Marvell using same network controller
as older Armada 370/38x/XP. There are however some differences that
needed taking into account when adding support for it:
* open default MBUS window to 4GB of DRAM - Armada 3700 SoC's Mbus
configuration for network controller has to be done on two levels:
global and per-port. The first one is inherited from the
bootloader. The latter can be opened in a default way, leaving
arbitration to the bus controller. Hence filled mbus_dram_target_info
structure is not needed
* make per-CPU operation optional - Recent patches adding RSS and XPS
support for Armada 38x/XP enabled per-CPU operation of the controller
by default. Contrary to older SoC's Armada 3700 SoC's network
controller is not capable of per-CPU processing due to interrupt lines'
connectivity. This patch restores non-per-CPU operation, which is now
optional and depends on neta_armada3700 flag value in mvneta_port
structure. In order not to complicate the code, separate interrupt
subroutine is implemented.
For now, on the Armada 3700, RSS is disabled as the current
implementation depend on the per cpu interrupts.
[gregory.clement at free-electrons.com: extract from a larger patch, replace
some ifdef and port to net-next for v4.10]
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt | 7 +-
drivers/net/ethernet/marvell/Kconfig | 7 +-
drivers/net/ethernet/marvell/mvneta.c | 287 +++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
3 files changed, 214 insertions(+), 87 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
index 73be8970815e..7aa840c8768d 100644
--- a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
+++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
@@ -1,7 +1,10 @@
-* Marvell Armada 370 / Armada XP Ethernet Controller (NETA)
+* Marvell Armada 370 / Armada XP / Armada 3700 Ethernet Controller (NETA)
Required properties:
-- compatible: "marvell,armada-370-neta" or "marvell,armada-xp-neta".
+- compatible: could be one of the followings
+ "marvell,armada-370-neta"
+ "marvell,armada-xp-neta"
+ "marvell,armada-3700-neta"
- reg: address and length of the register set for the device.
- interrupts: interrupt for the device
- phy: See ethernet.txt file in the same directory.
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index 2ccea9dd9248..3b8f11fe5e13 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -56,14 +56,15 @@ config MVNETA_BM_ENABLE
buffer management.
config MVNETA
- tristate "Marvell Armada 370/38x/XP network interface support"
- depends on PLAT_ORION || COMPILE_TEST
+ tristate "Marvell Armada 370/38x/XP/37xx network interface support"
+ depends on ARCH_MVEBU || COMPILE_TEST
depends on HAS_DMA
select MVMDIO
select FIXED_PHY
---help---
This driver supports the network interface units in the
- Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family.
+ Marvell ARMADA XP, ARMADA 370, ARMADA 38x and
+ ARMADA 37xx SoC family.
Note that this driver is distinct from the mv643xx_eth
driver, which should be used for the older Marvell SoCs
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 6421402ef394..c12859201f5d 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -397,6 +397,9 @@ struct mvneta_port {
spinlock_t lock;
bool is_stopped;
+ u32 cause_rx_tx;
+ struct napi_struct napi;
+
/* Core clock */
struct clk *clk;
/* AXI clock */
@@ -422,6 +425,9 @@ struct mvneta_port {
u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)];
u32 indir[MVNETA_RSS_LU_TABLE_SIZE];
+
+ /* Flags for special SoC configurations */
+ bool neta_armada3700;
u16 rx_offset_correction;
};
@@ -965,14 +971,9 @@ static int mvneta_mbus_io_win_set(struct mvneta_port *pp, u32 base, u32 wsize,
return 0;
}
-/* Assign and initialize pools for port. In case of fail
- * buffer manager will remain disabled for current port.
- */
-static int mvneta_bm_port_init(struct platform_device *pdev,
- struct mvneta_port *pp)
+static int mvneta_bm_port_mbus_init(struct mvneta_port *pp)
{
- struct device_node *dn = pdev->dev.of_node;
- u32 long_pool_id, short_pool_id, wsize;
+ u32 wsize;
u8 target, attr;
int err;
@@ -991,6 +992,25 @@ static int mvneta_bm_port_init(struct platform_device *pdev,
netdev_info(pp->dev, "fail to configure mbus window to BM\n");
return err;
}
+ return 0;
+}
+
+/* Assign and initialize pools for port. In case of fail
+ * buffer manager will remain disabled for current port.
+ */
+static int mvneta_bm_port_init(struct platform_device *pdev,
+ struct mvneta_port *pp)
+{
+ struct device_node *dn = pdev->dev.of_node;
+ u32 long_pool_id, short_pool_id;
+
+ if (!pp->neta_armada3700) {
+ int ret;
+
+ ret = mvneta_bm_port_mbus_init(pp);
+ if (ret)
+ return ret;
+ }
if (of_property_read_u32(dn, "bm,pool-long", &long_pool_id)) {
netdev_info(pp->dev, "missing long pool id\n");
@@ -1359,22 +1379,27 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
for_each_present_cpu(cpu) {
int rxq_map = 0, txq_map = 0;
int rxq, txq;
+ if (!pp->neta_armada3700) {
+ for (rxq = 0; rxq < rxq_number; rxq++)
+ if ((rxq % max_cpu) == cpu)
+ rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq);
+
+ for (txq = 0; txq < txq_number; txq++)
+ if ((txq % max_cpu) == cpu)
+ txq_map |= MVNETA_CPU_TXQ_ACCESS(txq);
+
+ /* With only one TX queue we configure a special case
+ * which will allow to get all the irq on a single
+ * CPU
+ */
+ if (txq_number == 1)
+ txq_map = (cpu == pp->rxq_def) ?
+ MVNETA_CPU_TXQ_ACCESS(1) : 0;
- for (rxq = 0; rxq < rxq_number; rxq++)
- if ((rxq % max_cpu) == cpu)
- rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq);
-
- for (txq = 0; txq < txq_number; txq++)
- if ((txq % max_cpu) == cpu)
- txq_map |= MVNETA_CPU_TXQ_ACCESS(txq);
-
- /* With only one TX queue we configure a special case
- * which will allow to get all the irq on a single
- * CPU
- */
- if (txq_number == 1)
- txq_map = (cpu == pp->rxq_def) ?
- MVNETA_CPU_TXQ_ACCESS(1) : 0;
+ } else {
+ txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK;
+ rxq_map = MVNETA_CPU_RXQ_ACCESS_ALL_MASK;
+ }
mvreg_write(pp, MVNETA_CPU_MAP(cpu), rxq_map | txq_map);
}
@@ -2627,6 +2652,17 @@ static void mvneta_set_rx_mode(struct net_device *dev)
/* Interrupt handling - the callback for request_irq() */
static irqreturn_t mvneta_isr(int irq, void *dev_id)
{
+ struct mvneta_port *pp = (struct mvneta_port *)dev_id;
+
+ mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
+ napi_schedule(&pp->napi);
+
+ return IRQ_HANDLED;
+}
+
+/* Interrupt handling - the callback for request_percpu_irq() */
+static irqreturn_t mvneta_percpu_isr(int irq, void *dev_id)
+{
struct mvneta_pcpu_port *port = (struct mvneta_pcpu_port *)dev_id;
disable_percpu_irq(port->pp->dev->irq);
@@ -2674,7 +2710,7 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports);
if (!netif_running(pp->dev)) {
- napi_complete(&port->napi);
+ napi_complete(napi);
return rx_done;
}
@@ -2703,7 +2739,8 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
*/
rx_queue = fls(((cause_rx_tx >> 8) & 0xff));
- cause_rx_tx |= port->cause_rx_tx;
+ cause_rx_tx |= pp->neta_armada3700 ? pp->cause_rx_tx :
+ port->cause_rx_tx;
if (rx_queue) {
rx_queue = rx_queue - 1;
@@ -2717,11 +2754,27 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
if (budget > 0) {
cause_rx_tx = 0;
- napi_complete(&port->napi);
- enable_percpu_irq(pp->dev->irq, 0);
+ napi_complete(napi);
+
+ if (pp->neta_armada3700) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ mvreg_write(pp, MVNETA_INTR_NEW_MASK,
+ MVNETA_RX_INTR_MASK(rxq_number) |
+ MVNETA_TX_INTR_MASK(txq_number) |
+ MVNETA_MISCINTR_INTR_MASK);
+ local_irq_restore(flags);
+ } else {
+ enable_percpu_irq(pp->dev->irq, 0);
+ }
}
- port->cause_rx_tx = cause_rx_tx;
+ if (pp->neta_armada3700)
+ pp->cause_rx_tx = cause_rx_tx;
+ else
+ port->cause_rx_tx = cause_rx_tx;
+
return rx_done;
}
@@ -2991,11 +3044,16 @@ static void mvneta_start_dev(struct mvneta_port *pp)
/* start the Rx/Tx activity */
mvneta_port_enable(pp);
- /* Enable polling on the port */
- for_each_online_cpu(cpu) {
- struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
+ if (!pp->neta_armada3700) {
+ /* Enable polling on the port */
+ for_each_online_cpu(cpu) {
+ struct mvneta_pcpu_port *port =
+ per_cpu_ptr(pp->ports, cpu);
- napi_enable(&port->napi);
+ napi_enable(&port->napi);
+ }
+ } else {
+ napi_enable(&pp->napi);
}
/* Unmask interrupts. It has to be done from each CPU */
@@ -3017,10 +3075,15 @@ static void mvneta_stop_dev(struct mvneta_port *pp)
phy_stop(ndev->phydev);
- for_each_online_cpu(cpu) {
- struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
+ if (!pp->neta_armada3700) {
+ for_each_online_cpu(cpu) {
+ struct mvneta_pcpu_port *port =
+ per_cpu_ptr(pp->ports, cpu);
- napi_disable(&port->napi);
+ napi_disable(&port->napi);
+ }
+ } else {
+ napi_disable(&pp->napi);
}
netif_carrier_off(pp->dev);
@@ -3430,31 +3493,37 @@ static int mvneta_open(struct net_device *dev)
goto err_cleanup_rxqs;
/* Connect to port interrupt line */
- ret = request_percpu_irq(pp->dev->irq, mvneta_isr,
- MVNETA_DRIVER_NAME, pp->ports);
+ if (pp->neta_armada3700)
+ ret = request_irq(pp->dev->irq, mvneta_isr, 0,
+ dev->name, pp);
+ else
+ ret = request_percpu_irq(pp->dev->irq, mvneta_percpu_isr,
+ dev->name, pp->ports);
if (ret) {
netdev_err(pp->dev, "cannot request irq %d\n", pp->dev->irq);
goto err_cleanup_txqs;
}
- /* Enable per-CPU interrupt on all the CPU to handle our RX
- * queue interrupts
- */
- on_each_cpu(mvneta_percpu_enable, pp, true);
+ if (!pp->neta_armada3700) {
+ /* Enable per-CPU interrupt on all the CPU to handle our RX
+ * queue interrupts
+ */
+ on_each_cpu(mvneta_percpu_enable, pp, true);
- pp->is_stopped = false;
- /* Register a CPU notifier to handle the case where our CPU
- * might be taken offline.
- */
- ret = cpuhp_state_add_instance_nocalls(online_hpstate,
- &pp->node_online);
- if (ret)
- goto err_free_irq;
+ pp->is_stopped = false;
+ /* Register a CPU notifier to handle the case where our CPU
+ * might be taken offline.
+ */
+ ret = cpuhp_state_add_instance_nocalls(online_hpstate,
+ &pp->node_online);
+ if (ret)
+ goto err_free_irq;
- ret = cpuhp_state_add_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
- &pp->node_dead);
- if (ret)
- goto err_free_online_hp;
+ ret = cpuhp_state_add_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
+ &pp->node_dead);
+ if (ret)
+ goto err_free_online_hp;
+ }
/* In default link is down */
netif_carrier_off(pp->dev);
@@ -3470,13 +3539,20 @@ static int mvneta_open(struct net_device *dev)
return 0;
err_free_dead_hp:
- cpuhp_state_remove_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
- &pp->node_dead);
+ if (!pp->neta_armada3700)
+ cpuhp_state_remove_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
+ &pp->node_dead);
err_free_online_hp:
- cpuhp_state_remove_instance_nocalls(online_hpstate, &pp->node_online);
+ if (!pp->neta_armada3700)
+ cpuhp_state_remove_instance_nocalls(online_hpstate,
+ &pp->node_online);
err_free_irq:
- on_each_cpu(mvneta_percpu_disable, pp, true);
- free_percpu_irq(pp->dev->irq, pp->ports);
+ if (pp->neta_armada3700) {
+ free_irq(pp->dev->irq, pp);
+ } else {
+ on_each_cpu(mvneta_percpu_disable, pp, true);
+ free_percpu_irq(pp->dev->irq, pp->ports);
+ }
err_cleanup_txqs:
mvneta_cleanup_txqs(pp);
err_cleanup_rxqs:
@@ -3489,23 +3565,30 @@ static int mvneta_stop(struct net_device *dev)
{
struct mvneta_port *pp = netdev_priv(dev);
- /* Inform that we are stopping so we don't want to setup the
- * driver for new CPUs in the notifiers. The code of the
- * notifier for CPU online is protected by the same spinlock,
- * so when we get the lock, the notifer work is done.
- */
- spin_lock(&pp->lock);
- pp->is_stopped = true;
- spin_unlock(&pp->lock);
+ if (!pp->neta_armada3700) {
+ /* Inform that we are stopping so we don't want to setup the
+ * driver for new CPUs in the notifiers. The code of the
+ * notifier for CPU online is protected by the same spinlock,
+ * so when we get the lock, the notifer work is done.
+ */
+ spin_lock(&pp->lock);
+ pp->is_stopped = true;
+ spin_unlock(&pp->lock);
- mvneta_stop_dev(pp);
- mvneta_mdio_remove(pp);
+ mvneta_stop_dev(pp);
+ mvneta_mdio_remove(pp);
cpuhp_state_remove_instance_nocalls(online_hpstate, &pp->node_online);
cpuhp_state_remove_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
&pp->node_dead);
- on_each_cpu(mvneta_percpu_disable, pp, true);
- free_percpu_irq(dev->irq, pp->ports);
+ on_each_cpu(mvneta_percpu_disable, pp, true);
+ free_percpu_irq(dev->irq, pp->ports);
+ } else {
+ mvneta_stop_dev(pp);
+ mvneta_mdio_remove(pp);
+ free_irq(dev->irq, pp);
+ }
+
mvneta_cleanup_rxqs(pp);
mvneta_cleanup_txqs(pp);
@@ -3784,6 +3867,11 @@ static int mvneta_ethtool_set_rxfh(struct net_device *dev, const u32 *indir,
const u8 *key, const u8 hfunc)
{
struct mvneta_port *pp = netdev_priv(dev);
+
+ /* Current code for Armada 3700 doesn't support RSS features yet */
+ if (pp->neta_armada3700)
+ return -EOPNOTSUPP;
+
/* We require at least one supported parameter to be changed
* and no change in any of the unsupported parameters
*/
@@ -3804,6 +3892,10 @@ static int mvneta_ethtool_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
{
struct mvneta_port *pp = netdev_priv(dev);
+ /* Current code for Armada 3700 doesn't support RSS features yet */
+ if (pp->neta_armada3700)
+ return -EOPNOTSUPP;
+
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
@@ -3911,16 +4003,29 @@ static void mvneta_conf_mbus_windows(struct mvneta_port *pp,
win_enable = 0x3f;
win_protect = 0;
- for (i = 0; i < dram->num_cs; i++) {
- const struct mbus_dram_window *cs = dram->cs + i;
- mvreg_write(pp, MVNETA_WIN_BASE(i), (cs->base & 0xffff0000) |
- (cs->mbus_attr << 8) | dram->mbus_dram_target_id);
+ if (dram) {
+ for (i = 0; i < dram->num_cs; i++) {
+ const struct mbus_dram_window *cs = dram->cs + i;
+
+ mvreg_write(pp, MVNETA_WIN_BASE(i),
+ (cs->base & 0xffff0000) |
+ (cs->mbus_attr << 8) |
+ dram->mbus_dram_target_id);
- mvreg_write(pp, MVNETA_WIN_SIZE(i),
- (cs->size - 1) & 0xffff0000);
+ mvreg_write(pp, MVNETA_WIN_SIZE(i),
+ (cs->size - 1) & 0xffff0000);
- win_enable &= ~(1 << i);
- win_protect |= 3 << (2 * i);
+ win_enable &= ~(1 << i);
+ win_protect |= 3 << (2 * i);
+ }
+ } else {
+ /* For Armada3700 open default 4GB Mbus window, leaving
+ * arbitration of target/attribute to a different layer
+ * of configuration.
+ */
+ mvreg_write(pp, MVNETA_WIN_SIZE(0), 0xffff0000);
+ win_enable &= ~BIT(0);
+ win_protect = 3;
}
mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable);
@@ -4050,6 +4155,10 @@ static int mvneta_probe(struct platform_device *pdev)
pp->indir[0] = rxq_def;
+ /* Get special SoC configurations */
+ if (of_device_is_compatible(dn, "marvell,armada-3700-neta"))
+ pp->neta_armada3700 = true;
+
pp->clk = devm_clk_get(&pdev->dev, "core");
if (IS_ERR(pp->clk))
pp->clk = devm_clk_get(&pdev->dev, NULL);
@@ -4117,7 +4226,11 @@ static int mvneta_probe(struct platform_device *pdev)
pp->tx_csum_limit = tx_csum_limit;
dram_target_info = mv_mbus_dram_info();
- if (dram_target_info)
+ /* Armada3700 requires setting default configuration of Mbus
+ * windows, however without using filled mbus_dram_target_info
+ * structure.
+ */
+ if (dram_target_info || pp->neta_armada3700)
mvneta_conf_mbus_windows(pp, dram_target_info);
pp->tx_ring_size = MVNETA_MAX_TXD;
@@ -4150,11 +4263,20 @@ static int mvneta_probe(struct platform_device *pdev)
goto err_netdev;
}
- for_each_present_cpu(cpu) {
- struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
+ /* Armada3700 network controller does not support per-cpu
+ * operation, so only single NAPI should be initialized.
+ */
+ if (pp->neta_armada3700) {
+ netif_napi_add(dev, &pp->napi, mvneta_poll, NAPI_POLL_WEIGHT);
+ } else {
+ for_each_present_cpu(cpu) {
+ struct mvneta_pcpu_port *port =
+ per_cpu_ptr(pp->ports, cpu);
- netif_napi_add(dev, &port->napi, mvneta_poll, NAPI_POLL_WEIGHT);
- port->pp = pp;
+ netif_napi_add(dev, &port->napi, mvneta_poll,
+ NAPI_POLL_WEIGHT);
+ port->pp = pp;
+ }
}
dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
@@ -4239,6 +4361,7 @@ static int mvneta_remove(struct platform_device *pdev)
static const struct of_device_id mvneta_match[] = {
{ .compatible = "marvell,armada-370-neta" },
{ .compatible = "marvell,armada-xp-neta" },
+ { .compatible = "marvell,armada-3700-neta" },
{ }
};
MODULE_DEVICE_TABLE(of, mvneta_match);
--
git-series 0.8.10
^ permalink raw reply related
* [PATCH v4 net-next 7/7] ARM64: dts: marvell: Add network support for Armada 3700
From: Gregory CLEMENT @ 2016-11-29 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.654978388d6811b943dd58ecb9a9d9b6cceeaee3.1480431285.git-series.gregory.clement@free-electrons.com>
Add neta nodes for network support both in device tree for the SoC and
the board.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-3720-db.dts | 23 +++++++++++++++++++-
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 23 +++++++++++++++++++-
2 files changed, 46 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..c8b82e4145de 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -81,3 +81,26 @@
&pcie0 {
status = "okay";
};
+
+&mdio {
+ status = "okay";
+ phy0: ethernet-phy at 0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy at 1 {
+ reg = <1>;
+ };
+};
+
+ð0 {
+ phy-mode = "rgmii-id";
+ phy = <&phy0>;
+ status = "okay";
+};
+
+ð1 {
+ phy-mode = "rgmii-id";
+ phy = <&phy1>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index e9bd58793464..3b8eb45bdc76 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -140,6 +140,29 @@
};
};
+ eth0: ethernet at 30000 {
+ compatible = "marvell,armada-3700-neta";
+ reg = <0x30000 0x4000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sb_periph_clk 8>;
+ status = "disabled";
+ };
+
+ mdio: mdio at 32004 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "marvell,orion-mdio";
+ reg = <0x32004 0x4>;
+ };
+
+ eth1: ethernet at 40000 {
+ compatible = "marvell,armada-3700-neta";
+ reg = <0x40000 0x4000>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sb_periph_clk 7>;
+ status = "disabled";
+ };
+
usb3: usb at 58000 {
compatible = "marvell,armada3700-xhci",
"generic-xhci";
--
git-series 0.8.10
^ permalink raw reply related
* [PATCH] watchdog: meson: Remove unneeded platform MODULE_ALIAS
From: Javier Martinez Canillas @ 2016-11-29 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161020222833.GA27421@roeck-us.net>
Hello Wim,
On 10/20/2016 07:28 PM, Guenter Roeck wrote:
> On Wed, Oct 19, 2016 at 04:49:42PM -0300, Javier Martinez Canillas wrote:
>> The Amlogic Meson is a DT-only platform, which means the devices are
>> registered via OF and not using the legacy platform devices support.
>>
>> So there's no need to have a MODULE_ALIAS("platform:meson-gxbb-wdt")
>> since the reported uevent MODALIAS to user-space will be the OF one.
>>
>> Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
>
> Reviewed-by: Guenter Roeck <linux@roeck-us.net>
>
Any comments about this patch? There are other two similar fixes for
watchdog drivers that were also reviewed by Guenter but never picked:
https://lkml.org/lkml/2016/10/14/412
https://lkml.org/lkml/2016/10/14/413
Best regards,
--
Javier Martinez Canillas
Open Source Group
Samsung Research America
^ permalink raw reply
* [PATCH v3 13/13] clocksource/drivers/rockchip_timer: Prevent ftrace recursion
From: Heiko Stübner @ 2016-11-29 15:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480427118-5126-14-git-send-email-al.kochet@gmail.com>
Am Dienstag, 29. November 2016, 16:45:18 schrieb Alexander Kochetkov:
> Currently rockchip_timer can be used as a scheduler clock. We properly
> marked rk_timer_sched_clock_read() as notrace but we then call another
> function rk_timer_counter_read() that _wasn't_ notrace.
>
> Having a traceable function in the sched_clock() path leads to a recursion
> within ftrace and a kernel crash.
>
> Fix this by adding an extra notrace function to keep other users of
> rk_timer_counter_read() traceable.
>
> Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
you introduced the issue yourself in patch 11/13. In general any patch should
never leave the kernel in a worse state than it was before, so no patch should
ever introduce known issues itself.
In that line of thought, don't patches 10+11 introduce warnings about unused
functions as well when applied without patch 12?
Maybe merge them?
Heiko
> ---
> drivers/clocksource/rockchip_timer.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/clocksource/rockchip_timer.c
> b/drivers/clocksource/rockchip_timer.c index 1af80a0..a127822 100644
> --- a/drivers/clocksource/rockchip_timer.c
> +++ b/drivers/clocksource/rockchip_timer.c
> @@ -87,7 +87,7 @@ static void rk_timer_update_counter(u64 cycles, struct
> rk_timer *timer) writel_relaxed(upper, timer->base + TIMER_LOAD_COUNT1);
> }
>
> -static u64 rk_timer_counter_read(struct rk_timer *timer)
> +static u64 notrace _rk_timer_counter_read(struct rk_timer *timer)
> {
> u64 counter;
> u32 lower;
> @@ -106,6 +106,11 @@ static u64 rk_timer_counter_read(struct rk_timer
> *timer) return counter;
> }
>
> +static u64 rk_timer_counter_read(struct rk_timer *timer)
> +{
> + return _rk_timer_counter_read(timer);
> +}
> +
> static void rk_timer_interrupt_clear(struct rk_timer *timer)
> {
> writel_relaxed(1, timer->base + TIMER_INT_STATUS);
> @@ -168,7 +173,7 @@ static u64 notrace rk_timer_sched_clock_read(void)
> {
> struct rk_clocksource *_cs = &cs_timer;
>
> - return ~rk_timer_counter_read(&_cs->timer);
> + return ~_rk_timer_counter_read(&_cs->timer);
> }
>
> static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
^ permalink raw reply
* [PATCH v3 08/13] clocksource/drivers/rockchip_timer: drop unused rk_base() and rk_ctrl()
From: Heiko Stübner @ 2016-11-29 15:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480427118-5126-9-git-send-email-al.kochet@gmail.com>
Am Dienstag, 29. November 2016, 16:45:13 schrieb Alexander Kochetkov:
> Use of functions has been ceased by previous commit.
Then why do you need another patch to remove them and don't do that in the
patch removing their respective usage?
>
> Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
> ---
> drivers/clocksource/rockchip_timer.c | 10 ----------
> 1 file changed, 10 deletions(-)
>
> diff --git a/drivers/clocksource/rockchip_timer.c
> b/drivers/clocksource/rockchip_timer.c index aa9ccd1..a17dc61 100644
> --- a/drivers/clocksource/rockchip_timer.c
> +++ b/drivers/clocksource/rockchip_timer.c
> @@ -53,16 +53,6 @@ static inline struct rk_timer *rk_timer(struct
> clock_event_device *ce) return &rk_clock_event_device(ce)->timer;
> }
>
> -static inline void __iomem *rk_base(struct clock_event_device *ce)
> -{
> - return rk_timer(ce)->base;
> -}
> -
> -static inline void __iomem *rk_ctrl(struct clock_event_device *ce)
> -{
> - return rk_timer(ce)->ctrl;
> -}
> -
> static inline void rk_timer_disable(struct rk_timer *timer)
> {
> writel_relaxed(TIMER_DISABLE, timer->ctrl);
^ permalink raw reply
* [PATCH] clocksource/arm_global_timer: reconfigure clockevents after cpufreq change
From: Alexander Kochetkov @ 2016-11-29 15:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <54233c9e-d136-4b85-b2db-bf8658a164e7@arm.com>
> 29 ????. 2016 ?., ? 17:51, Marc Zyngier <marc.zyngier@arm.com> ???????(?):
>
> That'd be my preferred course of action. I've located some documentation
> over there [1], and page 1126 seems to indicate a profusion of
> additional timers, some of which are in an always-on domain. Seems like
> a much better use of someone's time...
Thank you very much :)
And thank you for great explanation of core problem.
In general, I no longer insist on the inclusion the patch in the kernel.
Thank you guys for the help.
Alexander.
^ permalink raw reply
* [PATCH] clocksource/arm_global_timer: reconfigure clockevents after cpufreq change
From: Robin Murphy @ 2016-11-29 15:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <BC3314B3-6504-4324-8707-C04534893DAC@gmail.com>
On 29/11/16 14:51, Alexander Kochetkov wrote:
>
>> 29 ????. 2016 ?., ? 17:32, Thomas Gleixner <tglx@linutronix.de> ???????(?):
>>
>> Can we just disable that global timer on affected SoCs and use something
>> else instead?
>
> I?ve sent patch series for fixing that on rockchip SoC.
> http://lists.infradead.org/pipermail/linux-rockchip/2016-November/013217.html
>
> But the series contain fix only for rk3188, because I don?t have another rockchip
> SoC. rk3288 and other could be easy fixed with dts files.
3288 (and probably anything newer) is irrelevant to this discussion, as
it has the arch timer interface - that may be busted in other ways (such
as not being correctly set up by firmware and not being always-on as it
should), but frequency is not one of them. This only affects
Cortex-A9/A5 based parts.
> There are a lot of other platforms what probably use shed_clock and
> clocksource form global-timer.
Presumably it's only an issue if they also have cpufreq?
> alexander at ubuntu:dts$ grep arm,cortex-a9-global-timer *
> am4372.dtsi: compatible = "arm,cortex-a9-global-timer";
> artpec6.dtsi: compatible = "arm,cortex-a9-global-timer";
> bcm5301x.dtsi: compatible = "arm,cortex-a9-global-timer";
> bcm63138.dtsi: compatible = "arm,cortex-a9-global-timer";
> bcm-cygnus.dtsi: compatible = "arm,cortex-a9-global-timer";
> bcm-nsp.dtsi: compatible = "arm,cortex-a9-global-timer";
> hip01.dtsi: compatible = "arm,cortex-a9-global-timer";
> rk3xxx.dtsi: compatible = "arm,cortex-a9-global-timer";
> stih407-family.dtsi: compatible = "arm,cortex-a9-global-timer";
> stih41x.dtsi: compatible = "arm,cortex-a9-global-timer";
> uniphier-common32.dtsi: compatible = "arm,cortex-a9-global-timer";
> uniphier-ph1-sld3.dtsi: compatible = "arm,cortex-a9-global-timer";
> vexpress-v2p-ca5s.dts: "arm,cortex-a9-global-timer";
I can tell you that one, for one, is never used, because it depends on
an input clock provided by the vexpress-osc driver which cannot be
probed sufficiently early.
Robin.
> vf500.dtsi: compatible = "arm,cortex-a9-global-timer";
> zx296702.dtsi: compatible = "arm,cortex-a9-global-timer";
> zynq-7000.dtsi: compatible = "arm,cortex-a9-global-timer?;
>
> Regards,
> Alexander.
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply
* [PATCH 4/5] arm64: dts: marvell: Add definition of SPI controller for Armada 3700
From: Romain Perier @ 2016-11-29 15:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129155129.6f3c76b6@free-electrons.com>
Hello,
Le 29/11/2016 ? 15:51, Thomas Petazzoni a ?crit :
>
>> diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
>> index e9bd587..84e4f57 100644
>> --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
>> +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
>> @@ -98,6 +98,19 @@
>> /* 32M internal register @ 0xd000_0000 */
>> ranges = <0x0 0x0 0xd0000000 0x2000000>;
>>
>> + spi0: spi at 10600 {
>> + compatible = "marvell,armada-3700-spi";
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + reg = <0x10600 0x5d>;
>> + clocks = <&nb_periph_clk 7>;
>> + clock-frequency = <200000000>;
>
> This property.
>
>> + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
>> + max-frequency = <66000000>;
>
> And this one no longer exist in your DT binding, so I guess they should
> be removed from here as well.
>
Good point, I was pretty sure that I have removed these.
I probably did something wrong with my rebase.
Thanks,
Romain
^ permalink raw reply
* [PATCH V7 0/3] irqchip: qcom: Add IRQ combiner driver
From: Agustin Vega-Frias @ 2016-11-29 15:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4126fa80-c8da-764f-9ea3-ec9966a19ea9@linaro.org>
Hi Hanjun,
On 2016-11-29 06:31, Hanjun Guo wrote:
> Hi Agustin,
>
> On 2016/11/14 5:59, Agustin Vega-Frias wrote:
>> Add support for IRQ combiners in the Top-level Control and Status
>> Registers (TCSR) hardware block in Qualcomm Technologies chips.
>>
>> The first patch fixes IRQ probe deferral by allowing platform_device
>> IRQ resources to be re-initialized if the ACPI core failed to find
>> the IRQ domain during ACPI bus scan.
>>
>> The second patch adds support for ResourceSource/IRQ domain mapping
>> when using Extended IRQ Resources with a specific ResourceSource.
>> These changes are conditional on the ACPI_GENERIC_GSI config.
>>
>> The third patch takes advantage of the new capabilities to implement
>> the driver for the IRQ combiners.
>>
>> Tested on top of v4.9-rc4.
>>
>> Changes V6 -> V7:
>> * Consolidate changes for ResourceSource/IRQ domain mapping to the
>> same
>> source file implementing the generic GSI support, making it
>> conditional
>> on CONFIG_ACPI_GENERIC_GSI.
>> * Eliminate some code duplication by implementing acpi_register_gsi in
>> terms of the new acpi_register_irq API.
>
> I had a test on Hisilicon D03 which needs patch 1 and 2 in this patch
> set to enable the mbigen irqchip, and it works pretty good.
>
> Patch 1/3 can remove the device dependency for the irqchip and platform
> devices, and I removed my patch (ACPI: irq: introduce interrupt
> producer) then add your patch 2/3, devices such as SAS and native
> network works fine on my D03.
Thanks for testing. I will submit V8 with some of the changes suggested
by Lorenzo hopefully later today.
Agustin
>
> I will comment on the patches later.
>
> Thanks
> Hanjun
--
Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a
Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH V7 2/3] ACPI: Add support for ResourceSource/IRQ domain mapping
From: Agustin Vega-Frias @ 2016-11-29 15:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161129121152.GA32453@red-moon>
Hi Lorenzo,
On 2016-11-29 07:11, Lorenzo Pieralisi wrote:
> Hi Agustin,
>
> On Mon, Nov 28, 2016 at 05:40:24PM -0500, Agustin Vega-Frias wrote:
>> Hi Rafael,
>>
>> Can you chime in on Lorenzo's feedback and the discussion below?
>> It would be great if you can comment on the reason ACPI does things
>> in a certain way.
>>
>> Hi Lorenzo,
>>
>> On 2016-11-25 06:40, Lorenzo Pieralisi wrote:
>> >Hi Agustin,
>> >
>> >On Thu, Nov 24, 2016 at 04:15:48PM +0000, Lorenzo Pieralisi wrote:
>> >
>> >[...]
>> >
>> >>> @@ -448,6 +449,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
>> >>> {
>> >>> struct acpi_resource_irq *irq;
>> >>> struct acpi_resource_extended_irq *ext_irq;
>> >>> + struct fwnode_handle *src;
>> >>>
>> >>> switch (ares->type) {
>> >>> case ACPI_RESOURCE_TYPE_IRQ:
>> >>> @@ -460,7 +462,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
>> >>> acpi_dev_irqresource_disabled(res, 0);
>> >>> return false;
>> >>> }
>> >>> - acpi_dev_get_irqresource(res, irq->interrupts[index],
>> >>> + acpi_dev_get_irqresource(res, irq->interrupts[index], NULL,
>> >>> irq->triggering, irq->polarity,
>> >>> irq->sharable, true);
>> >>> break;
>> >>> @@ -470,7 +472,8 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
>> >>> acpi_dev_irqresource_disabled(res, 0);
>> >>> return false;
>> >>> }
>> >>> - acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
>> >>> + src = acpi_get_irq_source_fwhandle(&ext_irq->resource_source);
>> >>
>> >>Is there a reason why we need to do the domain look-up here ?
>>
>> Because we need to pass the resource down to acpi_dev_get_irqresource
>> which does the mapping through acpi_register_irq/acpi_register_gsi.
>>
>> >>
>> >>I would like to understand if, by reshuffling the code (and by
>> >>returning
>> >>the resource_source to the calling code - somehow), it would be
>> >>possible
>> >>to just mirror what the OF code does in of_irq_get(), namely:
>> >>
>> >>(1) parse the irq entry -> of_irq_parse_one()
>> >>(2) look the domain up -> irq_find_host()
>> >>(3) create the mapping -> irq_create_of_mapping()
>> >>
>> >>You wrote the code already, I think it is just a matter of shuffling
>> >>it around (well, minus returning the resource_source to the caller
>> >>which is phandle equivalent in DT).
>>
>> This is one area in which DT and ACPI are fundamentally different. In
>> DT
>> once the flattened blob is expanded the data is fixed. In ACPI the
>> data
>> returned by a method can change. In reality most methods like CRS
>> return
>> constants, but given that per-spec they are methods the interpreter
>> has
>> to be involved, which makes it an expensive operation. I believe that
>> is
>> the reason the resource parsing code in ACPI attempts all mappings
>> during
>> the bus scan. Rafael can you comment on this?
>>
>> One way to do what you suggest would be to defer IRQ mapping by, e.g.,
>> populating res->start with the HW IRQ number and res->end with the
>> fwnode.
>> That way we can avoid having to walk the resource buffer when a
>> mapping
>> is needed. I don't think that approach would deviate much more from
>> the spec from what the current ahead-of-time mapping does, but it
>> would
>> require more changes in the core code. An alternative would be to do
>> that only for resources that fail to map.
>>
>> >>
>> >>You abstracted away (2) and (3) behind acpi_register_irq(), that
>> >>on anything than does not use ACPI_GENERIC_GSI is just glue code
>> >>to acpi_register_gsi().
>> >>
>> >>Also, it is not a question on this patch but I ask it here because it
>> >>is related. On ACPI you are doing the reverse of what is done in
>> >>DT in platform_get_irq():
>> >>
>> >>- get the resources already parsed -> platform_get_resource()
>> >>- if they are disabled -> acpi_irq_get()
>> >>
>> >>and I think the ordering is tied to my question above because
>> >>you carry out the domain look up in acpi_dev_resource_interrupt()
>> >>so that if for any reason it fails the corresponding resource
>> >>is disabled so that we try to get it again through acpi_irq_get().
>> >>
>> >>I suspect you did it this way to make sure:
>> >>
>> >>a) keep the current ACPI IRQ parsing interface changes to a mininum
>> >>b) avoid changing the behaviour on x86/ia64; in particular, calling
>> >> acpi_register_gsi() for the _same_ mapping (an IRQ that was already
>> >> registered at device creation resource parsing) multiple times can
>> >> trigger issues on x86/ia64
>>
>> You are correct about my reasons. I wanted to keep ACPI core code
>> changes
>> to a minimum, and I also needed to work within the current
>> implementation
>> which uses the pre-converted IRQ resources.
>>
>> >>
>> >>I think that's a reasonable approach but I wanted to get these
>> >>clarifications, I do not think you are far from getting this
>> >>done but since it is a significant change I think it is worth
>> >>discussing the points I raised above because I think the DT code
>> >>sequence in of_irq_get() (1-2-3 above) is cleaner from an IRQ
>> >>layer perspective (instead of having the domain look-up buried
>> >>inside the ACPI IRQ resource parsing API).
>> >
>> >I had another look and to achieve the above one way of doing that is to
>> >implement acpi_irq_get() only for ACPI_GENERIC_GSI and stub it out for
>> >!ACPI_GENERIC_GSI (ie return an error code so that on !ACPI_GENERIC_GSI
>> >we would fall back to current solution for ACPI). Within acpi_irq_get()
>> >you can easily carry out the same steps (1->2->3) above in ACPI
>> >you have
>> >the code already there I think it is easy to change the
>> >acpi_irq_get_cb() interface to return a filled in struct irq_fwspec and
>> >the interface would become identical to of_irq_get() that is an
>> >advantage to maintain it from an IRQ maintainership perspective I
>> >think,
>> >that's my opinion.
>>
>> I think I get what you mean. I'll take a stab at implementing
>> acpi_irq_get()
>> in the way you suggest.
>>
>> >
>> >There is still a nagging snag though. When platform devices are
>> >created, core ACPI code parse the resources through:
>> >
>> >acpi_dev_get_resources()
>> >
>> >and we _have_ to have way to avoid initializing IRQ resources that
>> >have a dependency (ie there is a resource_source pointer that is valid
>> >in their descriptors) that's easy to do if we think that's the right
>> >thing to do and can hardly break current code (which ignores the
>> >resource_source altogether).
>>
>> I'd rather keep the core code as-is with regard to the ahead-of-time
>> conversion. Whether a resource source is available at the time of
>> the bus
>> scan should be transparent to the code in drivers/acpi/resource.c, and
>> we need the initialization as a disabled resource to signal the need
>> to retry anyway.
>
> Yes, exactly that's the nub. Your current code works, I am trying to
> make it more modular and similar to the DT/irqdomain IRQ look-up path,
> which has its advantages.
>
> There are two options IMHO:
>
> - always disable the resource if it has a resource_source dependency
> and defer
> its parsing to acpi_irq_get() (where you can easily implement steps
> 1-2-3 above).
> What I wanted to say is that, by disabling the resource if it has a
> resource_source dependency you can't break x86/ia64 (it is ignored at
> present - hopefully there is nothing that we are not aware of behind
> that choice). On x86/ia64 acpi_irq_get() would be an empty stub.
> This way you would keep the irqdomain look-up out of the ACPI
> resource
> parsing API, correct ?
> - keep code as-is
I plan to work on V8 today to address the point you raised w.r.t. making
it look more like DT for maintainability. I will leave other things
as-is
with an understanding that we might revisit based on Rafael's feedback
Thanks,
Agustin
>
> Your point on _CRS being _current_ resource setting is perfectly valid
> so platform_get_resource() in platform_get_irq() must always take
> precedence over acpi_irq_get() (which should just apply to disabled
> resources), I am not sure that doing it the other way around is safe.
>
>> Rafael, do you have any other suggestions/feedback on how to go about
>> doing this?
>
> Yes, comments very appreciated, these changes are not trivial and need
> agreement.
>
> Thanks,
> Lorenzo
>
>>
>> Thanks,
>> Agustin
>>
>> >
>> >It is an important difference with DT probing, where the IRQ
>> >resources are only created if the domain reference (ie interrupt
>> >controller phandle) is satisfied at of_device_alloc() time
>> >(see of_device_alloc()).
>> >
>> >Thoughts ? Please let me know, the code to implement what I say
>> >is already in these patches, it is just a matter of reshuffling it.
>> >
>> >Thanks !
>> >Lorenzo
>>
>> --
>> Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm
>> Technologies, Inc.
>> Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a
>> Linux Foundation Collaborative Project.
--
Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a
Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH V7 2/3] ACPI: Add support for ResourceSource/IRQ domain mapping
From: Agustin Vega-Frias @ 2016-11-29 15:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJZ5v0guuqb6OzSJgz0L537EhH75EkR--Mmm+QSpKhYXBZxV9w@mail.gmail.com>
Hi Rafael,
On 2016-11-29 07:43, Rafael J. Wysocki wrote:
> On Tue, Nov 29, 2016 at 1:11 PM, Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
>> Hi Agustin,
>>
>> On Mon, Nov 28, 2016 at 05:40:24PM -0500, Agustin Vega-Frias wrote:
>>> Hi Rafael,
>>>
>>> Can you chime in on Lorenzo's feedback and the discussion below?
>>> It would be great if you can comment on the reason ACPI does things
>>> in a certain way.
>>>
>>> Hi Lorenzo,
>>>
>>> On 2016-11-25 06:40, Lorenzo Pieralisi wrote:
>>> >Hi Agustin,
>>> >
>>> >On Thu, Nov 24, 2016 at 04:15:48PM +0000, Lorenzo Pieralisi wrote:
>>> >
>>> >[...]
>>> >
>>> >>> @@ -448,6 +449,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
>>> >>> {
>>> >>> struct acpi_resource_irq *irq;
>>> >>> struct acpi_resource_extended_irq *ext_irq;
>>> >>> + struct fwnode_handle *src;
>>> >>>
>>> >>> switch (ares->type) {
>>> >>> case ACPI_RESOURCE_TYPE_IRQ:
>>> >>> @@ -460,7 +462,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
>>> >>> acpi_dev_irqresource_disabled(res, 0);
>>> >>> return false;
>>> >>> }
>>> >>> - acpi_dev_get_irqresource(res, irq->interrupts[index],
>>> >>> + acpi_dev_get_irqresource(res, irq->interrupts[index], NULL,
>>> >>> irq->triggering, irq->polarity,
>>> >>> irq->sharable, true);
>>> >>> break;
>>> >>> @@ -470,7 +472,8 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
>>> >>> acpi_dev_irqresource_disabled(res, 0);
>>> >>> return false;
>>> >>> }
>>> >>> - acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
>>> >>> + src = acpi_get_irq_source_fwhandle(&ext_irq->resource_source);
>>> >>
>>> >>Is there a reason why we need to do the domain look-up here ?
>>>
>>> Because we need to pass the resource down to acpi_dev_get_irqresource
>>> which does the mapping through acpi_register_irq/acpi_register_gsi.
>>>
>>> >>
>>> >>I would like to understand if, by reshuffling the code (and by
>>> >>returning
>>> >>the resource_source to the calling code - somehow), it would be
>>> >>possible
>>> >>to just mirror what the OF code does in of_irq_get(), namely:
>>> >>
>>> >>(1) parse the irq entry -> of_irq_parse_one()
>>> >>(2) look the domain up -> irq_find_host()
>>> >>(3) create the mapping -> irq_create_of_mapping()
>>> >>
>>> >>You wrote the code already, I think it is just a matter of shuffling
>>> >>it around (well, minus returning the resource_source to the caller
>>> >>which is phandle equivalent in DT).
>>>
>>> This is one area in which DT and ACPI are fundamentally different. In
>>> DT
>>> once the flattened blob is expanded the data is fixed. In ACPI the
>>> data
>>> returned by a method can change. In reality most methods like CRS
>>> return
>>> constants, but given that per-spec they are methods the interpreter
>>> has
>>> to be involved, which makes it an expensive operation. I believe that
>>> is
>>> the reason the resource parsing code in ACPI attempts all mappings
>>> during
>>> the bus scan. Rafael can you comment on this?
>>>
>>> One way to do what you suggest would be to defer IRQ mapping by,
>>> e.g.,
>>> populating res->start with the HW IRQ number and res->end with the
>>> fwnode.
>>> That way we can avoid having to walk the resource buffer when a
>>> mapping
>>> is needed. I don't think that approach would deviate much more from
>>> the spec from what the current ahead-of-time mapping does, but it
>>> would
>>> require more changes in the core code. An alternative would be to do
>>> that only for resources that fail to map.
>>>
>>> >>
>>> >>You abstracted away (2) and (3) behind acpi_register_irq(), that
>>> >>on anything than does not use ACPI_GENERIC_GSI is just glue code
>>> >>to acpi_register_gsi().
>>> >>
>>> >>Also, it is not a question on this patch but I ask it here because it
>>> >>is related. On ACPI you are doing the reverse of what is done in
>>> >>DT in platform_get_irq():
>>> >>
>>> >>- get the resources already parsed -> platform_get_resource()
>>> >>- if they are disabled -> acpi_irq_get()
>>> >>
>>> >>and I think the ordering is tied to my question above because
>>> >>you carry out the domain look up in acpi_dev_resource_interrupt()
>>> >>so that if for any reason it fails the corresponding resource
>>> >>is disabled so that we try to get it again through acpi_irq_get().
>>> >>
>>> >>I suspect you did it this way to make sure:
>>> >>
>>> >>a) keep the current ACPI IRQ parsing interface changes to a mininum
>>> >>b) avoid changing the behaviour on x86/ia64; in particular, calling
>>> >> acpi_register_gsi() for the _same_ mapping (an IRQ that was already
>>> >> registered at device creation resource parsing) multiple times can
>>> >> trigger issues on x86/ia64
>>>
>>> You are correct about my reasons. I wanted to keep ACPI core code
>>> changes
>>> to a minimum, and I also needed to work within the current
>>> implementation
>>> which uses the pre-converted IRQ resources.
>>>
>>> >>
>>> >>I think that's a reasonable approach but I wanted to get these
>>> >>clarifications, I do not think you are far from getting this
>>> >>done but since it is a significant change I think it is worth
>>> >>discussing the points I raised above because I think the DT code
>>> >>sequence in of_irq_get() (1-2-3 above) is cleaner from an IRQ
>>> >>layer perspective (instead of having the domain look-up buried
>>> >>inside the ACPI IRQ resource parsing API).
>>> >
>>> >I had another look and to achieve the above one way of doing that is to
>>> >implement acpi_irq_get() only for ACPI_GENERIC_GSI and stub it out for
>>> >!ACPI_GENERIC_GSI (ie return an error code so that on !ACPI_GENERIC_GSI
>>> >we would fall back to current solution for ACPI). Within acpi_irq_get()
>>> >you can easily carry out the same steps (1->2->3) above in ACPI
>>> >you have
>>> >the code already there I think it is easy to change the
>>> >acpi_irq_get_cb() interface to return a filled in struct irq_fwspec and
>>> >the interface would become identical to of_irq_get() that is an
>>> >advantage to maintain it from an IRQ maintainership perspective I
>>> >think,
>>> >that's my opinion.
>>>
>>> I think I get what you mean. I'll take a stab at implementing
>>> acpi_irq_get()
>>> in the way you suggest.
>>>
>>> >
>>> >There is still a nagging snag though. When platform devices are
>>> >created, core ACPI code parse the resources through:
>>> >
>>> >acpi_dev_get_resources()
>>> >
>>> >and we _have_ to have way to avoid initializing IRQ resources that
>>> >have a dependency (ie there is a resource_source pointer that is valid
>>> >in their descriptors) that's easy to do if we think that's the right
>>> >thing to do and can hardly break current code (which ignores the
>>> >resource_source altogether).
>>>
>>> I'd rather keep the core code as-is with regard to the ahead-of-time
>>> conversion. Whether a resource source is available at the time of
>>> the bus
>>> scan should be transparent to the code in drivers/acpi/resource.c,
>>> and
>>> we need the initialization as a disabled resource to signal the need
>>> to retry anyway.
>>
>> Yes, exactly that's the nub. Your current code works, I am trying to
>> make it more modular and similar to the DT/irqdomain IRQ look-up path,
>> which has its advantages.
>>
>> There are two options IMHO:
>>
>> - always disable the resource if it has a resource_source dependency
>> and defer
>> its parsing to acpi_irq_get() (where you can easily implement steps
>> 1-2-3 above).
>> What I wanted to say is that, by disabling the resource if it has a
>> resource_source dependency you can't break x86/ia64 (it is ignored
>> at
>> present - hopefully there is nothing that we are not aware of behind
>> that choice). On x86/ia64 acpi_irq_get() would be an empty stub.
>> This way you would keep the irqdomain look-up out of the ACPI
>> resource
>> parsing API, correct ?
>> - keep code as-is
>>
>> Your point on _CRS being _current_ resource setting is perfectly valid
>> so platform_get_resource() in platform_get_irq() must always take
>> precedence over acpi_irq_get() (which should just apply to disabled
>> resources), I am not sure that doing it the other way around is safe.
>>
>>> Rafael, do you have any other suggestions/feedback on how to go about
>>> doing this?
>>
>> Yes, comments very appreciated, these changes are not trivial and need
>> agreement.
>
> So I need more time.
Please wait for V8 which will address some issues raised by Lorenzo.
>
> But basically, _CRS can't really change on the fly AFAICS. I'm not
> even sure it is valid for it to change at all after the first
> evaluation if _SRS/_PRS are not present.
That's good to know and it opens more possibilities.
Thanks,
Agustin
>
> Thanks,
> Rafael
--
Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a
Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH 1/2] ARM: mm: fix set_memory_*() bounds checks
From: Dave Gerlach @ 2016-11-29 15:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <E1c8r91-0007wL-Fl@rmk-PC.armlinux.org.uk>
Hi,
On 11/21/2016 10:08 AM, Russell King wrote:
> The set_memory_*() bounds checks are buggy on several fronts:
>
> 1. They fail to round the region size up if the passed address is not
> page aligned.
> 2. The region check was incomplete, and didn't correspond with what
> was being asked of apply_to_page_range()
>
> So, rework change_memory_common() to fix these problems, adding an
> "in_region()" helper to determine whether the start & size fit within
> the provided region start and stop addresses.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
> arch/arm/mm/pageattr.c | 26 +++++++++++++-------------
> 1 file changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c
> index d19b1ad29b07..db09f2e7efda 100644
> --- a/arch/arm/mm/pageattr.c
> +++ b/arch/arm/mm/pageattr.c
> @@ -34,28 +34,28 @@ static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr,
> return 0;
> }
>
> +static bool in_range(unsigned long start, unsigned long size,
> + unsigned long range_start, unsigned long range_end)
> +{
> + return start >= range_start && start < range_end &&
> + size <= range_end - start;
> +}
> +
> static int change_memory_common(unsigned long addr, int numpages,
> pgprot_t set_mask, pgprot_t clear_mask)
> {
> - unsigned long start = addr;
> - unsigned long size = PAGE_SIZE*numpages;
> - unsigned long end = start + size;
> + unsigned long start = addr & PAGE_SIZE;
This doesn't work as is, I believe 'start' should be set to
PAGE_ALIGN(addr), addr & PAGE_SIZE as it is doesn't make sense. If I
make this change this code works ok.
Regards,
Dave
> + unsigned long end = PAGE_ALIGN(addr) + numpages * PAGE_SIZE;
> + unsigned long size = end - start;
> int ret;
> struct page_change_data data;
>
> - if (!IS_ALIGNED(addr, PAGE_SIZE)) {
> - start &= PAGE_MASK;
> - end = start + size;
> - WARN_ON_ONCE(1);
> - }
> + WARN_ON_ONCE(start != addr);
>
> - if (!numpages)
> + if (!size)
> return 0;
>
> - if (start < MODULES_VADDR || start >= MODULES_END)
> - return -EINVAL;
> -
> - if (end < MODULES_VADDR || start >= MODULES_END)
> + if (!in_range(start, size, MODULES_VADDR, MODULES_END))
> return -EINVAL;
>
> data.set_mask = set_mask;
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox