* [PATCH V2] ARM: mx28: Skip OCOTP FEC MAC setup if in DT
From: Shawn Guo @ 2012-10-30 11:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201210301146.34506.marex@denx.de>
On Tue, Oct 30, 2012 at 11:46:34AM +0100, Marek Vasut wrote:
> Dear Shawn Guo,
>
> > On Fri, Oct 26, 2012 at 12:01:58PM +0200, Marek Vasut wrote:
> > > Can we apply this for 3.7?
> >
> > You meant for 3.8?
>
> 3.7 would be nice, but it's too late now.
>
Applied for 3.8.
^ permalink raw reply
* [PATCH 2/2] ARM: OMAP: omap_device: Correct resource handling for DT boot
From: Péter Ujfalusi @ 2012-10-30 11:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351593205-13590-3-git-send-email-peter.ujfalusi@ti.com>
On 10/30/2012 11:33 AM, Peter Ujfalusi wrote:
> When booting with DT the OF core can fill up the resources provided within
> the DT blob.
> The current way of handling the DT boot prevents us from removing hwmod data
> for platforms only suppose to boot with DT (OMAP5 for example) since we need
> to keep the whole hwmod database intact in order to have more resources in
> hwmod than in DT (to be able to append the DMA resource from hwmod).
>
> To fix this issue we just examine the OF provided resources:
> If we do not have resources we use hwmod to fill them.
> If we have resources we check if we already able to recive DMA resource, if
> no we only append the DMA resurce from hwmod to the OF provided ones.
>
> In this way we can start removing hwmod data for devices which have their
> resources correctly configured in DT without regressions.
>
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
> arch/arm/plat-omap/omap_device.c | 80 +++++++++++++++++++++++-----------------
> 1 file changed, 47 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index 915cf68..a8a9d08 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -560,55 +560,69 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
> od->hwmods = hwmods;
> od->pdev = pdev;
>
> - /* Count all resources for the device */
> - res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
> - IORESOURCE_DMA |
> - IORESOURCE_MEM);
> /*
> + * Non-DT Boot:
> + * Here, pdev->num_resources = 0, and we should get all the
> + * resources from hwmod.
> + *
> * DT Boot:
> * OF framework will construct the resource structure (currently
> * does for MEM & IRQ resource) and we should respect/use these
> * resources, killing hwmod dependency.
> * If pdev->num_resources > 0, we assume that MEM & IRQ resources
> * have been allocated by OF layer already (through DTB).
> - *
> - * Non-DT Boot:
> - * Here, pdev->num_resources = 0, and we should get all the
> - * resources from hwmod.
> + * As preparation for the future we examine the OF provided resources
> + * to see if we have DMA resources provided already. In this case
> + * there is no need to update the resources for the device, we use the
> + * OF provided ones.
> *
> * TODO: Once DMA resource is available from OF layer, we should
> * kill filling any resources from hwmod.
> */
> - if (res_count > pdev->num_resources) {
> - /* Allocate resources memory to account for new resources */
> - res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
> - if (!res)
> - goto oda_exit3;
> -
> - /*
> - * If pdev->num_resources > 0, then assume that,
> - * MEM and IRQ resources will only come from DT and only
> - * fill DMA resource from hwmod layer.
> - */
> - if (pdev->num_resources && pdev->resource) {
> - dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n",
> - __func__, res_count);
> - memcpy(res, pdev->resource,
> - sizeof(struct resource) * pdev->num_resources);
> - _od_fill_dma_resources(od, &res[pdev->num_resources]);
> - } else {
> - dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
> - __func__, res_count);
> - omap_device_fill_resources(od, res);
> + if (!pdev->num_resources) {
> + /* Count all resources for the device */
> + res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
> + IORESOURCE_DMA |
> + IORESOURCE_MEM);
> + } else {
> + /* Take a look if we already have DMA resource via DT */
> + for (i = 0; i < pdev->num_resources; i++) {
> + struct resource *r = &pdev->resource[i];
> +
> + /* We have it, no need to touch the resources */
> + if (r->flags == IORESOURCE_DMA)
> + goto have_everything;
> }
> + /* Count only DMA resources for the device */
> + res_count = omap_device_count_resources(od, IORESOURCE_DMA);
We have devices without DMA channel so we can skip the resource recreation for
them.
I'll resend the series with this update.
> + res_count += pdev->num_resources;
> + }
>
> - ret = platform_device_add_resources(pdev, res, res_count);
> - kfree(res);
> + /* Allocate resources memory to account for new resources */
> + res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
> + if (!res)
> + goto oda_exit3;
>
> - if (ret)
> - goto oda_exit3;
> + if (!pdev->num_resources) {
> + dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
> + __func__, res_count);
> + omap_device_fill_resources(od, res);
> + } else {
> + dev_dbg(&pdev->dev,
> + "%s: appending %d DMA resources from hwmod\n",
> + __func__, res_count - pdev->num_resources);
> + memcpy(res, pdev->resource,
> + sizeof(struct resource) * pdev->num_resources);
> + _od_fill_dma_resources(od, &res[pdev->num_resources]);
> }
>
> + ret = platform_device_add_resources(pdev, res, res_count);
> + kfree(res);
> +
> + if (ret)
> + goto oda_exit3;
> +
> +have_everything:
> if (!pm_lats) {
> pm_lats = omap_default_latency;
> pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
>
--
P?ter
^ permalink raw reply
* [PATCH V2 1/3] clk: mvebu: add armada-370-xp specific clocks
From: Mike Turquette @ 2012-10-30 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349125926-16144-2-git-send-email-gregory.clement@free-electrons.com>
Quoting Gregory CLEMENT (2012-10-01 14:12:04)
> Add Armada 370/XP specific clocks: core clocks and CPU clocks.
>
> The CPU clocks are only for Armada XP for the SMP mode.
>
> The core clocks are clocks which have their rate set during reset. The
> code was written with the other SoCs of the mvebu family in
> mind. Adding them should be pretty straight forward. For a new
> SoC, only 3 binding have to be added:
> - one to provide the tclk frequency
> - one to provde the pclk frequency
> - and one to provide the ratio between the pclk and the children
> clocks
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Thanks for sending v2 Gregory. Functionally this series looks good but
unfortunately there are a few style and white space nitpicks below.
> diff --git a/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
> new file mode 100644
> index 0000000..c524618
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
> @@ -0,0 +1,21 @@
> +Device Tree Clock bindings for cpu clock of Marvell EBU platforms
> +
> +Required properties:
> +- compatible : shall be one of the following:
> + "marvell,armada-xp-cpu-clockctrl" - cpu clocks for Armada XP
> +- reg : Address and length of the clock complex register set
> +- #clock-cells : should be set to 1.
> +- clocks : shall be the input parent clock phandle for the clock.
> +
> +cpuclk: clock-complex at d0018700 {
> + #clock-cells = <1>;
> + compatible = "marvell,armada-xp-cpu-clockctrl";
> + reg = <0xd0018700 0xA0>;
> + clocks = <&coreclk 1>;
> +}
> +
> +cpu at 0 {
> + compatible = "marvell,sheeva-v7";
Unnecessary white space before the tab in the line above.
> diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c
> new file mode 100644
> index 0000000..5792cb5
> --- /dev/null
> +++ b/drivers/clk/mvebu/clk-core.c
> @@ -0,0 +1,312 @@
> +/*
> + * Marvell EBU clock core handling defined at reset
> + *
> + * Copyright (C) 2012 Marvell
> + *
> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +#include <linux/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of_address.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +
> +/* Sample At Reset is a 64 bit bitfiled split in two register of 32
> + * bits*/
Can you make this proper comment block style per CodingStyle convention?
> +
> +#define SARL 0 /* Low part [0:31] */
> +#define SARL_AXP_PCLK_FREQ_OPT 21
> +#define SARL_AXP_PCLK_FREQ_OPT_MASK 0x7
> +#define SARL_A370_PCLK_FREQ_OPT 11
> +#define SARL_A370_PCLK_FREQ_OPT_MASK 0xF
> +#define SARL_AXP_FAB_FREQ_OPT 24
> +#define SARL_AXP_FAB_FREQ_OPT_MASK 0xF
> +#define SARL_A370_FAB_FREQ_OPT 15
> +#define SARL_A370_FAB_FREQ_OPT_MASK 0x1F
> +#define SARL_A370_TCLK_FREQ_OPT 20
> +#define SARL_A370_TCLK_FREQ_OPT_MASK 0x1
> +#define SARH 4 /* High part [32:63] */
> +#define SARH_AXP_PCLK_FREQ_OPT (52-32)
> +#define SARH_AXP_PCLK_FREQ_OPT_MASK 0x1
> +#define SARH_AXP_PCLK_FREQ_OPT_SHIFT 3
> +#define SARH_AXP_FAB_FREQ_OPT (51-32)
> +#define SARH_AXP_FAB_FREQ_OPT_MASK 0x1
> +#define SARH_AXP_FAB_FREQ_OPT_SHIFT 4
> +
> +u32 *sar_reg;
> +int sar_reg_size;
> +
> +enum core_clk {
> + tclk, pclk, nbclk, hclk, dramclk, clk_max
> +};
> +
> +struct core_clk_fn {
> + u32(*get_tclk_freq) (void);
> + u32(*get_pck_freq) (void);
> + const int *(*get_fab_freq_opt) (void);
> +};
> +
> +/* Ratio between VCO and each of the member in the following order:
> + CPU clock, L2 clock, DRAM controler clock, DDR clcok */
ditto
> +static const int reset_core_ratio[32][4] = {
> + [0x01] = {1, 2, 2, 2},
> + [0x02] = {2, 2, 6, 3},
> + [0x03] = {2, 2, 3, 3},
> + [0x04] = {1, 2, 3, 3},
> + [0x05] = {1, 2, 4, 2},
> + [0x06] = {1, 1, 2, 2},
> + [0x07] = {2, 3, 6, 6},
> + [0x09] = {1, 2, 6, 3},
> + [0x0A] = {2, 4, 10, 5},
> + [0x0C] = {1, 2, 4, 4},
> + [0x0F] = {2, 2, 5, 5},
> + [0x13] = {1, 1, 2, 1},
> + [0x14] = {2, 3, 6, 3},
> + [0x1B] = {1, 1, 1, 1},
> +};
> +
> +static struct clk *clks[clk_max];
> +
> +static struct clk_onecell_data clk_data;
> +
> +/* Frequency in MHz*/
> +static u32 armada_370_pclk[] = { 400, 533, 667, 800, 1000, 1067, 1200 };
> +
> +static u32 armada_xp_pclk[] = { 1000, 1066, 1200, 1333, 1500, 1666,
> + 1800, 2000, 667, 0, 800, 1600
> +};
> +
> +static u32 armada_370_tclk[] = { 166, 200 };
> +
> +static const int *__init armada_370_get_fab_freq_opt(void)
> +{
> + u8 fab_freq_opt = 0;
> +
> + fab_freq_opt = ((sar_reg[0] >> SARL_A370_FAB_FREQ_OPT) &
> + SARL_A370_FAB_FREQ_OPT_MASK);
> +
> + if (reset_core_ratio[fab_freq_opt][0] == 0)
> + return NULL;
> + else
> + return reset_core_ratio[fab_freq_opt];
> +}
> +
> +static u32 __init armada_370_get_pck_freq(void)
> +{
> + u32 cpu_freq;
> + u8 cpu_freq_select = 0;
> +
> + cpu_freq_select = ((sar_reg[0] >> SARL_A370_PCLK_FREQ_OPT) &
> + SARL_A370_PCLK_FREQ_OPT_MASK);
> + if (cpu_freq_select > ARRAY_SIZE(armada_370_pclk)) {
> + pr_err("CPU freq select unsuported %d\n", cpu_freq_select);
> + cpu_freq = 0;
> + } else
> + cpu_freq = armada_370_pclk[cpu_freq_select];
> +
> + return cpu_freq * 1000 * 1000;
> +}
> +
> +static u32 __init armada_370_get_tclk_freq(void)
> +{
> + u32 tclk_freq;
> + u8 tclk_freq_select = 0;
> +
> + tclk_freq_select = ((sar_reg[0] >> SARL_A370_TCLK_FREQ_OPT) &
> + SARL_A370_TCLK_FREQ_OPT_MASK);
> + if (tclk_freq_select > ARRAY_SIZE(armada_370_tclk)) {
> + pr_err("TCLK freq select unsuported %d\n", tclk_freq_select);
> + tclk_freq = 0;
> + } else
> + tclk_freq = armada_370_tclk[tclk_freq_select];
> +
> + return tclk_freq * 1000 * 1000;
> +}
> +
> +static const int *__init armada_xp_get_fab_freq_opt(void)
> +{
> + u8 fab_freq_opt = 0;
> +
> + fab_freq_opt = ((sar_reg[0] >> SARL_AXP_FAB_FREQ_OPT) &
> + SARL_AXP_FAB_FREQ_OPT_MASK);
> + /* The upper bit is not contiguous to the other ones
> + * and located in the high part of the SAR
> + * registers */
ditto
> + fab_freq_opt |= (((sar_reg[1] >> SARH_AXP_FAB_FREQ_OPT) &
> + SARH_AXP_FAB_FREQ_OPT_MASK)
> + << SARH_AXP_FAB_FREQ_OPT_SHIFT);
> +
> + if (reset_core_ratio[fab_freq_opt][0] == 0)
> + return NULL;
> + else
> + return reset_core_ratio[fab_freq_opt];
> +}
> +
> +static u32 __init armada_xp_get_pck_freq(void)
> +{
> + u32 cpu_freq;
> + u8 cpu_freq_select = 0;
> +
> + cpu_freq_select = ((sar_reg[0] >> SARL_AXP_PCLK_FREQ_OPT) &
> + SARL_AXP_PCLK_FREQ_OPT_MASK);
> + /* The upper bit is not contiguous to the other ones
> + * and located in the high part of the SAR
> + * registers */
ditto
> + cpu_freq_select |= (((sar_reg[1] >> SARH_AXP_PCLK_FREQ_OPT) &
> + SARH_AXP_PCLK_FREQ_OPT_MASK)
> + << SARH_AXP_PCLK_FREQ_OPT_SHIFT);
> + if (cpu_freq_select > ARRAY_SIZE(armada_xp_pclk)) {
> + pr_err("CPU freq select unsuported: %d\n", cpu_freq_select);
> + cpu_freq = 0;
> + } else
> + cpu_freq = armada_xp_pclk[cpu_freq_select];
> +
> + return cpu_freq * 1000 * 1000;
> +}
> +
> +/* For Armada XP TCLK frequency is fix: 250MHz */
> +static u32 __init armada_xp_get_tclk_freq(void)
> +{
> + return 250 * 1000 * 1000;
> +}
> +
> +void __init of_core_clk_setup(struct device_node *node,
> + struct core_clk_fn clk_fn)
> +{
> + struct clk *clk;
> + unsigned long rate;
> + const char *clk_name;
> + int i;
> +
> + /* clock 0 is tclk */
> + of_property_read_string_index(node, "clock-output-names", tclk,
> + &clk_name);
> + rate = clk_fn.get_tclk_freq();
> + if (rate != 0)
> + clk = clk_register_fixed_rate(NULL, clk_name, NULL,
> + CLK_IS_ROOT, rate);
> + else {
> + pr_err("Invalid freq for %s\n", clk_name);
> + return;
> + }
> +
> + if (WARN_ON(IS_ERR(clk)))
> + return;
> + clks[tclk] = clk;
> +
> + /* clock 1 is pclk */
> + of_property_read_string_index(node, "clock-output-names", pclk,
> + &clk_name);
> + rate = clk_fn.get_pck_freq();
> + if (rate != 0)
> + clk = clk_register_fixed_rate(NULL, clk_name, NULL,
> + CLK_IS_ROOT, rate);
> + else {
> + pr_err("Invalid freq for %s\n", clk_name);
> + return;
> + }
> + if (WARN_ON(IS_ERR(clk)))
> + return;
> + clks[pclk] = clk;
> +
> + /* the clocks 2 to 4 are nbclk, hclk and dramclk and are all
> + * derivated from the clock 1: pclk */
ditto
> +
> + for (i = nbclk; i <= dramclk; i++) {
> + const int *ratio = clk_fn.get_fab_freq_opt();
> + const char *parent_clk_name;
> +
> + of_property_read_string_index(node, "clock-output-names",
> + i, &clk_name);
> + of_property_read_string_index(node, "clock-output-names",
> + pclk, &parent_clk_name);
> +
> + if (ratio != NULL)
> + clk = clk_register_fixed_factor(NULL, clk_name,
> + parent_clk_name, 0,
> + ratio[0],
> + ratio[i - nbclk + 1]);
> + else {
> + pr_err("Invalid clk ratio for %s\n", clk_name);
> + return;
> + }
> +
> + if (WARN_ON(IS_ERR(clk)))
> + return;
> + clks[i] = clk;
> + }
> + clk_data.clk_num = ARRAY_SIZE(clks);
> + clk_data.clks = clks;
> + of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
> +}
> +
> +static struct core_clk_fn armada_370_clk_fn = {
> + .get_tclk_freq = armada_370_get_tclk_freq,
> + .get_pck_freq = armada_370_get_pck_freq,
> + .get_fab_freq_opt = armada_370_get_fab_freq_opt,
> +};
> +
> +static struct core_clk_fn armada_xp_clk_fn = {
> + .get_tclk_freq = armada_xp_get_tclk_freq,
> + .get_pck_freq = armada_xp_get_pck_freq,
> + .get_fab_freq_opt = armada_xp_get_fab_freq_opt,
> +};
> +
> +static const __initconst struct of_device_id clk_match[] = {
> + {
> + .compatible = "marvell,armada-370-core-clockctrl",
> + .data = &armada_370_clk_fn,
> + },
Indention is a bit weird here. The members are just indented with one
space and there is an extra white space in front of the closing bracket.
Can you re-align?
> +
> + {
> + .compatible = "marvell,armada-xp-core-clockctrl",
> + .data = &armada_xp_clk_fn,
> + },
ditto
> + {
> + /* sentinel */
> + }
ditto
> +};
> +
> +void __init mvebu_core_clocks_init(void)
> +{
> + struct device_node *np;
> + struct resource res;
> + void __iomem *sar_base;
> + int i;
> +
> + np = of_find_node_by_name(NULL, "mvebu-sar");
> +
> + if (!np)
> + goto err;
> +
> + if (of_address_to_resource(np, 0, &res))
> + goto err;
> +
> + sar_reg_size = resource_size(&res);
> + sar_reg = kmalloc(sar_reg_size, GFP_KERNEL);
> +
> + sar_base = ioremap(res.start, sar_reg_size);
> + if (sar_base == NULL)
> + goto err;
> + for (i = 0; i < sar_reg_size; i += sizeof(*sar_reg))
> + sar_reg[i] = readl(sar_base + i);
> +
> + iounmap(sar_base);
> +
> + for_each_matching_node(np, clk_match) {
> + const struct of_device_id *match = of_match_node(clk_match, np);
> + struct core_clk_fn *clk_fn = match->data;
> + of_core_clk_setup(np, *clk_fn);
> + }
> +
> + return;
> +err:
> + pr_err("%s:SAR base adresse not set in DT\n", __func__);
> + return;
> +}
> diff --git a/drivers/clk/mvebu/clk-core.h b/drivers/clk/mvebu/clk-core.h
> new file mode 100644
> index 0000000..a04f80b
> --- /dev/null
> +++ b/drivers/clk/mvebu/clk-core.h
> @@ -0,0 +1,19 @@
> +/*
> + * * Marvell EBU clock core handling defined at reset
> + *
> + * Copyright (C) 2012 Marvell
> + *
> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#ifndef __MVEBU_CLK_CORE_H
> +#define __MVEBU_CLK_CORE_H
> +
> +void __init of_core_clk_setup(struct device_node *node);
> +void __init mvebu_core_clocks_init(void);
> +
> +#endif
> diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
> new file mode 100644
> index 0000000..6b5c841
> --- /dev/null
> +++ b/drivers/clk/mvebu/clk-cpu.c
> @@ -0,0 +1,155 @@
> +/*
> + * Marvell MVEBU CPU clock handling.
> + *
> + * Copyright (C) 2012 Marvell
> + *
> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +#include <linux/kernel.h>
> +#include <linux/clk.h>
clk-provider.h includes clk.h, so this is redundant.
Regards,
Mike
^ permalink raw reply
* [PATCH v3 06/10] net/macb: clean up ring buffer logic
From: David Laight @ 2012-10-30 11:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <75eb5df193c504e68ebff7d6a6a88d9a1cc678cb.1351591858.git.nicolas.ferre@atmel.com>
> Instead of masking head and tail every time we increment them, just let them
> wrap through UINT_MAX and mask them when subscripting. Add simple accessor
> functions to do the subscripting properly to minimize the chances of messing
> this up.
...
> +static unsigned int macb_tx_ring_avail(struct macb *bp)
> +{
> + return TX_RING_SIZE - (bp->tx_head - bp->tx_tail);
> +}
That one doesn't look quite right to me.
Surely it should be masking with 'TX_RING_SIZE - 1'
David
^ permalink raw reply
* ARM: Add PI/robust mutexes support for SMP kernels
From: ashish yadav @ 2012-10-30 11:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJKbuCZT+5nkXWXEA7h54Rw2Ss94Co=q9YU3PT+WcNmn-QGC1g@mail.gmail.com>
Hi ,
This is for information that , I am using 2.6.35.14 Kernel Version.
Thanks & Regards
Ashish
On Tue, Oct 30, 2012 at 4:34 PM, ashish yadav <ashishyadav78@gmail.com>wrote:
> Hi ,
>
> I am using patch "ARM: Add PI/robust mutexes support for SMP kernels"
> for Arm Cortex-A9 from :
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-June/017374.html
>
> But still I can see mutex multiple lock/unlock error with PI mutex in my
> application.
>
> Seeing the mailing chain of this patch , its seems that this patch is not
> complete.
>
> Could any one please update full patch for same.
>
> Thanks & Regards
> Ashish
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121030/669e7149/attachment.html>
^ permalink raw reply
* ARM: Add PI/robust mutexes support for SMP kernels
From: ashish yadav @ 2012-10-30 11:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi ,
I am using patch "ARM: Add PI/robust mutexes support for SMP kernels" for
Arm Cortex-A9 from :
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-June/017374.html
But still I can see mutex multiple lock/unlock error with PI mutex in my
application.
Seeing the mailing chain of this patch , its seems that this patch is not
complete.
Could any one please update full patch for same.
Thanks & Regards
Ashish
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121030/e2e46e90/attachment.html>
^ permalink raw reply
* OMAP baseline test results for v3.7-rc3
From: Mark Jackson @ 2012-10-30 10:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1210300229590.12697@utopia.booyaka.com>
On 30/10/12 02:36, Paul Walmsley wrote:
>
> Here are some basic OMAP test results for Linux v3.7-rc3.
> Logs and other details at:
>
> http://www.pwsan.com/omap/testlogs/test_v3.7-rc3/20121028162003/
>
>
> Passing tests
> -------------
>
> Boot to userspace: 2420n800, 3517evm, 3530es3beagle, 3730beaglexm, 37xxevm,
> 4430es2panda, 5912osk, am335xbone
>
> PM ret/off, suspend + dynamic idle: (none)
>
>
> Failing tests: fixed by posted patches
> --------------------------------------
>
> Boot tests:
>
> * 2430sdp: vfp_reload_hw oops during MMC initialization
> - Kernel attempts to save FP registers that don't exist; fix posted:
> - http://www.spinics.net/lists/arm-kernel/msg200646.html
> - added to rmk's patch system as 7566/1
>
> * AM335x Beaglebone: omap2plus_defconfig kernels don't boot
> - Due to GPMC missing support for DT
> - Temporary workaround at http://www.spinics.net/lists/arm-kernel/msg200787.html
> - May be fixed now, pending retest:
> - http://marc.info/?l=linux-omap&m=135082257727502&w=2
At what point is booting from MMC on the BeagleBone going to start working ?
I only ask, since, by default, a new BeagleBone is setup to boot from MMC, so anyone testing a new
kernel will probably expect the same setup to work.
Cheers
Mark JACKSON
^ permalink raw reply
* Representation of external memory-mapped devices in DT (gpmc)
From: Afzal Mohammed @ 2012-10-30 10:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <508EBB47.8070405@gmail.com>
Hi Daniel,
On Monday 29 October 2012 10:52 PM, Daniel Mack wrote:
> On 29.10.2012 16:09, Rob Herring wrote:
>> You may want a CS0 node with nand as a child node of that.
> Hmm, I don't see what that would buy us. The question is which way is
> feasible for storing both the memory region and the cs number in the
> device tree. The CS number should certainly go to the child node, no?
>
> IOW, would it be a good idea to have something like the following layout?
>
> gpmc: gpmc at 50000000 {
> compatible = "ti,gpmc";
> ti,hwmods = "gpmc";
> reg =<0x50000000 0x2000>;
>
> /* cs-reg stores the setup of the controller's
> memory map */
>
> /* offset size */
> cs-reg =<0x0 0x1000000
> .... .....
> .... .....>;
>
> nand: child at 0 {
> /* timings */
> /* peripheral specifics */
> };
> };
>
> I would actually much prefer that approach.
>
> Afzal, because because that way, we can leave the code as-is for now and
> add the "cs-reg" property once the code is switched to dynamic handling.
> What do you think?
I don't know what to say, don't have a good grasp on DT to give
right suggestion.
It seems offset field may not be necessary. memory for connected
peripherals is not fixed, only CS is fixed (as CS pin is hard-wired).
Physical memory can be anywhere between 0-512MB (with
alignment constraints depending on size, refer GPMC_CONFIG7
register), even though right now memory region for peripheral
seems to be fixed (for boards supported in mainline it will be
what bootloader configures), it is possible to have it in a different
region for those peripherals.
And this memory should be presented to child device as resource,
say for smsc911x ethernet driver.
I see some similarity with PCI - BAR's, where address space
is configured (here a difference would be that size needs to
be known while configuring). Size here would be based on
connected peripheral (but no auto detection)
Regards
Afzal
^ permalink raw reply
* [PATCH 1/3] ARM: mvebu: Add support I2C controller
From: Thomas Petazzoni @ 2012-10-30 10:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351593685-19663-1-git-send-email-iwamatsu@nigauri.org>
Dear Nobuhiro Iwamatsu,
On Tue, 30 Oct 2012 19:41:23 +0900, Nobuhiro Iwamatsu wrote:
> The mvebu arch has the same I2C controller as mv64xxx-i2c.
> This support mv64xxx-i2c on mvebu.
>
> Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Thanks, looks good to me, but we have to wait for the Armada 370/XP
clock patch set to get merged before merging this.
I'll give it a test on the OpenBlocks hardware and report.
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 1/1] net: macb: add pinctrl consumer support
From: Nicolas Ferre @ 2012-10-30 10:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351352997-31116-1-git-send-email-plagnioj@jcrosoft.com>
On 10/27/2012 05:49 PM, Jean-Christophe PLAGNIOL-VILLARD :
> If no pinctrl available just report a warning as some architecture may not
> need to do anything.
>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> Cc: netdev at vger.kernel.org
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> ---
> drivers/net/ethernet/cadence/macb.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
> index 033064b..e5fdf8a 100644
> --- a/drivers/net/ethernet/cadence/macb.c
> +++ b/drivers/net/ethernet/cadence/macb.c
> @@ -26,6 +26,9 @@
> #include <linux/of.h>
> #include <linux/of_device.h>
> #include <linux/of_net.h>
> +#include <linux/of_gpio.h>
> +#include <linux/gpio.h>
> +#include <linux/pinctrl/consumer.h>
>
> #include "macb.h"
>
> @@ -1306,6 +1309,7 @@ static int __init macb_probe(struct platform_device *pdev)
> struct phy_device *phydev;
> u32 config;
> int err = -ENXIO;
> + struct pinctrl *pinctrl;
>
> regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!regs) {
> @@ -1313,6 +1317,15 @@ static int __init macb_probe(struct platform_device *pdev)
> goto err_out;
> }
>
> + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
> + if (IS_ERR(pinctrl)) {
> + err = PTR_ERR(pinctrl);
> + if (err == -EPROBE_DEFER)
> + return err;
I will modify this to be consistent with error path before and after
this change => goto err_out.
Do not bother to re-submit a patch, I will include this one in my
upcoming patch series.
Thanks,
> +
> + dev_warn(&pdev->dev, "No pinctrl provided\n");
> + }
> +
> err = -ENOMEM;
> dev = alloc_etherdev(sizeof(*bp));
> if (!dev)
>
--
Nicolas Ferre
^ permalink raw reply
* [PATCH V2] ARM: mx28: Skip OCOTP FEC MAC setup if in DT
From: Marek Vasut @ 2012-10-30 10:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121030013111.GD9921@S2101-09.ap.freescale.net>
Dear Shawn Guo,
> On Fri, Oct 26, 2012 at 12:01:58PM +0200, Marek Vasut wrote:
> > Can we apply this for 3.7?
>
> You meant for 3.8?
3.7 would be nice, but it's too late now.
Best regards,
Marek Vasut
^ permalink raw reply
* [PATCH] i2c: mv64xxx: Add support Armada-XP SoC
From: Thomas Petazzoni @ 2012-10-30 10:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351593581-19555-1-git-send-email-iwamatsu@nigauri.org>
Dear Nobuhiro Iwamatsu,
On Tue, 30 Oct 2012 19:39:41 +0900, Nobuhiro Iwamatsu wrote:
> The Armada-XP SoC has the same I2C controller as mv64xxxi-i2c.
> This validates to use mv64xxx in this SoC.
>
> Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
> ---
> drivers/i2c/busses/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> index 65dd599..ff53cf4 100644
> --- a/drivers/i2c/busses/Kconfig
> +++ b/drivers/i2c/busses/Kconfig
> @@ -474,7 +474,7 @@ config I2C_MPC
>
> config I2C_MV64XXX
> tristate "Marvell mv64xxx I2C Controller"
> - depends on (MV64X60 || PLAT_ORION)
> + depends on (MV64X60 || PLAT_ORION || MACH_ARMADA_370_XP)
> help
> If you say yes to this option, support will be included for the
> built-in I2C interface on the Marvell 64xxx line of host bridges.
This is not needed: ARCH_MVEBU already selects PLAT_ORION.
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 3/3] ARM: mvebu: Add support RTC for OpenBlockS AX3
From: Nobuhiro Iwamatsu @ 2012-10-30 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351593685-19663-1-git-send-email-iwamatsu@nigauri.org>
From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
OpenBlockS AX3 has Seiko Instruments S-35390A as RTC controller.
This validates RTC controller.
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
---
arch/arm/boot/dts/openblocks-ax3-4.dts | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/openblocks-ax3-4.dts b/arch/arm/boot/dts/openblocks-ax3-4.dts
index c42b9a5..61c2f2c 100644
--- a/arch/arm/boot/dts/openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/openblocks-ax3-4.dts
@@ -74,6 +74,11 @@
i2c at d0011100 {
status = "okay";
clock-frequency = <400000>;
+
+ s35390a: s35390a at 30 {
+ compatible = "s35390a";
+ reg = <0x30>;
+ };
};
};
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/3] ARM: mvebu: Add support I2C for OpenBlockS AX3
From: Nobuhiro Iwamatsu @ 2012-10-30 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351593685-19663-1-git-send-email-iwamatsu@nigauri.org>
OpenBlockS AX3 uses the I2C controller on the mvebu.
This validates I2C controller and clock-frequency.
Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
---
arch/arm/boot/dts/openblocks-ax3-4.dts | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm/boot/dts/openblocks-ax3-4.dts b/arch/arm/boot/dts/openblocks-ax3-4.dts
index 7ef8052..c42b9a5 100644
--- a/arch/arm/boot/dts/openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/openblocks-ax3-4.dts
@@ -65,5 +65,15 @@
linux,default-trigger = "heartbeat";
};
};
+
+ i2c at d0011000 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+
+ i2c at d0011100 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
};
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/3] ARM: mvebu: Add support I2C controller
From: Nobuhiro Iwamatsu @ 2012-10-30 10:41 UTC (permalink / raw)
To: linux-arm-kernel
The mvebu arch has the same I2C controller as mv64xxx-i2c.
This support mv64xxx-i2c on mvebu.
Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
---
arch/arm/boot/dts/armada-370-xp.dtsi | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index d0ea4a6..5da85c2 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -83,6 +83,29 @@
interrupts = <10>;
status = "disabled";
};
+
+
+ i2c0: i2c at d0011000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0xd0011000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <31>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c at d0011100 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0xd0011100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <32>;
+ timeout-ms = <1000>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
};
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH] i2c: mv64xxx: Add support Armada-XP SoC
From: Nobuhiro Iwamatsu @ 2012-10-30 10:39 UTC (permalink / raw)
To: linux-arm-kernel
The Armada-XP SoC has the same I2C controller as mv64xxxi-i2c.
This validates to use mv64xxx in this SoC.
Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
---
drivers/i2c/busses/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 65dd599..ff53cf4 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -474,7 +474,7 @@ config I2C_MPC
config I2C_MV64XXX
tristate "Marvell mv64xxx I2C Controller"
- depends on (MV64X60 || PLAT_ORION)
+ depends on (MV64X60 || PLAT_ORION || MACH_ARMADA_370_XP)
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Marvell 64xxx line of host bridges.
--
1.7.10.4
^ permalink raw reply related
* linux-next: manual merge of the clk tree with the arm-soc tree
From: Pawel Moll @ 2012-10-30 10:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121030101140.18780.69840@nucleus>
On Tue, 2012-10-30 at 10:11 +0000, Mike Turquette wrote:
> > diff --cc arch/arm/include/asm/hardware/sp810.h
> > index 2cdcf44,afd7e91..0000000
> > --- a/arch/arm/include/asm/hardware/sp810.h
> > +++ b/arch/arm/include/asm/hardware/sp810.h
> > @@@ -50,6 -50,14 +50,8 @@@
> > #define SCPCELLID2 0xFF8
> > #define SCPCELLID3 0xFFC
> >
> > -#define SCCTRL_TIMEREN0SEL_REFCLK (0 << 15)
> > -#define SCCTRL_TIMEREN0SEL_TIMCLK (1 << 15)
> > -
> > -#define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17)
> > -#define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17)
> > -
> > + #define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2))
> > +
> > static inline void sysctl_soft_reset(void __iomem *base)
> > {
> > /* switch to slow mode */
>
> Pawel,
>
> Does this look OK for you?
Yes, it's correct.
Thanks!
Pawe?
^ permalink raw reply
* [PATCH 2/2] ARM: OMAP: omap_device: Correct resource handling for DT boot
From: Peter Ujfalusi @ 2012-10-30 10:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351593205-13590-1-git-send-email-peter.ujfalusi@ti.com>
When booting with DT the OF core can fill up the resources provided within
the DT blob.
The current way of handling the DT boot prevents us from removing hwmod data
for platforms only suppose to boot with DT (OMAP5 for example) since we need
to keep the whole hwmod database intact in order to have more resources in
hwmod than in DT (to be able to append the DMA resource from hwmod).
To fix this issue we just examine the OF provided resources:
If we do not have resources we use hwmod to fill them.
If we have resources we check if we already able to recive DMA resource, if
no we only append the DMA resurce from hwmod to the OF provided ones.
In this way we can start removing hwmod data for devices which have their
resources correctly configured in DT without regressions.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
arch/arm/plat-omap/omap_device.c | 80 +++++++++++++++++++++++-----------------
1 file changed, 47 insertions(+), 33 deletions(-)
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 915cf68..a8a9d08 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -560,55 +560,69 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
od->hwmods = hwmods;
od->pdev = pdev;
- /* Count all resources for the device */
- res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
- IORESOURCE_DMA |
- IORESOURCE_MEM);
/*
+ * Non-DT Boot:
+ * Here, pdev->num_resources = 0, and we should get all the
+ * resources from hwmod.
+ *
* DT Boot:
* OF framework will construct the resource structure (currently
* does for MEM & IRQ resource) and we should respect/use these
* resources, killing hwmod dependency.
* If pdev->num_resources > 0, we assume that MEM & IRQ resources
* have been allocated by OF layer already (through DTB).
- *
- * Non-DT Boot:
- * Here, pdev->num_resources = 0, and we should get all the
- * resources from hwmod.
+ * As preparation for the future we examine the OF provided resources
+ * to see if we have DMA resources provided already. In this case
+ * there is no need to update the resources for the device, we use the
+ * OF provided ones.
*
* TODO: Once DMA resource is available from OF layer, we should
* kill filling any resources from hwmod.
*/
- if (res_count > pdev->num_resources) {
- /* Allocate resources memory to account for new resources */
- res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
- if (!res)
- goto oda_exit3;
-
- /*
- * If pdev->num_resources > 0, then assume that,
- * MEM and IRQ resources will only come from DT and only
- * fill DMA resource from hwmod layer.
- */
- if (pdev->num_resources && pdev->resource) {
- dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n",
- __func__, res_count);
- memcpy(res, pdev->resource,
- sizeof(struct resource) * pdev->num_resources);
- _od_fill_dma_resources(od, &res[pdev->num_resources]);
- } else {
- dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
- __func__, res_count);
- omap_device_fill_resources(od, res);
+ if (!pdev->num_resources) {
+ /* Count all resources for the device */
+ res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
+ IORESOURCE_DMA |
+ IORESOURCE_MEM);
+ } else {
+ /* Take a look if we already have DMA resource via DT */
+ for (i = 0; i < pdev->num_resources; i++) {
+ struct resource *r = &pdev->resource[i];
+
+ /* We have it, no need to touch the resources */
+ if (r->flags == IORESOURCE_DMA)
+ goto have_everything;
}
+ /* Count only DMA resources for the device */
+ res_count = omap_device_count_resources(od, IORESOURCE_DMA);
+ res_count += pdev->num_resources;
+ }
- ret = platform_device_add_resources(pdev, res, res_count);
- kfree(res);
+ /* Allocate resources memory to account for new resources */
+ res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
+ if (!res)
+ goto oda_exit3;
- if (ret)
- goto oda_exit3;
+ if (!pdev->num_resources) {
+ dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
+ __func__, res_count);
+ omap_device_fill_resources(od, res);
+ } else {
+ dev_dbg(&pdev->dev,
+ "%s: appending %d DMA resources from hwmod\n",
+ __func__, res_count - pdev->num_resources);
+ memcpy(res, pdev->resource,
+ sizeof(struct resource) * pdev->num_resources);
+ _od_fill_dma_resources(od, &res[pdev->num_resources]);
}
+ ret = platform_device_add_resources(pdev, res, res_count);
+ kfree(res);
+
+ if (ret)
+ goto oda_exit3;
+
+have_everything:
if (!pm_lats) {
pm_lats = omap_default_latency;
pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
--
1.7.12.4
^ permalink raw reply related
* [PATCH 1/2] ARM: OMAP: hwmod: Add possibility to count hwmod resources based on type
From: Peter Ujfalusi @ 2012-10-30 10:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351593205-13590-1-git-send-email-peter.ujfalusi@ti.com>
Add flags parameter for omap_hwmod_count_resources() so users can tell which
type of resources they are interested when counting them in hwmod database.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
arch/arm/mach-omap2/omap_hwmod.c | 27 ++++++++++++++++-----------
arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 +-
arch/arm/plat-omap/omap_device.c | 11 ++++++++---
3 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b969ab1..a79c941 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -3337,7 +3337,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
/**
* omap_hwmod_count_resources - count number of struct resources needed by hwmod
* @oh: struct omap_hwmod *
- * @res: pointer to the first element of an array of struct resource to fill
+ * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
*
* Count the number of struct resource array elements necessary to
* contain omap_hwmod @oh resources. Intended to be called by code
@@ -3350,20 +3350,25 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
* resource IDs.
*
*/
-int omap_hwmod_count_resources(struct omap_hwmod *oh)
+int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags)
{
- struct omap_hwmod_ocp_if *os;
- struct list_head *p;
- int ret;
- int i = 0;
+ int ret = 0;
- ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh);
+ if (flags & IORESOURCE_IRQ)
+ ret += _count_mpu_irqs(oh);
- p = oh->slave_ports.next;
+ if (flags & IORESOURCE_DMA)
+ ret += _count_sdma_reqs(oh);
- while (i < oh->slaves_cnt) {
- os = _fetch_next_ocp_if(&p, &i);
- ret += _count_ocp_if_addr_spaces(os);
+ if (flags & IORESOURCE_MEM) {
+ int i = 0;
+ struct omap_hwmod_ocp_if *os;
+ struct list_head *p = oh->slave_ports.next;
+
+ while (i < oh->slaves_cnt) {
+ os = _fetch_next_ocp_if(&p, &i);
+ ret += _count_ocp_if_addr_spaces(os);
+ }
}
return ret;
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index b3349f7..48a6f5d 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -628,7 +628,7 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
int omap_hwmod_softreset(struct omap_hwmod *oh);
-int omap_hwmod_count_resources(struct omap_hwmod *oh);
+int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags);
int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res);
int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 7a7d1f2..915cf68 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -442,19 +442,21 @@ int omap_device_get_context_loss_count(struct platform_device *pdev)
/**
* omap_device_count_resources - count number of struct resource entries needed
* @od: struct omap_device *
+ * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
*
* Count the number of struct resource entries needed for this
* omap_device @od. Used by omap_device_build_ss() to determine how
* much memory to allocate before calling
* omap_device_fill_resources(). Returns the count.
*/
-static int omap_device_count_resources(struct omap_device *od)
+static int omap_device_count_resources(struct omap_device *od,
+ unsigned long flags)
{
int c = 0;
int i;
for (i = 0; i < od->hwmods_cnt; i++)
- c += omap_hwmod_count_resources(od->hwmods[i]);
+ c += omap_hwmod_count_resources(od->hwmods[i], flags);
pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
od->pdev->name, c, od->hwmods_cnt);
@@ -558,7 +560,10 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
od->hwmods = hwmods;
od->pdev = pdev;
- res_count = omap_device_count_resources(od);
+ /* Count all resources for the device */
+ res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
+ IORESOURCE_DMA |
+ IORESOURCE_MEM);
/*
* DT Boot:
* OF framework will construct the resource structure (currently
--
1.7.12.4
^ permalink raw reply related
* [PATCH 0/2] ARM: OMAP: hwmod/omapd_device: Fix for resource handling in DT boot
From: Peter Ujfalusi @ 2012-10-30 10:33 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
This series resolves the issue we currently have with the resource handling when
booting with DT.
In short: at the moment the omap_device_alloc() decides if it needs to update the
OF filled resources based on the number of resources on the device and in the
hwmod database.
This prevents us from removing hwmod data for platforms (OMAP5) which does not
support non DT boot anymore.
With this series we can make sure that the DT provided resources are used and we
only append the DMA resources to the device from hwmod.
I have added extra check to prepare us when the DMA resource can be filled via
OF. In this case we do not update the resources at all.
Tony, Benoit, Paul: Not sure if this qualify for 3.7 inclusion, but for sure
going to help us to clean up the OMAP5 hwmod database.
Regards,
Peter
---
Peter Ujfalusi (2):
ARM: OMAP: hwmod: Add possibility to count hwmod resources based on
type
ARM: OMAP: omap_device: Correct resource handling for DT boot
arch/arm/mach-omap2/omap_hwmod.c | 27 +++++----
arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 +-
arch/arm/plat-omap/omap_device.c | 83 +++++++++++++++++-----------
3 files changed, 68 insertions(+), 44 deletions(-)
--
1.7.12.4
^ permalink raw reply
* [PATCH v3 10/10] net/macb: add pinctrl consumer support
From: Nicolas Ferre @ 2012-10-30 10:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>
From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
If no pinctrl available just report a warning as some architecture may not
need to do anything.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
[nicolas.ferre at atmel.com: adapt the error path]
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: netdev at vger.kernel.org
---
drivers/net/ethernet/cadence/macb.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 4d51877..eae3d74 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -26,6 +26,9 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_net.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/consumer.h>
#include "macb.h"
@@ -1472,6 +1475,7 @@ static int __init macb_probe(struct platform_device *pdev)
struct phy_device *phydev;
u32 config;
int err = -ENXIO;
+ struct pinctrl *pinctrl;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
@@ -1479,6 +1483,15 @@ static int __init macb_probe(struct platform_device *pdev)
goto err_out;
}
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ err = PTR_ERR(pinctrl);
+ if (err == -EPROBE_DEFER)
+ goto err_out;
+
+ dev_warn(&pdev->dev, "No pinctrl provided\n");
+ }
+
err = -ENOMEM;
dev = alloc_etherdev(sizeof(*bp));
if (!dev)
--
1.8.0
^ permalink raw reply related
* [PATCH v3 09/10] net/macb: Offset first RX buffer by two bytes
From: Nicolas Ferre @ 2012-10-30 10:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>
From: Havard Skinnemoen <havard@skinnemoen.net>
Make the ethernet frame payload word-aligned, possibly making the
memcpy into the skb a bit faster. This will be even more important
after we eliminate the copy altogether.
Also eliminate the redundant RX_OFFSET constant -- it has the same
definition and purpose as NET_IP_ALIGN.
Signed-off-by: Havard Skinnemoen <havard@skinnemoen.net>
[nicolas.ferre at atmel.com: adapt to newer kernel]
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
drivers/net/ethernet/cadence/macb.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 83aa834..4d51877 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -33,9 +33,6 @@
#define RX_RING_SIZE 512
#define RX_RING_BYTES (sizeof(struct macb_dma_desc) * RX_RING_SIZE)
-/* Make the IP header word-aligned (the ethernet header is 14 bytes) */
-#define RX_OFFSET 2
-
#define TX_RING_SIZE 128
#define TX_RING_BYTES (sizeof(struct macb_dma_desc) * TX_RING_SIZE)
@@ -498,7 +495,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
{
unsigned int len;
unsigned int frag;
- unsigned int offset = 0;
+ unsigned int offset;
struct sk_buff *skb;
struct macb_dma_desc *desc;
@@ -509,7 +506,16 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
macb_rx_ring_wrap(first_frag),
macb_rx_ring_wrap(last_frag), len);
- skb = netdev_alloc_skb(bp->dev, len + RX_OFFSET);
+ /*
+ * The ethernet header starts NET_IP_ALIGN bytes into the
+ * first buffer. Since the header is 14 bytes, this makes the
+ * payload word-aligned.
+ *
+ * Instead of calling skb_reserve(NET_IP_ALIGN), we just copy
+ * the two padding bytes into the skb so that we avoid hitting
+ * the slowpath in memcpy(), and pull them off afterwards.
+ */
+ skb = netdev_alloc_skb(bp->dev, len + NET_IP_ALIGN);
if (!skb) {
bp->stats.rx_dropped++;
for (frag = first_frag; ; frag++) {
@@ -525,7 +531,8 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
return 1;
}
- skb_reserve(skb, RX_OFFSET);
+ offset = 0;
+ len += NET_IP_ALIGN;
skb_checksum_none_assert(skb);
skb_put(skb, len);
@@ -549,10 +556,11 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
/* Make descriptor updates visible to hardware */
wmb();
+ __skb_pull(skb, NET_IP_ALIGN);
skb->protocol = eth_type_trans(skb, bp->dev);
bp->stats.rx_packets++;
- bp->stats.rx_bytes += len;
+ bp->stats.rx_bytes += skb->len;
netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
skb->len, skb->csum);
netif_receive_skb(skb);
@@ -1012,6 +1020,7 @@ static void macb_init_hw(struct macb *bp)
__macb_set_hwaddr(bp);
config = macb_mdc_clk_div(bp);
+ config |= MACB_BF(RBOF, NET_IP_ALIGN); /* Make eth data aligned */
config |= MACB_BIT(PAE); /* PAuse Enable */
config |= MACB_BIT(DRFCS); /* Discard Rx FCS */
config |= MACB_BIT(BIG); /* Receive oversized frames */
--
1.8.0
^ permalink raw reply related
* [PATCH v3 08/10] net/macb: better manage tx errors
From: Nicolas Ferre @ 2012-10-30 10:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>
Handle all TX errors, not only underruns. TX error management is
deferred to a dedicated workqueue.
Reinitialize the TX ring after treating all remaining frames, and
restart the controller when everything has been cleaned up properly.
Napi is not stopped during this task as the driver only handles
napi for RX for now.
With this sequence, we do not need a special check during the xmit
method as the packets will be caught by TX disable during workqueue
execution.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
drivers/net/ethernet/cadence/macb.c | 166 ++++++++++++++++++++++++------------
drivers/net/ethernet/cadence/macb.h | 1 +
2 files changed, 113 insertions(+), 54 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index ce29741..83aa834 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -44,6 +44,16 @@
#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \
| MACB_BIT(ISR_ROVR))
+#define MACB_TX_ERR_FLAGS (MACB_BIT(ISR_TUND) \
+ | MACB_BIT(ISR_RLE) \
+ | MACB_BIT(TXERR))
+#define MACB_TX_INT_FLAGS (MACB_TX_ERR_FLAGS | MACB_BIT(TCOMP))
+
+/*
+ * Graceful stop timeouts in us. We should allow up to
+ * 1 frame time (10 Mbits/s, full-duplex, ignoring collisions)
+ */
+#define MACB_HALT_TIMEOUT 1230
/* Ring buffer accessors */
static unsigned int macb_tx_ring_wrap(unsigned int index)
@@ -339,66 +349,113 @@ static void macb_update_stats(struct macb *bp)
*p += __raw_readl(reg);
}
-static void macb_tx(struct macb *bp)
+static int macb_halt_tx(struct macb *bp)
{
- unsigned int tail;
- unsigned int head;
- u32 status;
+ unsigned long halt_time, timeout;
+ u32 status;
- status = macb_readl(bp, TSR);
- macb_writel(bp, TSR, status);
+ macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(THALT));
- netdev_vdbg(bp->dev, "macb_tx status = 0x%03lx\n", (unsigned long)status);
+ timeout = jiffies + usecs_to_jiffies(MACB_HALT_TIMEOUT);
+ do {
+ halt_time = jiffies;
+ status = macb_readl(bp, TSR);
+ if (!(status & MACB_BIT(TGO)))
+ return 0;
- if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) {
- int i;
- netdev_err(bp->dev, "TX %s, resetting buffers\n",
- status & MACB_BIT(UND) ?
- "underrun" : "retry limit exceeded");
+ usleep_range(10, 250);
+ } while (time_before(halt_time, timeout));
- /* Transfer ongoing, disable transmitter, to avoid confusion */
- if (status & MACB_BIT(TGO))
- macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE));
+ return -ETIMEDOUT;
+}
- head = bp->tx_head;
+static void macb_tx_error_task(struct work_struct *work)
+{
+ struct macb *bp = container_of(work, struct macb, tx_error_task);
+ struct macb_tx_skb *tx_skb;
+ struct sk_buff *skb;
+ unsigned int tail;
- /*Mark all the buffer as used to avoid sending a lost buffer*/
- for (i = 0; i < TX_RING_SIZE; i++)
- bp->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+ netdev_vdbg(bp->dev, "macb_tx_error_task: t = %u, h = %u\n",
+ bp->tx_tail, bp->tx_head);
- /* Add wrap bit */
- bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
+ /* Make sure nobody is trying to queue up new packets */
+ netif_stop_queue(bp->dev);
- /* free transmit buffer in upper layer*/
- for (tail = bp->tx_tail; tail != head; tail++) {
- struct macb_tx_skb *tx_skb;
- struct sk_buff *skb;
+ /*
+ * Stop transmission now
+ * (in case we have just queued new packets)
+ */
+ if (macb_halt_tx(bp))
+ /* Just complain for now, reinitializing TX path can be good */
+ netdev_err(bp->dev, "BUG: halt tx timed out\n");
- rmb();
+ /* No need for the lock here as nobody will interrupt us anymore */
- tx_skb = macb_tx_skb(bp, tail);
- skb = tx_skb->skb;
+ /*
+ * Treat frames in TX queue including the ones that caused the error.
+ * Free transmit buffers in upper layer.
+ */
+ for (tail = bp->tx_tail; tail != bp->tx_head; tail++) {
+ struct macb_dma_desc *desc;
+ u32 ctrl;
- dma_unmap_single(&bp->pdev->dev, tx_skb->mapping,
- skb->len, DMA_TO_DEVICE);
- tx_skb->skb = NULL;
- dev_kfree_skb_irq(skb);
- }
+ desc = macb_tx_desc(bp, tail);
+ ctrl = desc->ctrl;
+ tx_skb = macb_tx_skb(bp, tail);
+ skb = tx_skb->skb;
- bp->tx_head = bp->tx_tail = 0;
+ if (ctrl & MACB_BIT(TX_USED)) {
+ netdev_vdbg(bp->dev, "txerr skb %u (data %p) TX complete\n",
+ macb_tx_ring_wrap(tail), skb->data);
+ bp->stats.tx_packets++;
+ bp->stats.tx_bytes += skb->len;
+ } else {
+ /*
+ * "Buffers exhausted mid-frame" errors may only happen
+ * if the driver is buggy, so complain loudly about those.
+ * Statistics are updated by hardware.
+ */
+ if (ctrl & MACB_BIT(TX_BUF_EXHAUSTED))
+ netdev_err(bp->dev,
+ "BUG: TX buffers exhausted mid-frame\n");
- /* Enable the transmitter again */
- if (status & MACB_BIT(TGO))
- macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE));
+ desc->ctrl = ctrl | MACB_BIT(TX_USED);
+ }
+
+ dma_unmap_single(&bp->pdev->dev, tx_skb->mapping, skb->len,
+ DMA_TO_DEVICE);
+ tx_skb->skb = NULL;
+ dev_kfree_skb(skb);
}
- if (!(status & MACB_BIT(COMP)))
- /*
- * This may happen when a buffer becomes complete
- * between reading the ISR and scanning the
- * descriptors. Nothing to worry about.
- */
- return;
+ /* Make descriptor updates visible to hardware */
+ wmb();
+
+ /* Reinitialize the TX desc queue */
+ macb_writel(bp, TBQP, bp->tx_ring_dma);
+ /* Make TX ring reflect state of hardware */
+ bp->tx_head = bp->tx_tail = 0;
+
+ /* Now we are ready to start transmission again */
+ netif_wake_queue(bp->dev);
+
+ /* Housework before enabling TX IRQ */
+ macb_writel(bp, TSR, macb_readl(bp, TSR));
+ macb_writel(bp, IER, MACB_TX_INT_FLAGS);
+}
+
+static void macb_tx_interrupt(struct macb *bp)
+{
+ unsigned int tail;
+ unsigned int head;
+ u32 status;
+
+ status = macb_readl(bp, TSR);
+ macb_writel(bp, TSR, status);
+
+ netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n",
+ (unsigned long)status);
head = bp->tx_head;
for (tail = bp->tx_tail; tail != head; tail++) {
@@ -638,9 +695,14 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
}
}
- if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) |
- MACB_BIT(ISR_RLE)))
- macb_tx(bp);
+ if (unlikely(status & (MACB_TX_ERR_FLAGS))) {
+ macb_writel(bp, IDR, MACB_TX_INT_FLAGS);
+ schedule_work(&bp->tx_error_task);
+ break;
+ }
+
+ if (status & MACB_BIT(TCOMP))
+ macb_tx_interrupt(bp);
/*
* Link change detection isn't possible with RMII, so we'll
@@ -970,13 +1032,8 @@ static void macb_init_hw(struct macb *bp)
macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE));
/* Enable interrupts */
- macb_writel(bp, IER, (MACB_BIT(RCOMP)
- | MACB_BIT(RXUBR)
- | MACB_BIT(ISR_TUND)
- | MACB_BIT(ISR_RLE)
- | MACB_BIT(TXERR)
- | MACB_BIT(TCOMP)
- | MACB_BIT(ISR_ROVR)
+ macb_writel(bp, IER, (MACB_RX_INT_FLAGS
+ | MACB_TX_INT_FLAGS
| MACB_BIT(HRESP)));
}
@@ -1428,6 +1485,7 @@ static int __init macb_probe(struct platform_device *pdev)
bp->dev = dev;
spin_lock_init(&bp->lock);
+ INIT_WORK(&bp->tx_error_task, macb_tx_error_task);
bp->pclk = clk_get(&pdev->dev, "pclk");
if (IS_ERR(bp->pclk)) {
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 232dca6..4235ab8 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -538,6 +538,7 @@ struct macb {
struct clk *hclk;
struct net_device *dev;
struct napi_struct napi;
+ struct work_struct tx_error_task;
struct net_device_stats stats;
union {
struct macb_stats macb;
--
1.8.0
^ permalink raw reply related
* [PATCH v3 07/10] net/macb: ethtool interface: add register dump feature
From: Nicolas Ferre @ 2012-10-30 10:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>
Add macb_get_regs() ethtool function and its helper function:
macb_get_regs_len().
The version field is deduced from the IP revision which gives the
"MACB or GEM" information. An additional version field is reserved.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/ethernet/cadence/macb.c | 40 +++++++++++++++++++++++++++++++++++++
drivers/net/ethernet/cadence/macb.h | 3 +++
2 files changed, 43 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index dc03b36..ce29741 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -1273,9 +1273,49 @@ static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return phy_ethtool_sset(phydev, cmd);
}
+static int macb_get_regs_len(struct net_device *netdev)
+{
+ return MACB_GREGS_NBR * sizeof(u32);
+}
+
+static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ void *p)
+{
+ struct macb *bp = netdev_priv(dev);
+ unsigned int tail, head;
+ u32 *regs_buff = p;
+
+ regs->version = (macb_readl(bp, MID) & ((1 << MACB_REV_SIZE) - 1))
+ | MACB_GREGS_VERSION;
+
+ tail = macb_tx_ring_wrap(bp->tx_tail);
+ head = macb_tx_ring_wrap(bp->tx_head);
+
+ regs_buff[0] = macb_readl(bp, NCR);
+ regs_buff[1] = macb_or_gem_readl(bp, NCFGR);
+ regs_buff[2] = macb_readl(bp, NSR);
+ regs_buff[3] = macb_readl(bp, TSR);
+ regs_buff[4] = macb_readl(bp, RBQP);
+ regs_buff[5] = macb_readl(bp, TBQP);
+ regs_buff[6] = macb_readl(bp, RSR);
+ regs_buff[7] = macb_readl(bp, IMR);
+
+ regs_buff[8] = tail;
+ regs_buff[9] = head;
+ regs_buff[10] = macb_tx_dma(bp, tail);
+ regs_buff[11] = macb_tx_dma(bp, head);
+
+ if (macb_is_gem(bp)) {
+ regs_buff[12] = gem_readl(bp, USRIO);
+ regs_buff[13] = gem_readl(bp, DMACFG);
+ }
+}
+
const struct ethtool_ops macb_ethtool_ops = {
.get_settings = macb_get_settings,
.set_settings = macb_set_settings,
+ .get_regs_len = macb_get_regs_len,
+ .get_regs = macb_get_regs,
.get_link = ethtool_op_get_link,
.get_ts_info = ethtool_op_get_ts_info,
};
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 024a270..232dca6 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -10,6 +10,9 @@
#ifndef _MACB_H
#define _MACB_H
+#define MACB_GREGS_NBR 16
+#define MACB_GREGS_VERSION 1
+
/* MACB register offsets */
#define MACB_NCR 0x0000
#define MACB_NCFGR 0x0004
--
1.8.0
^ permalink raw reply related
* [PATCH v3 06/10] net/macb: clean up ring buffer logic
From: Nicolas Ferre @ 2012-10-30 10:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>
From: Havard Skinnemoen <havard@skinnemoen.net>
Instead of masking head and tail every time we increment them, just let them
wrap through UINT_MAX and mask them when subscripting. Add simple accessor
functions to do the subscripting properly to minimize the chances of messing
this up.
This makes the code slightly smaller, and hopefully faster as well. Also,
doing the ring buffer management this way will simplify things a lot when
making the ring sizes configurable in the future.
Signed-off-by: Havard Skinnemoen <havard@skinnemoen.net>
[nicolas.ferre at atmel.com: split patch in topics, adapt to newer kernel]
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
drivers/net/ethernet/cadence/macb.c | 168 +++++++++++++++++++++++-------------
drivers/net/ethernet/cadence/macb.h | 22 +++--
2 files changed, 122 insertions(+), 68 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index cd6d431..dc03b36 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -31,24 +31,13 @@
#define RX_BUFFER_SIZE 128
#define RX_RING_SIZE 512
-#define RX_RING_BYTES (sizeof(struct dma_desc) * RX_RING_SIZE)
+#define RX_RING_BYTES (sizeof(struct macb_dma_desc) * RX_RING_SIZE)
/* Make the IP header word-aligned (the ethernet header is 14 bytes) */
#define RX_OFFSET 2
#define TX_RING_SIZE 128
-#define DEF_TX_RING_PENDING (TX_RING_SIZE - 1)
-#define TX_RING_BYTES (sizeof(struct dma_desc) * TX_RING_SIZE)
-
-#define TX_RING_GAP(bp) \
- (TX_RING_SIZE - (bp)->tx_pending)
-#define TX_BUFFS_AVAIL(bp) \
- (((bp)->tx_tail <= (bp)->tx_head) ? \
- (bp)->tx_tail + (bp)->tx_pending - (bp)->tx_head : \
- (bp)->tx_tail - (bp)->tx_head - TX_RING_GAP(bp))
-#define NEXT_TX(n) (((n) + 1) & (TX_RING_SIZE - 1))
-
-#define NEXT_RX(n) (((n) + 1) & (RX_RING_SIZE - 1))
+#define TX_RING_BYTES (sizeof(struct macb_dma_desc) * TX_RING_SIZE)
/* minimum number of free TX descriptors before waking up TX process */
#define MACB_TX_WAKEUP_THRESH (TX_RING_SIZE / 4)
@@ -56,6 +45,51 @@
#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \
| MACB_BIT(ISR_ROVR))
+/* Ring buffer accessors */
+static unsigned int macb_tx_ring_wrap(unsigned int index)
+{
+ return index & (TX_RING_SIZE - 1);
+}
+
+static unsigned int macb_tx_ring_avail(struct macb *bp)
+{
+ return TX_RING_SIZE - (bp->tx_head - bp->tx_tail);
+}
+
+static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index)
+{
+ return &bp->tx_ring[macb_tx_ring_wrap(index)];
+}
+
+static struct macb_tx_skb *macb_tx_skb(struct macb *bp, unsigned int index)
+{
+ return &bp->tx_skb[macb_tx_ring_wrap(index)];
+}
+
+static dma_addr_t macb_tx_dma(struct macb *bp, unsigned int index)
+{
+ dma_addr_t offset;
+
+ offset = macb_tx_ring_wrap(index) * sizeof(struct macb_dma_desc);
+
+ return bp->tx_ring_dma + offset;
+}
+
+static unsigned int macb_rx_ring_wrap(unsigned int index)
+{
+ return index & (RX_RING_SIZE - 1);
+}
+
+static struct macb_dma_desc *macb_rx_desc(struct macb *bp, unsigned int index)
+{
+ return &bp->rx_ring[macb_rx_ring_wrap(index)];
+}
+
+static void *macb_rx_buffer(struct macb *bp, unsigned int index)
+{
+ return bp->rx_buffers + RX_BUFFER_SIZE * macb_rx_ring_wrap(index);
+}
+
static void __macb_set_hwaddr(struct macb *bp)
{
u32 bottom;
@@ -336,17 +370,18 @@ static void macb_tx(struct macb *bp)
bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
/* free transmit buffer in upper layer*/
- for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {
- struct ring_info *rp = &bp->tx_skb[tail];
- struct sk_buff *skb = rp->skb;
-
- BUG_ON(skb == NULL);
+ for (tail = bp->tx_tail; tail != head; tail++) {
+ struct macb_tx_skb *tx_skb;
+ struct sk_buff *skb;
rmb();
- dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
- DMA_TO_DEVICE);
- rp->skb = NULL;
+ tx_skb = macb_tx_skb(bp, tail);
+ skb = tx_skb->skb;
+
+ dma_unmap_single(&bp->pdev->dev, tx_skb->mapping,
+ skb->len, DMA_TO_DEVICE);
+ tx_skb->skb = NULL;
dev_kfree_skb_irq(skb);
}
@@ -366,34 +401,38 @@ static void macb_tx(struct macb *bp)
return;
head = bp->tx_head;
- for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {
- struct ring_info *rp = &bp->tx_skb[tail];
- struct sk_buff *skb = rp->skb;
- u32 bufstat;
+ for (tail = bp->tx_tail; tail != head; tail++) {
+ struct macb_tx_skb *tx_skb;
+ struct sk_buff *skb;
+ struct macb_dma_desc *desc;
+ u32 ctrl;
- BUG_ON(skb == NULL);
+ desc = macb_tx_desc(bp, tail);
/* Make hw descriptor updates visible to CPU */
rmb();
- bufstat = bp->tx_ring[tail].ctrl;
+ ctrl = desc->ctrl;
- if (!(bufstat & MACB_BIT(TX_USED)))
+ if (!(ctrl & MACB_BIT(TX_USED)))
break;
+ tx_skb = macb_tx_skb(bp, tail);
+ skb = tx_skb->skb;
+
netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
- tail, skb->data);
- dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
+ macb_tx_ring_wrap(tail), skb->data);
+ dma_unmap_single(&bp->pdev->dev, tx_skb->mapping, skb->len,
DMA_TO_DEVICE);
bp->stats.tx_packets++;
bp->stats.tx_bytes += skb->len;
- rp->skb = NULL;
+ tx_skb->skb = NULL;
dev_kfree_skb_irq(skb);
}
bp->tx_tail = tail;
- if (netif_queue_stopped(bp->dev) &&
- TX_BUFFS_AVAIL(bp) > MACB_TX_WAKEUP_THRESH)
+ if (netif_queue_stopped(bp->dev)
+ && macb_tx_ring_avail(bp) > MACB_TX_WAKEUP_THRESH)
netif_wake_queue(bp->dev);
}
@@ -404,17 +443,21 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
unsigned int frag;
unsigned int offset = 0;
struct sk_buff *skb;
+ struct macb_dma_desc *desc;
- len = MACB_BFEXT(RX_FRMLEN, bp->rx_ring[last_frag].ctrl);
+ desc = macb_rx_desc(bp, last_frag);
+ len = MACB_BFEXT(RX_FRMLEN, desc->ctrl);
netdev_vdbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n",
- first_frag, last_frag, len);
+ macb_rx_ring_wrap(first_frag),
+ macb_rx_ring_wrap(last_frag), len);
skb = netdev_alloc_skb(bp->dev, len + RX_OFFSET);
if (!skb) {
bp->stats.rx_dropped++;
- for (frag = first_frag; ; frag = NEXT_RX(frag)) {
- bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
+ for (frag = first_frag; ; frag++) {
+ desc = macb_rx_desc(bp, frag);
+ desc->addr &= ~MACB_BIT(RX_USED);
if (frag == last_frag)
break;
}
@@ -429,7 +472,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
skb_checksum_none_assert(skb);
skb_put(skb, len);
- for (frag = first_frag; ; frag = NEXT_RX(frag)) {
+ for (frag = first_frag; ; frag++) {
unsigned int frag_len = RX_BUFFER_SIZE;
if (offset + frag_len > len) {
@@ -437,11 +480,10 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
frag_len = len - offset;
}
skb_copy_to_linear_data_offset(skb, offset,
- (bp->rx_buffers +
- (RX_BUFFER_SIZE * frag)),
- frag_len);
+ macb_rx_buffer(bp, frag), frag_len);
offset += RX_BUFFER_SIZE;
- bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
+ desc = macb_rx_desc(bp, frag);
+ desc->addr &= ~MACB_BIT(RX_USED);
if (frag == last_frag)
break;
@@ -467,8 +509,10 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin,
{
unsigned int frag;
- for (frag = begin; frag != end; frag = NEXT_RX(frag))
- bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
+ for (frag = begin; frag != end; frag++) {
+ struct macb_dma_desc *desc = macb_rx_desc(bp, frag);
+ desc->addr &= ~MACB_BIT(RX_USED);
+ }
/* Make descriptor updates visible to hardware */
wmb();
@@ -483,17 +527,18 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin,
static int macb_rx(struct macb *bp, int budget)
{
int received = 0;
- unsigned int tail = bp->rx_tail;
+ unsigned int tail;
int first_frag = -1;
- for (; budget > 0; tail = NEXT_RX(tail)) {
+ for (tail = bp->rx_tail; budget > 0; tail++) {
+ struct macb_dma_desc *desc = macb_rx_desc(bp, tail);
u32 addr, ctrl;
/* Make hw descriptor updates visible to CPU */
rmb();
- addr = bp->rx_ring[tail].addr;
- ctrl = bp->rx_ring[tail].ctrl;
+ addr = desc->addr;
+ ctrl = desc->ctrl;
if (!(addr & MACB_BIT(RX_USED)))
break;
@@ -647,6 +692,8 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct macb *bp = netdev_priv(dev);
dma_addr_t mapping;
unsigned int len, entry;
+ struct macb_dma_desc *desc;
+ struct macb_tx_skb *tx_skb;
u32 ctrl;
unsigned long flags;
@@ -663,7 +710,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&bp->lock, flags);
/* This is a hard error, log it. */
- if (TX_BUFFS_AVAIL(bp) < 1) {
+ if (macb_tx_ring_avail(bp) < 1) {
netif_stop_queue(dev);
spin_unlock_irqrestore(&bp->lock, flags);
netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n");
@@ -672,12 +719,15 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
- entry = bp->tx_head;
+ entry = macb_tx_ring_wrap(bp->tx_head);
+ bp->tx_head++;
netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry);
mapping = dma_map_single(&bp->pdev->dev, skb->data,
len, DMA_TO_DEVICE);
- bp->tx_skb[entry].skb = skb;
- bp->tx_skb[entry].mapping = mapping;
+
+ tx_skb = &bp->tx_skb[entry];
+ tx_skb->skb = skb;
+ tx_skb->mapping = mapping;
netdev_vdbg(bp->dev, "Mapped skb data %p to DMA addr %08lx\n",
skb->data, (unsigned long)mapping);
@@ -686,20 +736,18 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (entry == (TX_RING_SIZE - 1))
ctrl |= MACB_BIT(TX_WRAP);
- bp->tx_ring[entry].addr = mapping;
- bp->tx_ring[entry].ctrl = ctrl;
+ desc = &bp->tx_ring[entry];
+ desc->addr = mapping;
+ desc->ctrl = ctrl;
/* Make newly initialized descriptor visible to hardware */
wmb();
- entry = NEXT_TX(entry);
- bp->tx_head = entry;
-
skb_tx_timestamp(skb);
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
- if (TX_BUFFS_AVAIL(bp) < 1)
+ if (macb_tx_ring_avail(bp) < 1)
netif_stop_queue(dev);
spin_unlock_irqrestore(&bp->lock, flags);
@@ -735,7 +783,7 @@ static int macb_alloc_consistent(struct macb *bp)
{
int size;
- size = TX_RING_SIZE * sizeof(struct ring_info);
+ size = TX_RING_SIZE * sizeof(struct macb_tx_skb);
bp->tx_skb = kmalloc(size, GFP_KERNEL);
if (!bp->tx_skb)
goto out_err;
@@ -1412,8 +1460,6 @@ static int __init macb_probe(struct platform_device *pdev)
macb_or_gem_writel(bp, USRIO, MACB_BIT(MII));
#endif
- bp->tx_pending = DEF_TX_RING_PENDING;
-
err = register_netdev(dev);
if (err) {
dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 33a050f..024a270 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -362,7 +362,12 @@
__v; \
})
-struct dma_desc {
+/**
+ * struct macb_dma_desc - Hardware DMA descriptor
+ * @addr: DMA address of data buffer
+ * @ctrl: Control and status bits
+ */
+struct macb_dma_desc {
u32 addr;
u32 ctrl;
};
@@ -427,7 +432,12 @@ struct dma_desc {
#define MACB_TX_USED_OFFSET 31
#define MACB_TX_USED_SIZE 1
-struct ring_info {
+/**
+ * struct macb_tx_skb - data about an skb which is being transmitted
+ * @skb: skb currently being transmitted
+ * @mapping: DMA address of the skb's data buffer
+ */
+struct macb_tx_skb {
struct sk_buff *skb;
dma_addr_t mapping;
};
@@ -512,12 +522,12 @@ struct macb {
void __iomem *regs;
unsigned int rx_tail;
- struct dma_desc *rx_ring;
+ struct macb_dma_desc *rx_ring;
void *rx_buffers;
unsigned int tx_head, tx_tail;
- struct dma_desc *tx_ring;
- struct ring_info *tx_skb;
+ struct macb_dma_desc *tx_ring;
+ struct macb_tx_skb *tx_skb;
spinlock_t lock;
struct platform_device *pdev;
@@ -535,8 +545,6 @@ struct macb {
dma_addr_t tx_ring_dma;
dma_addr_t rx_buffers_dma;
- unsigned int rx_pending, tx_pending;
-
struct mii_bus *mii_bus;
struct phy_device *phy_dev;
unsigned int link;
--
1.8.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox