diff options
author | Florian Fainelli <florian@openwrt.org> | 2013-01-08 22:20:16 +0000 |
---|---|---|
committer | Florian Fainelli <florian@openwrt.org> | 2013-01-08 22:20:16 +0000 |
commit | 91e3a3252f68589aaa7d5131cbe77c2c552c1df4 (patch) | |
tree | a5cbc0f5235b30a249d4532479600f183be2eec6 /target/linux/mvebu/patches-3.8 | |
parent | b5988e0640bd2ad96cc2c0b79197873f7ab9085c (diff) | |
download | upstream-91e3a3252f68589aaa7d5131cbe77c2c552c1df4.tar.gz upstream-91e3a3252f68589aaa7d5131cbe77c2c552c1df4.tar.bz2 upstream-91e3a3252f68589aaa7d5131cbe77c2c552c1df4.zip |
mvebu: add inital support for Marvell Armada XP/370 SoCs
This brings in the initial support for the Marvell Armada XP/370 SoCs.
Successfully tested on RD-A370-A1 and DB-MV784MP-GP boards the following
interfaces:
- Ethernet
- SDIO
- GPIOs
- SATA
Signed-off-by: Florian Fainelli <florian@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35058 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/mvebu/patches-3.8')
18 files changed, 1201 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.8/001-clk_mvebu_remove_inappropriate_init_tagging.patch b/target/linux/mvebu/patches-3.8/001-clk_mvebu_remove_inappropriate_init_tagging.patch new file mode 100644 index 0000000000..33787f266b --- /dev/null +++ b/target/linux/mvebu/patches-3.8/001-clk_mvebu_remove_inappropriate_init_tagging.patch @@ -0,0 +1,28 @@ +From: Joshua Coombs <josh.coombs@gmail.com> + +If the Orion WDT driver is built as a module, an opps occurs during +clk lookup when calling mvebu_clk_gating_get_src(). Remove the +inappropriate __init tag so the function is available for modules +after kernel init. + +Signed-off-by: Joshua Coombs <josh.coombs@gmail.com> +Signed-off-by: Andrew Lunn <andrew@lunn.ch> +--- + drivers/clk/mvebu/clk-gating-ctrl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c +index c6d3c26..8fa5408 100644 +--- a/drivers/clk/mvebu/clk-gating-ctrl.c ++++ b/drivers/clk/mvebu/clk-gating-ctrl.c +@@ -32,7 +32,7 @@ struct mvebu_soc_descr { + + #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) + +-static struct clk __init *mvebu_clk_gating_get_src( ++static struct clk *mvebu_clk_gating_get_src( + struct of_phandle_args *clkspec, void *data) + { + struct mvebu_gating_ctrl *ctrl = (struct mvebu_gating_ctrl *)data; +-- +1.7.10.4 diff --git a/target/linux/mvebu/patches-3.8/002-dma_mv_xor_fix_error_handling.patch b/target/linux/mvebu/patches-3.8/002-dma_mv_xor_fix_error_handling.patch new file mode 100644 index 0000000000..f5940fbb1d --- /dev/null +++ b/target/linux/mvebu/patches-3.8/002-dma_mv_xor_fix_error_handling.patch @@ -0,0 +1,38 @@ +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + +When mv_xor_channel_add() fails for one XOR channel, we jump to the +err_channel_add label to clean up all previous channels that had been +initialized correctly. Unfortunately, while handling this error +condition, we were disposing the IRQ mapping before calling +mv_xor_channel_remove() (which does the free_irq()), which is +incorrect. + +Instead, do things properly in the reverse order of the +initialization: first remove the XOR channel (so that free_irq() is +done), and then dispose the IRQ mapping. + +This avoids ugly warnings when for some reason one of the XOR channel +fails to initialize. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + drivers/dma/mv_xor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c +index ac71f55..cc5d23d 100644 +--- a/drivers/dma/mv_xor.c ++++ b/drivers/dma/mv_xor.c +@@ -1361,9 +1361,9 @@ static int mv_xor_probe(struct platform_device *pdev) + err_channel_add: + for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) + if (xordev->channels[i]) { ++ mv_xor_channel_remove(xordev->channels[i]); + if (pdev->dev.of_node) + irq_dispose_mapping(xordev->channels[i]->irq); +- mv_xor_channel_remove(xordev->channels[i]); + } + + clk_disable_unprepare(xordev->clk); +-- +1.7.10.4 diff --git a/target/linux/mvebu/patches-3.8/003-dma_mv_xor_fix_error_handling_clocks.patch b/target/linux/mvebu/patches-3.8/003-dma_mv_xor_fix_error_handling_clocks.patch new file mode 100644 index 0000000000..9bee8acded --- /dev/null +++ b/target/linux/mvebu/patches-3.8/003-dma_mv_xor_fix_error_handling_clocks.patch @@ -0,0 +1,35 @@ +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + +When a channel fails to initialize, we release all ressources, +including clocks. However, a XOR unit is not necessarily associated to +a clock (some variants of Marvell SoCs have a clock for XOR units, +some don't), so we shouldn't unconditionally be releasing the clock. + +Instead, just like we do in the mv_xor_remove() function, we should +check if one clock was found before releasing it. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + drivers/dma/mv_xor.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c +index cc5d23d..e17fad0 100644 +--- a/drivers/dma/mv_xor.c ++++ b/drivers/dma/mv_xor.c +@@ -1366,8 +1366,11 @@ err_channel_add: + irq_dispose_mapping(xordev->channels[i]->irq); + } + +- clk_disable_unprepare(xordev->clk); +- clk_put(xordev->clk); ++ if (!IS_ERR(xordev->clk)) { ++ clk_disable_unprepare(xordev->clk); ++ clk_put(xordev->clk); ++ } ++ + return ret; + } + +-- +1.7.10.4 diff --git a/target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch b/target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch new file mode 100644 index 0000000000..c7e992fc4f --- /dev/null +++ b/target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch @@ -0,0 +1,75 @@ +From: Dmitri Epshtein <dima@marvell.com> + +In order for the driver to behave properly in a SMP context, the same +transmit queue should be used by the kernel in dev_queue_xmit() and in +the driver's mvneta_tx() function. To achieve that, the driver now +implements the ->ndo_select_txq() operation. + +For now, it always returns the same transmit queue, txq_def, until the +driver is expanded to properly take advantage of the multiqueue +capabilities of the hardware. + +Without this patch, the network driver crashes the kernel almost +immediately on Armada XP platforms, if the network load is at least a +little bit parallel (i.e several threads). + +[Thomas Petazzoni: reword commit message] +Signed-off-by: Dmitri Epshtein <dima@marvell.com> +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- +This is 3.8-rc material. +--- + drivers/net/ethernet/marvell/mvneta.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c +index b6025c3..af2c421 100644 +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -1310,6 +1310,17 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb) + return MVNETA_TX_L4_CSUM_NOT; + } + ++static u16 mvneta_tx_policy(struct mvneta_port *pp, struct sk_buff *skb) ++{ ++ return (u16)txq_def; ++} ++ ++static u16 mvneta_select_txq(struct net_device *dev, struct sk_buff *skb) ++{ ++ struct mvneta_port *pp = netdev_priv(dev); ++ return mvneta_tx_policy(pp, skb); ++} ++ + /* Returns rx queue pointer (find last set bit) according to causeRxTx + * value + */ +@@ -1476,7 +1487,8 @@ error: + static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) + { + struct mvneta_port *pp = netdev_priv(dev); +- struct mvneta_tx_queue *txq = &pp->txqs[txq_def]; ++ u16 txq_id = mvneta_tx_policy(pp, skb); ++ struct mvneta_tx_queue *txq = &pp->txqs[txq_id]; + struct mvneta_tx_desc *tx_desc; + struct netdev_queue *nq; + int frags = 0; +@@ -1486,7 +1498,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) + goto out; + + frags = skb_shinfo(skb)->nr_frags + 1; +- nq = netdev_get_tx_queue(dev, txq_def); ++ nq = netdev_get_tx_queue(dev, txq_id); + + /* Get a descriptor for the first part of the packet */ + tx_desc = mvneta_txq_next_desc_get(txq); +@@ -2550,6 +2562,7 @@ static const struct net_device_ops mvneta_netdev_ops = { + .ndo_change_mtu = mvneta_change_mtu, + .ndo_tx_timeout = mvneta_tx_timeout, + .ndo_get_stats64 = mvneta_get_stats64, ++ .ndo_select_queue = mvneta_select_txq, + }; + + const struct ethtool_ops mvneta_eth_tool_ops = { +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/005-arm_mvebu_use_global_interrupts_for_gpio.patch b/target/linux/mvebu/patches-3.8/005-arm_mvebu_use_global_interrupts_for_gpio.patch new file mode 100644 index 0000000000..726e2529fc --- /dev/null +++ b/target/linux/mvebu/patches-3.8/005-arm_mvebu_use_global_interrupts_for_gpio.patch @@ -0,0 +1,174 @@ +The Armada XP GPIO controller has two ways of notifying interrupts: +using global interrupts or using per-CPU interrupts. In an attempt to +use the best available features, the 'marvell,armadaxp-gpio' +compatible string selects a variant of the gpio-mvebu driver that +makes use of the per-CPU interrupts. + +Unfortunately, this doesn't work properly in a SMP context, because we +fall into cases where the GPIO interrupt is enabled on CPU X at the +GPIO controller level, but on CPU Y at the interrupt controller +level. It is not yet clear how to fix that easily. + +So for 3.8, our approach is to switch to global interrupts for GPIOs, +so that we do not fall into this per-CPU interrupts problem. + +This patch therefore fixes GPIO interrupts on Armada XP +platforms. Without this patch, GPIO interrupts simply do not work +reliably, because their proper operation depends on which CPU the code +requesting the interrupt is running. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- +This is 3.8-rc material. +--- + arch/arm/boot/dts/armada-xp-mv78230.dtsi | 14 ++++++-------- + arch/arm/boot/dts/armada-xp-mv78260.dtsi | 21 +++++++++------------ + arch/arm/boot/dts/armada-xp-mv78460.dtsi | 21 +++++++++------------ + 3 files changed, 24 insertions(+), 32 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +index 271855a..e041f42 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +@@ -50,27 +50,25 @@ + }; + + gpio0: gpio@d0018100 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018100 0x40>, +- <0xd0018800 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <16>, <17>, <18>, <19>; ++ interrupts = <82>, <83>, <84>, <85>; + }; + + gpio1: gpio@d0018140 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018140 0x40>, +- <0xd0018840 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018140 0x40>; + ngpios = <17>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <20>, <21>, <22>; ++ interrupts = <87>, <88>, <89>; + }; + }; + }; +diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +index 1c1937d..9e23bd8 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +@@ -51,39 +51,36 @@ + }; + + gpio0: gpio@d0018100 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018100 0x40>, +- <0xd0018800 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <16>, <17>, <18>, <19>; ++ interrupts = <82>, <83>, <84>, <85>; + }; + + gpio1: gpio@d0018140 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018140 0x40>, +- <0xd0018840 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018140 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <20>, <21>, <22>, <23>; ++ interrupts = <87>, <88>, <89>, <90>; + }; + + gpio2: gpio@d0018180 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018180 0x40>, +- <0xd0018870 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018180 0x40>; + ngpios = <3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <24>; ++ interrupts = <91>; + }; + + ethernet@d0034000 { +diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +index 4905cf3..9659661 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +@@ -66,39 +66,36 @@ + }; + + gpio0: gpio@d0018100 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018100 0x40>, +- <0xd0018800 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <16>, <17>, <18>, <19>; ++ interrupts = <82>, <83>, <84>, <85>; + }; + + gpio1: gpio@d0018140 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018140 0x40>, +- <0xd0018840 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018140 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <20>, <21>, <22>, <23>; ++ interrupts = <87>, <88>, <89>, <90>; + }; + + gpio2: gpio@d0018180 { +- compatible = "marvell,armadaxp-gpio"; +- reg = <0xd0018180 0x40>, +- <0xd0018870 0x30>; ++ compatible = "marvell,orion-gpio"; ++ reg = <0xd0018180 0x40>; + ngpios = <3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; +- interrupts = <24>; ++ interrupts = <91>; + }; + + ethernet@d0034000 { +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch b/target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch new file mode 100644 index 0000000000..8a77de3068 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch @@ -0,0 +1,101 @@ +The MMC core subsystem provides in drivers/mmc/core/slot-gpio.c a nice +set of helper functions to simplify the management of the write +protect GPIO in MMC host drivers. This patch migrates the mvsdio +driver to using those helpers, which will make the ->probe() code +simpler, and therefore ease the process of adding a Device Tree +binding for this driver. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + drivers/mmc/host/mvsdio.c | 34 +++++----------------------------- + 1 file changed, 5 insertions(+), 29 deletions(-) + +diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c +index de4c20b..a24a22f 100644 +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -22,6 +22,7 @@ + #include <linux/clk.h> + #include <linux/gpio.h> + #include <linux/mmc/host.h> ++#include <linux/mmc/slot-gpio.h> + + #include <asm/sizes.h> + #include <asm/unaligned.h> +@@ -54,7 +55,6 @@ struct mvsd_host { + int irq; + struct clk *clk; + int gpio_card_detect; +- int gpio_write_protect; + }; + + #define mvsd_write(offs, val) writel(val, iobase + (offs)) +@@ -566,20 +566,6 @@ static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable) + spin_unlock_irqrestore(&host->lock, flags); + } + +-static int mvsd_get_ro(struct mmc_host *mmc) +-{ +- struct mvsd_host *host = mmc_priv(mmc); +- +- if (host->gpio_write_protect) +- return gpio_get_value(host->gpio_write_protect); +- +- /* +- * Board doesn't support read only detection; let the mmc core +- * decide what to do. +- */ +- return -ENOSYS; +-} +- + static void mvsd_power_up(struct mvsd_host *host) + { + void __iomem *iobase = host->base; +@@ -676,7 +662,7 @@ static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + + static const struct mmc_host_ops mvsd_ops = { + .request = mvsd_request, +- .get_ro = mvsd_get_ro, ++ .get_ro = mmc_gpio_get_ro, + .set_ios = mvsd_set_ios, + .enable_sdio_irq = mvsd_enable_sdio_irq, + }; +@@ -798,15 +784,7 @@ static int __init mvsd_probe(struct platform_device *pdev) + if (!host->gpio_card_detect) + mmc->caps |= MMC_CAP_NEEDS_POLL; + +- if (mvsd_data->gpio_write_protect) { +- ret = gpio_request(mvsd_data->gpio_write_protect, +- DRIVER_NAME " wp"); +- if (ret == 0) { +- gpio_direction_input(mvsd_data->gpio_write_protect); +- host->gpio_write_protect = +- mvsd_data->gpio_write_protect; +- } +- } ++ mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); + + setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host); + platform_set_drvdata(pdev, mmc); +@@ -831,8 +809,7 @@ out: + free_irq(gpio_to_irq(host->gpio_card_detect), host); + gpio_free(host->gpio_card_detect); + } +- if (host->gpio_write_protect) +- gpio_free(host->gpio_write_protect); ++ mmc_gpio_free_ro(mmc); + if (host->base) + iounmap(host->base); + } +@@ -861,8 +838,7 @@ static int __exit mvsd_remove(struct platform_device *pdev) + } + mmc_remove_host(mmc); + free_irq(host->irq, host); +- if (host->gpio_write_protect) +- gpio_free(host->gpio_write_protect); ++ mmc_gpio_free_ro(mmc); + del_timer_sync(&host->timer); + mvsd_power_down(host); + iounmap(host->base); +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch b/target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch new file mode 100644 index 0000000000..287dedf1d9 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch @@ -0,0 +1,105 @@ +The MMC core subsystem provides in drivers/mmc/core/slot-gpio.c a nice +set of helper functions to simplify the management of the card detect +GPIO in MMC host drivers. This patch migrates the mvsdio driver to +using those helpers, which will make the ->probe() code simpler, and +therefore ease the process of adding a Device Tree binding for this +driver. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + drivers/mmc/host/mvsdio.c | 44 +++++++++----------------------------------- + 1 file changed, 9 insertions(+), 35 deletions(-) + +diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c +index a24a22f..baf19fc 100644 +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -54,7 +54,6 @@ struct mvsd_host { + struct resource *res; + int irq; + struct clk *clk; +- int gpio_card_detect; + }; + + #define mvsd_write(offs, val) writel(val, iobase + (offs)) +@@ -540,13 +539,6 @@ static void mvsd_timeout_timer(unsigned long data) + mmc_request_done(host->mmc, mrq); + } + +-static irqreturn_t mvsd_card_detect_irq(int irq, void *dev) +-{ +- struct mvsd_host *host = dev; +- mmc_detect_change(host->mmc, msecs_to_jiffies(100)); +- return IRQ_HANDLED; +-} +- + static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable) + { + struct mvsd_host *host = mmc_priv(mmc); +@@ -765,23 +757,11 @@ static int __init mvsd_probe(struct platform_device *pdev) + clk_prepare_enable(host->clk); + } + +- if (mvsd_data->gpio_card_detect) { +- ret = gpio_request(mvsd_data->gpio_card_detect, +- DRIVER_NAME " cd"); +- if (ret == 0) { +- gpio_direction_input(mvsd_data->gpio_card_detect); +- irq = gpio_to_irq(mvsd_data->gpio_card_detect); +- ret = request_irq(irq, mvsd_card_detect_irq, +- IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING, +- DRIVER_NAME " cd", host); +- if (ret == 0) +- host->gpio_card_detect = +- mvsd_data->gpio_card_detect; +- else +- gpio_free(mvsd_data->gpio_card_detect); +- } +- } +- if (!host->gpio_card_detect) ++ if (gpio_is_valid(mvsd_data->gpio_card_detect)) { ++ ret = mmc_gpio_request_cd(mmc, mvsd_data->gpio_card_detect); ++ if (ret) ++ goto out; ++ } else + mmc->caps |= MMC_CAP_NEEDS_POLL; + + mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); +@@ -794,9 +774,9 @@ static int __init mvsd_probe(struct platform_device *pdev) + + pr_notice("%s: %s driver initialized, ", + mmc_hostname(mmc), DRIVER_NAME); +- if (host->gpio_card_detect) ++ if (!(mmc->caps & MMC_CAP_NEEDS_POLL)) + printk("using GPIO %d for card detection\n", +- host->gpio_card_detect); ++ mvsd_data->gpio_card_detect); + else + printk("lacking card detect (fall back to polling)\n"); + return 0; +@@ -805,10 +785,7 @@ out: + if (host) { + if (host->irq) + free_irq(host->irq, host); +- if (host->gpio_card_detect) { +- free_irq(gpio_to_irq(host->gpio_card_detect), host); +- gpio_free(host->gpio_card_detect); +- } ++ mmc_gpio_free_cd(mmc); + mmc_gpio_free_ro(mmc); + if (host->base) + iounmap(host->base); +@@ -832,10 +809,7 @@ static int __exit mvsd_remove(struct platform_device *pdev) + if (mmc) { + struct mvsd_host *host = mmc_priv(mmc); + +- if (host->gpio_card_detect) { +- free_irq(gpio_to_irq(host->gpio_card_detect), host); +- gpio_free(host->gpio_card_detect); +- } ++ mmc_gpio_free_cd(mmc); + mmc_remove_host(mmc); + free_irq(host->irq, host); + mmc_gpio_free_ro(mmc); +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch b/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch new file mode 100644 index 0000000000..4f8cc2011f --- /dev/null +++ b/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch @@ -0,0 +1,169 @@ +This patch adds a simple Device Tree binding for the mvsdio driver, as +well as the necessary documentation for it. Compatibility with non-DT +platforms is preserved, by keeping the platform_data based +initialization. + +We introduce a small difference between non-DT and DT platforms: DT +platforms are required to provide a clocks = <...> property, which the +driver uses to get the frequency of the clock that goes to the SDIO +IP. The behaviour on non-DT platforms is kept unchanged: a clock +reference is not mandatory, but the clock frequency must be passed in +the "clock" field of the mvsdio_platform_data structure. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + .../devicetree/bindings/mmc/orion-sdio.txt | 17 ++++++ + drivers/mmc/host/mvsdio.c | 60 +++++++++++++++----- + 2 files changed, 62 insertions(+), 15 deletions(-) + create mode 100644 Documentation/devicetree/bindings/mmc/orion-sdio.txt + +diff --git a/Documentation/devicetree/bindings/mmc/orion-sdio.txt b/Documentation/devicetree/bindings/mmc/orion-sdio.txt +new file mode 100644 +index 0000000..84f0ebd +--- /dev/null ++++ b/Documentation/devicetree/bindings/mmc/orion-sdio.txt +@@ -0,0 +1,17 @@ ++* Marvell orion-sdio controller ++ ++This file documents differences between the core properties in mmc.txt ++and the properties used by the orion-sdio driver. ++ ++- compatible: Should be "marvell,orion-sdio" ++- clocks: reference to the clock of the SDIO interface ++ ++Example: ++ ++ mvsdio@d00d4000 { ++ compatible = "marvell,orion-sdio"; ++ reg = <0xd00d4000 0x200>; ++ interrupts = <54>; ++ clocks = <&gateclk 17>; ++ status = "disabled"; ++ }; +diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c +index baf19fc..56954bc 100644 +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -21,6 +21,8 @@ + #include <linux/irq.h> + #include <linux/clk.h> + #include <linux/gpio.h> ++#include <linux/of_gpio.h> ++#include <linux/of_irq.h> + #include <linux/mmc/host.h> + #include <linux/mmc/slot-gpio.h> + +@@ -683,17 +685,17 @@ mv_conf_mbus_windows(struct mvsd_host *host, + + static int __init mvsd_probe(struct platform_device *pdev) + { ++ struct device_node *np = pdev->dev.of_node; + struct mmc_host *mmc = NULL; + struct mvsd_host *host = NULL; +- const struct mvsdio_platform_data *mvsd_data; + const struct mbus_dram_target_info *dram; + struct resource *r; + int ret, irq; ++ int gpio_card_detect, gpio_write_protect; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); +- mvsd_data = pdev->dev.platform_data; +- if (!r || irq < 0 || !mvsd_data) ++ if (!r || irq < 0) + return -ENXIO; + + r = request_mem_region(r->start, SZ_1K, DRIVER_NAME); +@@ -710,7 +712,35 @@ static int __init mvsd_probe(struct platform_device *pdev) + host->mmc = mmc; + host->dev = &pdev->dev; + host->res = r; +- host->base_clock = mvsd_data->clock / 2; ++ ++ /* Some non-DT platforms do not pass a clock, and the clock ++ frequency is passed through platform_data. On DT platforms, ++ a clock must always be passed, even if there is no gatable ++ clock associated to the SDIO interface (it can simply be a ++ fixed rate clock). */ ++ host->clk = clk_get(&pdev->dev, NULL); ++ if (!IS_ERR(host->clk)) ++ clk_prepare_enable(host->clk); ++ ++ if (np) { ++ if (IS_ERR(host->clk)) { ++ dev_err(&pdev->dev, "DT platforms must have a clock associated\n"); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ host->base_clock = clk_get_rate(host->clk) / 2; ++ gpio_card_detect = of_get_named_gpio(np, "cd-gpios", 0); ++ gpio_write_protect = of_get_named_gpio(np, "wp-gpios", 0); ++ } else { ++ const struct mvsdio_platform_data *mvsd_data; ++ mvsd_data = pdev->dev.platform_data; ++ if (!mvsd_data) ++ return -ENXIO; ++ host->base_clock = mvsd_data->clock / 2; ++ gpio_card_detect = mvsd_data->gpio_card_detect; ++ gpio_write_protect = mvsd_data->gpio_write_protect; ++ } + + mmc->ops = &mvsd_ops; + +@@ -750,21 +780,14 @@ static int __init mvsd_probe(struct platform_device *pdev) + } else + host->irq = irq; + +- /* Not all platforms can gate the clock, so it is not +- an error if the clock does not exists. */ +- host->clk = clk_get(&pdev->dev, NULL); +- if (!IS_ERR(host->clk)) { +- clk_prepare_enable(host->clk); +- } +- +- if (gpio_is_valid(mvsd_data->gpio_card_detect)) { +- ret = mmc_gpio_request_cd(mmc, mvsd_data->gpio_card_detect); ++ if (gpio_is_valid(gpio_card_detect)) { ++ ret = mmc_gpio_request_cd(mmc, gpio_card_detect); + if (ret) + goto out; + } else + mmc->caps |= MMC_CAP_NEEDS_POLL; + +- mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); ++ mmc_gpio_request_ro(mmc, gpio_write_protect); + + setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host); + platform_set_drvdata(pdev, mmc); +@@ -776,7 +799,7 @@ static int __init mvsd_probe(struct platform_device *pdev) + mmc_hostname(mmc), DRIVER_NAME); + if (!(mmc->caps & MMC_CAP_NEEDS_POLL)) + printk("using GPIO %d for card detection\n", +- mvsd_data->gpio_card_detect); ++ gpio_card_detect); + else + printk("lacking card detect (fall back to polling)\n"); + return 0; +@@ -855,12 +878,19 @@ static int mvsd_resume(struct platform_device *dev) + #define mvsd_resume NULL + #endif + ++static const struct of_device_id mvsdio_dt_ids[] = { ++ { .compatible = "marvell,orion-sdio" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, mvsdio_dt_ids); ++ + static struct platform_driver mvsd_driver = { + .remove = __exit_p(mvsd_remove), + .suspend = mvsd_suspend, + .resume = mvsd_resume, + .driver = { + .name = DRIVER_NAME, ++ .of_match_table = mvsdio_dt_ids, + }, + }; + +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch b/target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch new file mode 100644 index 0000000000..394fc4ceba --- /dev/null +++ b/target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch @@ -0,0 +1,48 @@ +On many Marvell SoCs, the pins used for the SDIO interface are part of +the MPP pins, that are muxable pins. In order to get the muxing of +those pins correct, this commit integrates the mvsdio driver with the +pinctrl infrastructure by calling devm_pinctrl_get_select_default() +during ->probe(). + +Note that we permit this function to fail because not all Marvell +platforms have yet been fully converted to using the pinctrl +infrastructure. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + drivers/mmc/host/mvsdio.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c +index 56954bc..feb16bd 100644 +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -25,6 +25,7 @@ + #include <linux/of_irq.h> + #include <linux/mmc/host.h> + #include <linux/mmc/slot-gpio.h> ++#include <linux/pinctrl/consumer.h> + + #include <asm/sizes.h> + #include <asm/unaligned.h> +@@ -692,6 +693,7 @@ static int __init mvsd_probe(struct platform_device *pdev) + struct resource *r; + int ret, irq; + int gpio_card_detect, gpio_write_protect; ++ struct pinctrl *pinctrl; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); +@@ -713,6 +715,10 @@ static int __init mvsd_probe(struct platform_device *pdev) + host->dev = &pdev->dev; + host->res = r; + ++ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); ++ if (IS_ERR(pinctrl)) ++ dev_warn(&pdev->dev, "no pins associated\n"); ++ + /* Some non-DT platforms do not pass a clock, and the clock + frequency is passed through platform_data. On DT platforms, + a clock must always be passed, even if there is no gatable +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch b/target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch new file mode 100644 index 0000000000..36e5ea2a22 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch @@ -0,0 +1,30 @@ +Now that the mvsdio MMC driver has a Device Tree binding, we add the +Device Tree informations to describe the SDIO interface available in +the Armada 370/XP SoCs. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-xp.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi +index cf6c48a..41a5b11 100644 +--- a/arch/arm/boot/dts/armada-370-xp.dtsi ++++ b/arch/arm/boot/dts/armada-370-xp.dtsi +@@ -129,6 +129,14 @@ + clocks = <&coreclk 0>; + status = "disabled"; + }; ++ ++ mvsdio@d00d4000 { ++ compatible = "marvell,orion-sdio"; ++ reg = <0xd00d4000 0x200>; ++ interrupts = <54>; ++ clocks = <&gateclk 17>; ++ status = "disabled"; ++ }; + }; + }; + +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch b/target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch new file mode 100644 index 0000000000..6b245a0179 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch @@ -0,0 +1,38 @@ +The SDIO interface is available either on pins MPP9/11/12/13/14/15 or +MPP47/48/49/50/51/52 on the Armada 370. Even though all combinations +are potentially possible, those two muxing options are the most +probable ones, so we provide those at the SoC level .dtsi file. + +In practice, in turns out the Armada 370 DB board uses the former, +while the Armada 370 Mirabox uses the latter. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi +index 636cf7d..88f9bab 100644 +--- a/arch/arm/boot/dts/armada-370.dtsi ++++ b/arch/arm/boot/dts/armada-370.dtsi +@@ -47,6 +47,18 @@ + pinctrl { + compatible = "marvell,mv88f6710-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins1: sdio-pins1 { ++ marvell,pins = "mpp9", "mpp11", "mpp12", ++ "mpp13", "mpp14", "mpp15"; ++ marvell,function = "sd0"; ++ }; ++ ++ sdio_pins2: sdio-pins2 { ++ marvell,pins = "mpp47", "mpp48", "mpp49", ++ "mpp50", "mpp51", "mpp52"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch b/target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch new file mode 100644 index 0000000000..f4d9a96f83 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch @@ -0,0 +1,69 @@ +The SDIO interface is only available on pins MPP30/31/32/33/34/35 on +the various Armada XP variants, so we provide a pin muxing option for +this in the Armada XP .dtsi files. + +Even though those muxing options are the same for MV78230, MV78260 and +MV78460, we keep them in each .dtsi file, because the number of pins, +and therefore the declaration of the pinctrl node, is different for +each SoC variant. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-xp-mv78230.dtsi | 6 ++++++ + arch/arm/boot/dts/armada-xp-mv78260.dtsi | 6 ++++++ + arch/arm/boot/dts/armada-xp-mv78460.dtsi | 6 ++++++ + 3 files changed, 18 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +index c45c7b4..3fa9c84 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +@@ -40,6 +40,12 @@ + pinctrl { + compatible = "marvell,mv78230-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins: sdio-pins { ++ marvell,pins = "mpp30", "mpp31", "mpp32", ++ "mpp33", "mpp34", "mpp35"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +index a2aee57..5a907b3 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +@@ -48,6 +48,12 @@ + pinctrl { + compatible = "marvell,mv78260-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins: sdio-pins { ++ marvell,pins = "mpp30", "mpp31", "mpp32", ++ "mpp33", "mpp34", "mpp35"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +index da03a12..6dcdc50d 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +@@ -63,6 +63,12 @@ + pinctrl { + compatible = "marvell,mv78460-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins: sdio-pins { ++ marvell,pins = "mpp30", "mpp31", "mpp32", ++ "mpp33", "mpp34", "mpp35"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch b/target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch new file mode 100644 index 0000000000..f013ec0f11 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch @@ -0,0 +1,29 @@ +The Armada XP DB evaluation board has one SD card slot, directly +connected to the SDIO IP of the SoC, so we enable this +IP. Unfortunately, there are no GPIOs for card-detect and +write-protect. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-xp-db.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts +index 8e53b25..c7035c5 100644 +--- a/arch/arm/boot/dts/armada-xp-db.dts ++++ b/arch/arm/boot/dts/armada-xp-db.dts +@@ -90,5 +90,12 @@ + phy = <&phy3>; + phy-mode = "sgmii"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ /* No CD or WP GPIOs */ ++ }; + }; + }; +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch b/target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch new file mode 100644 index 0000000000..3759741dbe --- /dev/null +++ b/target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch @@ -0,0 +1,46 @@ +The Armada XP DB evaluation board has one SD card slot, directly +connected to the SDIO IP of the SoC, so we add a device tree +description for it. + +However, in the default configuration of the board, the SD card slot +is not usable: the connector plugged into CON40 must be changed +against a different one, provided with the board by the +manufacturer. Since such a manual modification of the hardware is +needed, we did not enable the SDIO interface by default, and left it +to the board user to modify the Device Tree if needed. Since this +board is really only an evaluation board for developers and not a +final product, it is not too bad. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- +[florian: changed status to "okay" for RD-A370-A1] + arch/arm/boot/dts/armada-370-db.dts | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts +index 0004402..43ff156 100644 +--- a/arch/arm/boot/dts/armada-370-db.dts ++++ b/arch/arm/boot/dts/armada-370-db.dts +@@ -59,5 +59,20 @@ + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins1>; ++ pinctrl-names = "default"; ++ /* ++ * This device is disabled by default, because ++ * using the SD card connector requires ++ * changing the default CON40 connector ++ * "DB-88F6710_MPP_2xRGMII_DEVICE_Jumper" to a ++ * different connector ++ * "DB-88F6710_MPP_RGMII_SD_Jumper". ++ */ ++ status = "okay"; ++ /* No CD or WP GPIOs */ ++ }; + }; + }; +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch b/target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch new file mode 100644 index 0000000000..3868d46d8d --- /dev/null +++ b/target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch @@ -0,0 +1,31 @@ +The Globalscale Mirabox uses the SDIO interface of the Armada 370 to +connect to a Wifi/Bluetooth SD8787 chip, so we enable the SDIO +interface of this board in its Device Tree file. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-mirabox.dts | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts +index 3b40713..1864820 100644 +--- a/arch/arm/boot/dts/armada-370-mirabox.dts ++++ b/arch/arm/boot/dts/armada-370-mirabox.dts +@@ -52,5 +52,15 @@ + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins2>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ /* ++ * No CD or WP GPIOs: SDIO interface used for ++ * Wifi/Bluetooth chip ++ */ ++ }; + }; + }; +-- +1.7.9.5 diff --git a/target/linux/mvebu/patches-3.8/016-arm_cache_l2x0_aurora_invalidate.patch b/target/linux/mvebu/patches-3.8/016-arm_cache_l2x0_aurora_invalidate.patch new file mode 100644 index 0000000000..7e7c5fda8b --- /dev/null +++ b/target/linux/mvebu/patches-3.8/016-arm_cache_l2x0_aurora_invalidate.patch @@ -0,0 +1,52 @@ +From e84ed03e1c5d45305fdd9b872e0b7be97bcfda16 Mon Sep 17 00:00:00 2001 +From: Gregory CLEMENT <gregory.clement@free-electrons.com> +Date: Thu, 13 Dec 2012 15:03:27 +0100 +Subject: [PATCH] arm: cache-l2x0: aurora: Invalidate during clean operation + with WT enable + +This patch fixes a bug for Aurora L2 cache controller when the +write-through mode is enable. For the clean operation even if we don't +have to flush the lines we still need to invalidate them. + +Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> +--- + arch/arm/mm/cache-l2x0.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c +index 6911b8b..7ffe943 100644 +--- a/arch/arm/mm/cache-l2x0.c ++++ b/arch/arm/mm/cache-l2x0.c +@@ -505,15 +505,21 @@ static void aurora_clean_range(unsigned long start, unsigned long end) + + static void aurora_flush_range(unsigned long start, unsigned long end) + { +- if (!l2_wt_override) { +- start &= ~(CACHE_LINE_SIZE - 1); +- end = ALIGN(end, CACHE_LINE_SIZE); +- while (start != end) { +- unsigned long range_end = calc_range_end(start, end); ++ start &= ~(CACHE_LINE_SIZE - 1); ++ end = ALIGN(end, CACHE_LINE_SIZE); ++ while (start != end) { ++ unsigned long range_end = calc_range_end(start, end); ++ /* ++ * If L2 is forced to WT, the L2 will always be clean and we ++ * just need to invalidate. ++ */ ++ if (l2_wt_override) + aurora_pa_range(start, range_end - CACHE_LINE_SIZE, +- AURORA_FLUSH_RANGE_REG); +- start = range_end; +- } ++ AURORA_INVAL_RANGE_REG); ++ else ++ aurora_pa_range(start, range_end - CACHE_LINE_SIZE, ++ AURORA_FLUSH_RANGE_REG); ++ start = range_end; + } + } + +-- +1.7.10.4 + diff --git a/target/linux/mvebu/patches-3.8/017-arm_cache_l2x0_aurora_use_writel_relaxed.patch b/target/linux/mvebu/patches-3.8/017-arm_cache_l2x0_aurora_use_writel_relaxed.patch new file mode 100644 index 0000000000..5f5ba11d79 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/017-arm_cache_l2x0_aurora_use_writel_relaxed.patch @@ -0,0 +1,45 @@ +From 6c8928f877a1572f16cfc8a0c055d7e16320c741 Mon Sep 17 00:00:00 2001 +From: Gregory CLEMENT <gregory.clement@free-electrons.com> +Date: Thu, 13 Dec 2012 18:33:06 +0100 +Subject: [PATCH] arm: cache-l2x0: aurora: Use writel_relaxed instead of + writel + +The use of writel instead of writel_relaxed lead to deadlock in some +situation (SMP on Armada 370 for instance). The use of writel_relaxed +as it was done in the rest of this driver fixes this bug. + +Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> +--- + arch/arm/mm/cache-l2x0.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c +index 7ffe943..96a1ae4 100644 +--- a/arch/arm/mm/cache-l2x0.c ++++ b/arch/arm/mm/cache-l2x0.c +@@ -459,8 +459,8 @@ static void aurora_pa_range(unsigned long start, unsigned long end, + unsigned long flags; + + raw_spin_lock_irqsave(&l2x0_lock, flags); +- writel(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG); +- writel(end, l2x0_base + offset); ++ writel_relaxed(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG); ++ writel_relaxed(end, l2x0_base + offset); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); + + cache_sync(); +@@ -674,8 +674,9 @@ static void pl310_resume(void) + static void aurora_resume(void) + { + if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { +- writel(l2x0_saved_regs.aux_ctrl, l2x0_base + L2X0_AUX_CTRL); +- writel(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL); ++ writel_relaxed(l2x0_saved_regs.aux_ctrl, ++ l2x0_base + L2X0_AUX_CTRL); ++ writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL); + } + } + +-- +1.7.10.4 + diff --git a/target/linux/mvebu/patches-3.8/018-arm_mvebu_dw_apb_uart.patch b/target/linux/mvebu/patches-3.8/018-arm_mvebu_dw_apb_uart.patch new file mode 100644 index 0000000000..29c199cad4 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/018-arm_mvebu_dw_apb_uart.patch @@ -0,0 +1,88 @@ +From 3487b074a742bc3300683e91e3ade383b659fbe9 Mon Sep 17 00:00:00 2001 +From: Gregory CLEMENT <gregory.clement@free-electrons.com> +Date: Tue, 4 Dec 2012 18:04:59 +0100 +Subject: [PATCH] arm: mvebu: Use dw-apb-uart instead of ns16650 as UART + driver + +The UART controller used in the Armada 370 and Armada XP SoCs is the +Synopsys DesignWare 8250 (aka Synopsys DesignWare ABP UART). The +improper use of the ns16550 can lead to a kernel oops during boot if +a character is sent to the UART before the initialization of the +driver. The DW APB has an extra interrupt that gets raised when +writing to the LCR when busy. This explains why we need to use +dw-apb-uart driver to handle this. + +Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-xp.dtsi | 6 ++++-- + arch/arm/boot/dts/armada-xp.dtsi | 6 ++++-- + arch/arm/configs/mvebu_defconfig | 1 + + 3 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi +index cf6c48a..4c0abe8 100644 +--- a/arch/arm/boot/dts/armada-370-xp.dtsi ++++ b/arch/arm/boot/dts/armada-370-xp.dtsi +@@ -50,17 +50,19 @@ + ranges; + + serial@d0012000 { +- compatible = "ns16550"; ++ compatible = "snps,dw-apb-uart"; + reg = <0xd0012000 0x100>; + reg-shift = <2>; + interrupts = <41>; ++ reg-io-width = <4>; + status = "disabled"; + }; + serial@d0012100 { +- compatible = "ns16550"; ++ compatible = "snps,dw-apb-uart"; + reg = <0xd0012100 0x100>; + reg-shift = <2>; + interrupts = <42>; ++ reg-io-width = <4>; + status = "disabled"; + }; + +diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi +index 367aa3f..8a85ffe 100644 +--- a/arch/arm/boot/dts/armada-xp.dtsi ++++ b/arch/arm/boot/dts/armada-xp.dtsi +@@ -42,17 +42,19 @@ + + soc { + serial@d0012200 { +- compatible = "ns16550"; ++ compatible = "snps,dw-apb-uart"; + reg = <0xd0012200 0x100>; + reg-shift = <2>; + interrupts = <43>; ++ reg-io-width = <4>; + status = "disabled"; + }; + serial@d0012300 { +- compatible = "ns16550"; ++ compatible = "snps,dw-apb-uart"; + reg = <0xd0012300 0x100>; + reg-shift = <2>; + interrupts = <44>; ++ reg-io-width = <4>; + status = "disabled"; + }; + +diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig +index a702fb3..3ba35f1 100644 +--- a/arch/arm/configs/mvebu_defconfig ++++ b/arch/arm/configs/mvebu_defconfig +@@ -34,6 +34,7 @@ CONFIG_MARVELL_PHY=y + CONFIG_SERIAL_8250=y + CONFIG_SERIAL_8250_CONSOLE=y + CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_8250_DW=y + CONFIG_I2C=y + CONFIG_I2C_MV64XXX=y + CONFIG_GPIOLIB=y +-- +1.7.10.4 + |