* [PATCH 02/10] gpio: pxa: identify ed mask reg with platform data
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-1-git-send-email-haojian.zhuang@linaro.org>
Avoid to judge whether edge mask register exists by CPU. Use platform
data to identify it instead. The gpio edge mask register exists in MMP
series SoC.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
arch/arm/mach-mmp/aspenite.c | 7 +++++++
arch/arm/mach-mmp/avengers_lite.c | 7 +++++++
arch/arm/mach-mmp/brownstone.c | 7 +++++++
arch/arm/mach-mmp/flint.c | 7 +++++++
arch/arm/mach-mmp/gplugd.c | 7 +++++++
arch/arm/mach-mmp/tavorevb.c | 7 +++++++
arch/arm/mach-mmp/teton_bga.c | 7 +++++++
arch/arm/mach-mmp/ttc_dkb.c | 7 +++++++
drivers/gpio/gpio-pxa.c | 11 ++++++++++-
include/linux/gpio-pxa.h | 1 +
10 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index e5dba9c..ee1fb62 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -9,6 +9,7 @@
* publishhed by the Free Software Foundation.
*/
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
@@ -110,6 +111,10 @@ static unsigned long common_pin_config[] __initdata = {
GPIO121_KP_MKIN4,
};
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .ed_mask = 1,
+};
+
static struct smc91x_platdata smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
@@ -248,6 +253,8 @@ static void __init common_init(void)
pxa168_add_nand(&aspenite_nand_info);
pxa168_add_fb(&aspenite_lcd_info);
pxa168_add_keypad(&aspenite_keypad_info);
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa168_device_gpio);
/* off-chip devices */
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index 603542a..8b4b1ae 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/gpio-pxa.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
@@ -32,12 +33,18 @@ static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
GPIO89_UART2_RXD,
};
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .ed_mask = 1,
+};
+
static void __init avengers_lite_init(void)
{
mfp_config(ARRAY_AND_SIZE(avengers_lite_pin_config_V16F));
/* on-chip devices */
pxa168_add_uart(2);
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa168_device_gpio);
}
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index 5cb769c..0454488 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/gpio-pxa.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/max8649.h>
#include <linux/regulator/fixed.h>
@@ -104,6 +105,10 @@ static unsigned long brownstone_pin_config[] __initdata = {
GPIO89_GPIO,
};
+static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+ .ed_mask = 1,
+};
+
static struct regulator_consumer_supply max8649_supply[] = {
REGULATOR_SUPPLY("vcc_core", NULL),
};
@@ -202,6 +207,8 @@ static void __init brownstone_init(void)
/* on-chip devices */
mmp2_add_uart(1);
mmp2_add_uart(3);
+ platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&mmp2_device_gpio);
mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 8059cc0..7ec873c 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -16,6 +16,7 @@
#include <linux/smc91x.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/interrupt.h>
#include <asm/mach-types.h>
@@ -77,6 +78,10 @@ static unsigned long flint_pin_config[] __initdata = {
GPIO160_ND_RDY1,
};
+static struct pxa_gpio_platform_data mmp2_gpio_pdata = {
+ .ed_mask = 1,
+};
+
static struct smc91x_platdata flint_smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
@@ -111,6 +116,8 @@ static void __init flint_init(void)
/* on-chip devices */
mmp2_add_uart(1);
mmp2_add_uart(2);
+ platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&mmp2_device_gpio);
/* off-chip devices */
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 5c3d61e..d592041 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@@ -127,6 +128,10 @@ static unsigned long gplugd_pin_config[] __initdata = {
GPIO116_I2S_TXD
};
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .ed_mask = 1,
+};
+
static struct i2c_board_info gplugd_i2c_board_info[] = {
{
.type = "isl1208",
@@ -185,6 +190,8 @@ static void __init gplugd_init(void)
pxa168_add_uart(3);
pxa168_add_ssp(1);
pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa168_device_gpio);
pxa168_add_eth(&gplugd_eth_platform_data);
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index b28f908..a855e69 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -8,6 +8,7 @@
* publishhed by the Free Software Foundation.
*/
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
@@ -60,6 +61,10 @@ static unsigned long tavorevb_pin_config[] __initdata = {
DF_RDY0_DF_RDY0,
};
+static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+ .ed_mask = 1,
+};
+
static struct smc91x_platdata tavorevb_smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
@@ -93,6 +98,8 @@ static void __init tavorevb_init(void)
/* on-chip devices */
pxa910_add_uart(1);
+ platform_device_add_data(&pxa910_device_gpio, &ttc_dkb_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa910_device_gpio);
/* off-chip devices */
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index dd30ea7..9f64f37 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/input.h>
#include <linux/platform_data/keypad-pxa27x.h>
#include <linux/i2c.h>
@@ -49,6 +50,10 @@ static unsigned long teton_bga_pin_config[] __initdata = {
GPIO78_GPIO,
};
+static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
+ .ed_mask = 1,
+};
+
static unsigned int teton_bga_matrix_key_map[] = {
KEY(0, 6, KEY_ESC),
KEY(0, 7, KEY_ENTER),
@@ -79,6 +84,8 @@ static void __init teton_bga_init(void)
pxa168_add_uart(1);
pxa168_add_keypad(&teton_bga_keypad_info);
pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info));
+ platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_device_register(&pxa168_device_gpio);
}
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index ce55fd8..74081cd 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/i2c/pca953x.h>
#include <linux/gpio.h>
+#include <linux/gpio-pxa.h>
#include <linux/mfd/88pm860x.h>
#include <linux/platform_data/mv_usb.h>
@@ -73,6 +74,10 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
DF_RDY0_DF_RDY0,
};
+static struct pxa_gpio_platform_data ttc_dkb_gpio_pdata = {
+ .ed_mask = 1,
+};
+
static struct mtd_partition ttc_dkb_onenand_partitions[] = {
{
.name = "bootloader",
@@ -196,6 +201,8 @@ static void __init ttc_dkb_init(void)
/* off-chip devices */
pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info));
+ platform_device_add_data(&pxa910_device_gpio, &ttc_dkb_gpio_pdata,
+ sizeof(struct pxa_gpio_platform_data));
platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));
#ifdef CONFIG_USB_MV_UDC
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 9cc108d..8e66c6b 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -493,6 +493,7 @@ const struct irq_domain_ops pxa_irq_domain_ops = {
static int pxa_gpio_probe_dt(struct platform_device *pdev)
{
int ret, nr_banks, nr_gpios;
+ struct pxa_gpio_platform_data *pdata;
struct device_node *prev, *next, *np = pdev->dev.of_node;
const struct of_device_id *of_id =
of_match_device(pxa_gpio_dt_ids, &pdev->dev);
@@ -501,6 +502,14 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
dev_err(&pdev->dev, "Failed to find gpio controller\n");
return -EFAULT;
}
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ ret = of_find_property(np, "marvell,gpio-ed-mask", NULL);
+ if (ret)
+ pdata->ed_mask = 1;
+ /* set the platform data */
+ pdev->dev.platform_data = pdata;
gpio_type = (int)of_id->data;
next = of_get_next_child(np, NULL);
@@ -604,7 +613,7 @@ static int pxa_gpio_probe(struct platform_device *pdev)
writel_relaxed(0, c->regbase + GRER_OFFSET);
writel_relaxed(~0,c->regbase + GEDR_OFFSET);
/* unmask GPIO edge detect for AP side */
- if (gpio_is_mmp_type(gpio_type))
+ if (info->ed_mask)
writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
}
diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h
index d755b28..d88d6e3 100644
--- a/include/linux/gpio-pxa.h
+++ b/include/linux/gpio-pxa.h
@@ -14,6 +14,7 @@ extern int pxa_last_gpio;
extern int pxa_irq_to_gpio(int irq);
struct pxa_gpio_platform_data {
+ unsigned ed_mask; /* not 0 means ed_mask reg is available */
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 01/10] gpio: pxa: set initcall level to module init
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-1-git-send-email-haojian.zhuang@linaro.org>
gpio & pinctrl driver are used together. The pinctrl driver is already
launched before gpio driver in Makefile. So set gpio driver to module
init level. Otherwise, the sequence will be inverted.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
drivers/gpio/gpio-pxa.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 8325f58..9cc108d 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -642,12 +642,7 @@ static struct platform_driver pxa_gpio_driver = {
.of_match_table = of_match_ptr(pxa_gpio_dt_ids),
},
};
-
-static int __init pxa_gpio_init(void)
-{
- return platform_driver_register(&pxa_gpio_driver);
-}
-postcore_initcall(pxa_gpio_init);
+module_platform_driver(pxa_gpio_driver);
#ifdef CONFIG_PM
static int pxa_gpio_suspend(void)
--
1.7.10.4
^ permalink raw reply related
* [PATCH 00/10] rework gpio pxa driver for pinctrl
From: Haojian Zhuang @ 2013-01-23 8:25 UTC (permalink / raw)
To: linux-arm-kernel
Remove all cpu depend macro. Bind gpio pxa driver with pinctrl driver.
^ permalink raw reply
* [PATCH] mtd: gpmi: fix a dereferencing freed memory error
From: Huang Shijie @ 2013-01-23 8:20 UTC (permalink / raw)
To: linux-arm-kernel
The patch "490e280 mtd: gpmi-nand: Convert to module_platform_driver()"
introduced a "dereferencing freed memory" error.
This patch fixes it.
Signed-off-by: Huang Shijie <b32955@freescale.com>
---
drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 631564d..38c8b8b 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1657,8 +1657,8 @@ exit_nfc_init:
release_resources(this);
exit_acquire_resources:
platform_set_drvdata(pdev, NULL);
- kfree(this);
dev_err(this->dev, "driver registration failed: %d\n", ret);
+ kfree(this);
return ret;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 23/24] ab8500-bm: Fix minor niggles experienced during testing
From: Lee Jones @ 2013-01-23 8:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130123062506.GA20858@lizard.gateway.2wire.net>
On Tue, 22 Jan 2013, Anton Vorontsov wrote:
> On Tue, Jan 22, 2013 at 09:27:17AM +0000, Lee Jones wrote:
> > On Mon, 21 Jan 2013, Anton Vorontsov wrote:
> >
> > > On Mon, Jan 21, 2013 at 12:03:59PM +0000, Lee Jones wrote:
> > > > When compile testing the new AB8500 Battery Management changes
> > > > due for inclusion into upstream, there were a few minor niggles
> > > > which required repairing, or adapting for use against the
> > > > Mainline kernel. This patch is a collection of them all.
> > >
> > > No. This is the third time I'm saying it: the last time I checked, this is
> > > not how we do development in the mainline.
> >
> > Okay, all of these changes have now been fixed-up into the patches
> > which caused the issues. I have also added Stable to the patch you
> > requested it on.
> >
> > How would you like to proceed? Do you want a pull-request, or for me
> > to send the patches to the list again?
>
> Either way will work.
>
> Thanks!
>
> Anton
>
> p.s. I took another look at the patches, and noticed one issue that is
> constantly there: you place your signed-off-by line on top of everyones',
> but that's wrong. Sign offs are going downwards, not upwards. This is
> quite important since the lines encode how the code "travels" between
> companies and submitters. Currently, one might assume that the origin of
> the code is always Linaro, which is not quite true. (And 'From:' doesn't
> always mean the author, fwiw.)
Thanks for the info. I'll move them all and re-submit.
--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v3 2/2] mtd: vt8500: Add support for Wondermedia Serial Flash Controller
From: Tony Prisk @ 2013-01-23 8:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358928068-12417-1-git-send-email-linux@prisktech.co.nz>
This patch adds support for the Wondermedia serial flash controller
found on WM8505, WM8650 and WM8850 SoCs.
Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
drivers/mtd/devices/Kconfig | 10 +
drivers/mtd/devices/Makefile | 3 +-
drivers/mtd/devices/wmt_sflash.c | 585 ++++++++++++++++++++++++++++++++++++++
3 files changed, 597 insertions(+), 1 deletion(-)
create mode 100644 drivers/mtd/devices/wmt_sflash.c
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 27f80cd..dbabb08 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -128,6 +128,16 @@ config MTD_BCM47XXSFLASH
registered by bcma as platform devices. This enables driver for
serial flash memories (only read-only mode is implemented).
+config MTD_WMT_SFLASH
+ tristate "WonderMedia Serial Flash Support"
+ depends on ARCH_VT8500
+ help
+ Enable this option to provide support for the Wondermedia SoC serial
+ flash controller.
+
+ Select M to build this driver as a module. The module will be called
+ 'wmt_sflash'.
+
config MTD_SLRAM
tristate "Uncached system RAM"
help
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 395733a..79af2f6 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
obj-$(CONFIG_MTD_M25P80) += m25p80.o
obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
obj-$(CONFIG_MTD_SST25L) += sst25l.o
+obj-$(CONFIG_MTD_WMT_SFLASH) += wmt_sflash.o flash_jedec.o
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
-CFLAGS_docg3.o += -I$(src)
\ No newline at end of file
+CFLAGS_docg3.o += -I$(src)
diff --git a/drivers/mtd/devices/wmt_sflash.c b/drivers/mtd/devices/wmt_sflash.c
new file mode 100644
index 0000000..d3adf7a
--- /dev/null
+++ b/drivers/mtd/devices/wmt_sflash.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+
+#include <linux/mtd/mtd.h>
+
+#include "flash_jedec.h"
+
+
+/* controller only supports erase size of 64KB */
+#define WMT_ERASESIZE 0x10000
+
+/* Serial Flash controller register offsets */
+#define SF_CHIP_SEL_0_CFG 0x000
+#define SF_CHIP_SEL_1_CFG 0x008
+#define SF_SPI_INTF_CFG 0x040
+#define SF_SPI_RD_WR_CTR 0x050
+#define SF_SPI_WR_EN_CTR 0x060
+#define SF_SPI_ER_CTR 0x070
+#define SF_SPI_ER_START_ADDR 0x074
+#define SF_SPI_ERROR_STATUS 0x080
+#define SF_SPI_MEM_0_SR_ACC 0x100
+#define SF_SPI_MEM_1_SR_ACC 0x110
+#define SF_SPI_PDWN_CTR_0 0x180
+#define SF_SPI_PDWN_CTR_1 0x190
+#define SF_SPI_PROG_CMD_CTR 0x200
+#define SF_SPI_USER_CMD_VAL 0x210
+#define SF_SPI_PROG_CMD_WBF 0x300 /* 64 bytes */
+#define SF_SPI_PROG_CMD_RBF 0x380 /* 64 bytes */
+
+/* SF_SPI_WR_EN_CTR bit fields */
+#define SF_CS0_WR_EN BIT(0)
+#define SF_CS1_WR_EN BIT(1)
+
+/* SF_SPI_ER_CTR bit fields */
+#define SF_SEC_ER_EN BIT(31)
+
+/* SF_SPI_ERROR_STATUS bit fields */
+#define SF_ERR_TIMEOUT BIT(31)
+#define SF_ERR_WR_PROT_ERR BIT(5)
+#define SF_ERR_MEM_REGION_ERR BIT(4)
+#define SF_ERR_PWR_DWN_ACC_ERR BIT(3)
+#define SF_ERR_PCMD_OP_ERR BIT(2)
+#define SF_ERR_PCMD_ACC_ERR BIT(1)
+#define SF_ERR_MASLOCK_ERR BIT(0)
+
+/*
+ * Serial Flash device manufacturers
+ * Please keep sorted by manufacturers ID
+ */
+#define MFR_SPANSION 0x01
+#define MFR_EON 0x1C
+#define MFR_ATMEL 0x1F
+#define MFR_NUMONYX 0x20
+#define MFR_FUDAN 0xA1
+#define MFR_SST 0xBF
+#define MFR_MXIC 0xC2
+#define MFR_WINBOND 0xEF
+
+/*
+ * SF Device Models
+ * Please keep in the same order as the manufacturers table
+ */
+
+/* Spansion */
+#define SPAN_FL016A 0x0214 /* 2 MB */
+#define SPAN_FL064A 0x0216 /* 8 MB */
+
+/* Eon */
+#define EON_25P16 0x2015 /* 2 MB */
+#define EON_25P64 0x2017 /* 8 MB */
+#define EON_25F40 0x3113 /* 512 KB */
+#define EON_25F16 0x3115 /* 2 MB */
+
+/* Atmel */
+#define AT_25DF041A 0x4401 /* 512KB */
+
+/* Numonyx */
+#define NX_25P16 0x2015 /* 2 MB */
+#define NX_25P64 0x2017 /* 8 MB */
+
+/* Fudan Microelectronics Group */
+#define FM_25F04 0x3113 /* 512 KB */
+
+/* SST */
+#define SST_VF016B 0x2541 /* 2 MB */
+
+/* MXIC */
+#define MX_L512 0x2010 /* 64 KB , 4KB*/
+#define MX_L4005A 0x2013 /* 512 KB */
+#define MX_L1605D 0x2015 /* 2 MB */
+#define MX_L3205D 0x2016 /* 4 MB */
+#define MX_L6405D 0x2017 /* 8 MB */
+#define MX_L1635D 0x2415 /* 2 MB */
+#define MX_L3235D 0x5E16 /* 4 MB */
+#define MX_L12805D 0x2018 /* 16 MB */
+
+/* WinBond */
+#define WB_W25X40BV 0x3013 /* 512 KB */
+#define WB_X16A 0x3015 /* 2 MB */
+#define WB_X32 0x3016 /* 4 MB */
+#define WB_X64 0x3017 /* 8 MB */
+
+
+#define SF_ID(mfr, mdl) ((mfr << 16) | mdl)
+
+#define FLASH_UNKNOWN 0x00ffffff
+
+struct wmt_sf_chip {
+ u32 id;
+ u32 size;
+ u32 addr_phys;
+ u32 ccr;
+};
+
+struct wmt_sf_data {
+ struct mtd_info *sf_mtd;
+ struct clk *sf_clk;
+ struct device *dev;
+
+ struct wmt_sf_chip chip[2];
+
+ void __iomem *base; /* register virt base */
+
+ void __iomem *sf_base_virt; /* mem-mapped sf virt base */
+ u32 sf_base_phys; /* mem-mapped sf phys base */
+ u32 sf_total_size;
+};
+
+static void sf_calc_ccr(struct wmt_sf_chip *chip)
+{
+ unsigned int cnt = 0, size;
+
+ size = chip->size;
+ while (size) {
+ size >>= 1;
+ cnt++;
+ }
+ cnt -= 16;
+ cnt = cnt << 8;
+ chip->ccr = (chip->addr_phys | cnt);
+}
+
+static int wmt_sf_init_hw(struct wmt_sf_data *info)
+{
+ u32 strap;
+ u32 phys_addr;
+ struct device_node *np;
+ struct flash_device_info *flash;
+ void __iomem *gpio_base;
+
+ np = of_find_compatible_node(NULL, NULL, "wm,wm8650-gpio");
+ if (!np) {
+ dev_err(info->dev, "Unable to find GPIO node\n");
+ return -1;
+ }
+
+ gpio_base = of_iomap(np, 0);
+ if (!gpio_base) {
+ dev_err(info->dev, "Failed to map gpio memory\n");
+ return -1;
+ }
+
+ strap = readl_relaxed(gpio_base + 0x100);
+ iounmap(gpio_base);
+
+ if ((strap & 0x06) == 0) {
+ phys_addr = 0xFFFFFFFF;
+ writel(0x00000011, info->base + SF_SPI_RD_WR_CTR);
+ writel(0xFF800800, info->base + SF_CHIP_SEL_0_CFG);
+ writel(0x00030000, info->base + SF_SPI_INTF_CFG);
+ } else {
+ phys_addr = 0xEFFFFFFF;
+ writel(0x00000011, info->base + SF_SPI_RD_WR_CTR);
+ writel(0xEF800800, info->base + SF_CHIP_SEL_0_CFG);
+ writel(0x00030000, info->base + SF_SPI_INTF_CFG);
+ }
+
+ info->chip[0].id = FLASH_UNKNOWN;
+ info->chip[1].id = FLASH_UNKNOWN;
+
+ /* Read serial flash ID */
+ writel(0x11, info->base + SF_SPI_RD_WR_CTR);
+ info->chip[0].id = readl(info->base + SF_SPI_MEM_0_SR_ACC);
+ writel(0x01, info->base + SF_SPI_RD_WR_CTR);
+
+ writel(0x11, info->base + SF_SPI_RD_WR_CTR);
+ info->chip[1].id = readl(info->base + SF_SPI_MEM_1_SR_ACC);
+ writel(0x01, info->base + SF_SPI_RD_WR_CTR);
+
+ flash = jedec_match_device(info->chip[0].id);
+ if (IS_ERR(flash)) {
+ dev_err(info->dev, "Unknown flash id (%08x)\n",
+ info->chip[0].id);
+ return -1;
+ }
+
+ info->chip[0].size = flash->size_kb * 1024;
+ info->chip[0].addr_phys = phys_addr - info->chip[0].size + 1;
+ if (info->chip[0].addr_phys & 0xffff) {
+ dev_err(info->dev, "Chip 0 start address must align to 64KB\n");
+ return -1;
+ }
+ info->sf_base_phys = info->chip[0].addr_phys;
+ info->sf_total_size = info->chip[0].size;
+ pr_info("SFC: Chip 0 @ %08x (size: %d)\n", info->chip[0].addr_phys,
+ info->chip[0].size);
+
+ sf_calc_ccr(&info->chip[0]);
+ writel(info->chip[0].ccr, info->base + SF_CHIP_SEL_0_CFG);
+
+ if (info->chip[1].id != FLASH_UNKNOWN) {
+ flash = jedec_match_device(info->chip[1].id);
+ if (IS_ERR(flash)) {
+ dev_err(info->dev, "Unknown flash id (%08x)\n",
+ info->chip[1].id);
+ return -1;
+ }
+
+ info->chip[0].size = flash->size_kb * 1024;
+ info->chip[1].addr_phys = info->chip[0].addr_phys -
+ info->chip[1].size;
+ if (info->chip[1].addr_phys & 0xffff) {
+ dev_err(info->dev, "Chip 1 start address must align to 64KB\n");
+ info->chip[1].id = FLASH_UNKNOWN;
+ return 0;
+ }
+ info->sf_base_phys = info->chip[1].addr_phys;
+ info->sf_total_size += info->chip[1].size;
+ pr_info("SFC: Chip 1 @ %08x (size: %d)\n",
+ info->chip[1].addr_phys, info->chip[1].size);
+
+ sf_calc_ccr(&info->chip[1]);
+ writel(info->chip[1].ccr, info->base + SF_CHIP_SEL_1_CFG);
+ }
+
+ return 0;
+}
+
+static int sf_check_error(struct device *dev, u32 code)
+{
+ if (code & SF_ERR_TIMEOUT) {
+ dev_err(dev, "Serial flash timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ if (code & SF_ERR_WR_PROT_ERR) {
+ dev_err(dev, "Serial flash write-protected\n");
+ return -EIO;
+ }
+
+ if (code & SF_ERR_MEM_REGION_ERR) {
+ dev_err(dev, "Serial flash memory region error\n");
+ return -EIO;
+ }
+
+ if (code & SF_ERR_PWR_DWN_ACC_ERR) {
+ dev_err(dev, "Serial flash power down access error\n");
+ return -EIO;
+ }
+
+ if (code & SF_ERR_PCMD_OP_ERR) {
+ dev_err(dev, "Serial flash program CMD OP error\n");
+ return -EIO;
+ }
+
+ if (code & SF_ERR_PCMD_ACC_ERR) {
+ dev_err(dev, "Serial flash program CMD OP access error\n");
+ return -EIO;
+ }
+
+ if (code & SF_ERR_MASLOCK_ERR) {
+ dev_err(dev, "Serial flash master lock error\n");
+ return -EIO;
+ }
+
+ /* no error */
+ return 0;
+}
+
+static int sf_spi_read_status(struct wmt_sf_data *info, int chip)
+{
+ u32 timeout = 0x30000000;
+ u32 temp;
+ int err;
+
+ do {
+ if (chip == 0)
+ temp = readl_relaxed(info->base + SF_SPI_MEM_0_SR_ACC);
+ else
+ temp = readl_relaxed(info->base + SF_SPI_MEM_1_SR_ACC);
+
+ if ((temp & 0x1) == 0x0)
+ break;
+
+ err = sf_check_error(info->dev,
+ readl(info->base + SF_SPI_ERROR_STATUS));
+ if (err) {
+ writel(0x3f, info->base + SF_SPI_ERROR_STATUS);
+ return err;
+ }
+ timeout--;
+ } while (timeout);
+
+ if (timeout == 0) {
+ dev_err(info->dev, "spi request timed-out\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int sf_sector_erase(struct wmt_sf_data *info, u32 addr)
+{
+ int chip;
+ u32 val;
+
+ if ((info->sf_base_phys + addr) < info->chip[0].addr_phys) {
+ chip = 0;
+ writel(SF_CS0_WR_EN, info->base + SF_SPI_WR_EN_CTR);
+ } else {
+ chip = 1;
+ writel(SF_CS1_WR_EN, info->base + SF_SPI_WR_EN_CTR);
+ }
+
+ addr &= ~(info->sf_mtd->erasesize - 1);
+ writel(addr, info->base + SF_SPI_ER_START_ADDR);
+
+ writel(SF_SEC_ER_EN, info->base + SF_SPI_ER_CTR);
+
+ val = sf_spi_read_status(info, chip);
+
+ writel(0, info->base + SF_SPI_WR_EN_CTR);
+ return val;
+}
+
+static int sf_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct wmt_sf_data *info = mtd->priv;
+ int ret;
+
+ ret = clk_enable(info->sf_clk);
+ if (ret)
+ return ret;
+
+ ret = sf_sector_erase(info, (u32)instr->addr);
+ if (ret) {
+ clk_disable(info->sf_clk);
+ return ret;
+ }
+
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ clk_disable(info->sf_clk);
+ return 0;
+}
+
+static int sf_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct wmt_sf_data *info = mtd->priv;
+ int ret;
+
+ ret = clk_enable(info->sf_clk);
+ if (ret)
+ return ret;
+
+ if (sf_spi_read_status(info, 0))
+ return -EBUSY;
+ if (sf_spi_read_status(info, 1))
+ return -EBUSY;
+
+ if (from + len > mtd->size) {
+ dev_err(info->dev, "Request out of bounds (from=%llu, len=%d)\n",
+ from, len);
+ return -EINVAL;
+ }
+
+ memcpy_fromio(buf, info->sf_base_virt + from, len);
+ *retlen = len;
+
+ clk_disable(info->sf_clk);
+ return 0;
+}
+
+static int sf_sector_write(struct wmt_sf_data *info, loff_t to, size_t len,
+ const u_char *buf)
+{
+ int ret;
+ int data_size;
+ u32 count;
+ u32 addr_to = (u32)info->sf_base_virt + to;
+
+ ret = clk_enable(info->sf_clk);
+ if (ret)
+ return ret;
+
+ if (sf_spi_read_status(info, 0))
+ return -EBUSY;
+ if (sf_spi_read_status(info, 1))
+ return -EBUSY;
+
+ writel(SF_CS0_WR_EN | SF_CS1_WR_EN, info->base + SF_SPI_WR_EN_CTR);
+
+ count = 0;
+ while (len) {
+ data_size = (len >= 4) ? 4 : 1;
+ memcpy_toio(((void *)(addr_to + count)), buf + count,
+ data_size);
+ count += data_size;
+ len -= data_size;
+
+ if (len) {
+ data_size = (len >= 4) ? 4 : 1;
+ memcpy_toio(((void *)(addr_to + count)), buf + count,
+ data_size);
+ count += data_size;
+ len -= data_size;
+ }
+
+ ret = sf_spi_read_status(info, 0);
+ if (ret) {
+ clk_disable(info->sf_clk);
+ return ret;
+ }
+ }
+
+ writel(0, info->base + SF_SPI_WR_EN_CTR);
+
+ clk_disable(info->sf_clk);
+
+ return count;
+}
+
+static int sf_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct wmt_sf_data *info = mtd->priv;
+
+ *retlen = sf_sector_write(info, to, len, buf);
+
+ return 0;
+}
+
+static int mtdsf_init_device(struct device *dev, struct mtd_info *mtd,
+ unsigned long size, char *name)
+{
+ mtd->name = name;
+ mtd->type = MTD_NORFLASH;
+ mtd->flags = MTD_CAP_NORFLASH;
+ mtd->size = size;
+ mtd->erasesize = WMT_ERASESIZE;
+ mtd->owner = THIS_MODULE;
+ mtd->_erase = sf_erase;
+ mtd->_read = sf_read;
+ mtd->_write = sf_write;
+ mtd->writesize = 1;
+
+ if (mtd_device_register(mtd, NULL, 0)) {
+ dev_err(dev, "Erroring adding MTD device\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int wmt_sf_probe(struct platform_device *pdev)
+{
+ struct wmt_sf_data *info;
+ struct device_node *np = pdev->dev.of_node;
+ int err;
+
+ if (!np) {
+ dev_err(&pdev->dev, "Invalid devicetree node\n");
+ return -EINVAL;
+ }
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "Failed to get memory for SF info\n");
+ return -ENOMEM;
+ }
+
+ info->dev = &pdev->dev;
+
+ info->base = of_iomap(np, 0);
+ if (!info->base) {
+ dev_err(&pdev->dev, "Failed to map register memory\n");
+ return -ENOMEM;
+ }
+
+ info->sf_clk = of_clk_get(np, 0);
+ if (!info->sf_clk) {
+ dev_err(&pdev->dev, "Failed to get clock from device tree\n");
+ return -EINVAL;
+ }
+
+ err = clk_prepare_enable(info->sf_clk);
+ if (err)
+ return err;
+
+ err = wmt_sf_init_hw(info);
+ clk_disable(info->sf_clk);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to initialize SF hardware\n");
+ return -EIO;
+ }
+
+ info->sf_base_virt = devm_ioremap(&pdev->dev, info->sf_base_phys,
+ info->sf_total_size);
+ if (!info->sf_base_virt) {
+ dev_err(&pdev->dev, "Failed to map serial flash memory\n");
+ return -ENOMEM;
+ }
+
+ info->sf_mtd = devm_kzalloc(&pdev->dev, sizeof(struct mtd_info),
+ GFP_KERNEL);
+ if (!info->sf_mtd) {
+ dev_err(&pdev->dev, "Failed to allocate SFMTD memory\n");
+ return -ENOMEM;
+ }
+
+ err = mtdsf_init_device(info->dev, info->sf_mtd, info->sf_total_size,
+ "Wondermedia SF Device");
+ if (err)
+ return err;
+
+ info->sf_mtd->priv = info;
+ dev_set_drvdata(&pdev->dev, info);
+
+ pr_info("Wondermedia Serial Flash Controller initialized\n");
+
+ return 0;
+}
+
+static int wmt_sf_remove(struct platform_device *pdev)
+{
+ struct wmt_sf_data *info = dev_get_drvdata(&pdev->dev);
+
+ mtd_device_unregister(info->sf_mtd);
+
+ return 0;
+}
+
+static const struct of_device_id wmt_dt_ids[] = {
+ { .compatible = "wm,wm8505-sf", },
+ {}
+};
+
+static struct platform_driver wmt_sf_driver = {
+ .probe = wmt_sf_probe,
+ .remove = wmt_sf_remove,
+ .driver = {
+ .name = "wmt-sf",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(wmt_dt_ids),
+ },
+};
+
+module_platform_driver(wmt_sf_driver);
+
+MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
+MODULE_DESCRIPTION("Wondermedia SoC Serial Flash driver");
+MODULE_LICENSE("GPL v2");
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 1/2] mtd: Add a common JEDEC flash device table
From: Tony Prisk @ 2013-01-23 8:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358928068-12417-1-git-send-email-linux@prisktech.co.nz>
This patch adds a common JEDEC flash device table which can be
expanded on as more features are required.
A simple match function is also included to query the table for
a match based on the JEDEC id.
Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
drivers/mtd/devices/flash_jedec.c | 96 +++++++++++++++++++++++++++++++++++++
drivers/mtd/devices/flash_jedec.h | 30 ++++++++++++
2 files changed, 126 insertions(+)
create mode 100644 drivers/mtd/devices/flash_jedec.c
create mode 100644 drivers/mtd/devices/flash_jedec.h
diff --git a/drivers/mtd/devices/flash_jedec.c b/drivers/mtd/devices/flash_jedec.c
new file mode 100644
index 0000000..c0b2272
--- /dev/null
+++ b/drivers/mtd/devices/flash_jedec.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright Tony Prisk <linux@prisktech.co.nz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "flash_jedec.h"
+
+/*
+ * Device Manufacturer IDs
+ * Please keep sorted by manufacturer ID
+ */
+#define MFR_SPANSION 0X01
+#define MFR_EON 0X1C
+#define MFR_ATMEL 0X1F
+#define MFR_MICRON 0X20 /* Also Numonyx & STM */
+#define MFR_INTEL 0x89
+#define MFR_FUDAN 0XA1
+#define MFR_SST 0XBF
+#define MFR_MXIC 0XC2
+#define MFR_WINBOND 0XEF
+
+#define _ID(m, d) ((m << 16) | d)
+
+/*
+ * Flash device information
+ * Please keep sorted by manufacturer id, then device id
+ */
+static struct flash_device_info flash_devices[] = {
+ /* Spansion */
+ { "s25fl016", _ID(MFR_SPANSION, 0x0214), 2048 },
+ { "s25fl064", _ID(MFR_SPANSION, 0x0216), 8192 },
+ /* EON */
+ { "en25p16", _ID(MFR_EON, 0x2015), 2048 },
+ { "en25p64", _ID(MFR_EON, 0x2017), 8192 },
+ { "en25f40", _ID(MFR_EON, 0x3113), 512 },
+ { "en25f16", _ID(MFR_EON, 0x3115), 2048 },
+ /* ATMEL */
+ { "at25df041a", _ID(MFR_ATMEL, 0x4401), 512 },
+ /* Micron, STM & Numonyx */
+ { "stm25p16", _ID(MFR_MICRON, 0x2015), 2048 },
+ { "stm25p64", _ID(MFR_MICRON, 0x2017), 8192 },
+ /* Fudan */
+ { "fm25f04", _ID(MFR_FUDAN, 0x3113), 512 },
+ /* SST */
+ { "sst25vf016b", _ID(MFR_SST, 0x2541), 2048 },
+ /* Macronix - MXIC */
+ { "mx25l512", _ID(MFR_MXIC, 0x2010), 64 },
+ { "mx25l4005", _ID(MFR_MXIC, 0x2013), 512 },
+ { "mx25l1605", _ID(MFR_MXIC, 0x2015), 2048 },
+ { "mx25l3205", _ID(MFR_MXIC, 0x2016), 4096 },
+ { "mx25l6405", _ID(MFR_MXIC, 0x2017), 8192 },
+ { "mx25l12805", _ID(MFR_MXIC, 0x2018), 16384 },
+ { "mx25l1635", _ID(MFR_MXIC, 0x2415), 2048 },
+ { "mx25l3235", _ID(MFR_MXIC, 0x5E16), 4096 },
+ /* Winbond */
+ { "w25x40", _ID(MFR_WINBOND, 0x3013), 512 },
+ { "w25x16", _ID(MFR_WINBOND, 0x3015), 2048 },
+ { "w25x32", _ID(MFR_WINBOND, 0x3016), 4096 },
+ { "w25x64", _ID(MFR_WINBOND, 0x3017), 8192 },
+};
+
+/*
+ * jedec_match_device - match a jedec id against the flash_devices table
+ * @jedecid: JEDEC formatted id to match
+ * bits 16..24: manufacturer id
+ * bits 0..15: device id
+ * Returns a valid flash_device_info* or ERR_PTR(-ENODEV) if an entry is
+ * not found
+ */
+struct flash_device_info *jedec_match_device(u32 jedec_id)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(flash_devices); i++)
+ if (flash_devices[i].jedec_id == jedec_id)
+ return &flash_devices[i];
+
+ return ERR_PTR(-ENODEV);
+}
diff --git a/drivers/mtd/devices/flash_jedec.h b/drivers/mtd/devices/flash_jedec.h
new file mode 100644
index 0000000..27b978a
--- /dev/null
+++ b/drivers/mtd/devices/flash_jedec.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright Tony Prisk <linux@prisktech.co.nz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MTD_FLASH_JEDEC
+#define __MTD_FLASH_JEDEC
+
+struct flash_device_info {
+ const char *name;
+ u32 jedec_id;
+ u32 size_kb;
+};
+
+extern struct flash_device_info *jedec_match_device(u32 jedec_id);
+
+#endif
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 0/2] Add Wondermedia Serial Flash controller support
From: Tony Prisk @ 2013-01-23 8:01 UTC (permalink / raw)
To: linux-arm-kernel
v3 Changes:
As requested by Artem Bityutskiy, I have seperated out the flash chip data into
a seperate file (flash_jedec.(h/c)) which should be expandable by other drivers
as needed.
I have also cleared up some of the sparse warnings that were being generated,
but need some help with the last one:
+drivers/mtd/devices/wmt_sflash.c:442:24: warning: cast removes address space of expression [sparse]
which relates to this line:
+ u32 addr_to = (u32)info->sf_base_virt + to;
What is the correct way to get the value of ->sf_base_virt without generating
a sparse warning? sf_base_virt is void __iomem *.
Tony Prisk (2):
mtd: Add a common JEDEC flash device table
mtd: vt8500: Add support for Wondermedia Serial Flash Controller
drivers/mtd/devices/Kconfig | 10 +
drivers/mtd/devices/Makefile | 3 +-
drivers/mtd/devices/flash_jedec.c | 96 ++++++
drivers/mtd/devices/flash_jedec.h | 30 ++
drivers/mtd/devices/wmt_sflash.c | 585 +++++++++++++++++++++++++++++++++++++
5 files changed, 723 insertions(+), 1 deletion(-)
create mode 100644 drivers/mtd/devices/flash_jedec.c
create mode 100644 drivers/mtd/devices/flash_jedec.h
create mode 100644 drivers/mtd/devices/wmt_sflash.c
--
1.7.9.5
^ permalink raw reply
* [PATCH 1/2 net-next] net: fec: add napi support to improve proformance
From: Frank Li @ 2013-01-23 8:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130123075323.GU1906@pengutronix.de>
> Why do you want to make it configurable anyway? So far no other driver
> seems to need this. My suggestion is to make it unconfigurable.
>
> For adding properties like this to the devicetree remember that they
> should be OS agnostic. napi is a implementation detail relevant only
> for Linux. And even Linux may decide to drop napi support in favour for
> something better in the future.
>
Okay, I will remove such config in v2 version.
best regards
Frank Li
^ permalink raw reply
* [PATCH 2/2] ARM: dts: imx51-babbage: Add at24c512b eeprom support
From: Liu Ying @ 2013-01-23 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130123075525.GV1906@pengutronix.de>
2013/1/23 Sascha Hauer <s.hauer@pengutronix.de>:
> On Wed, Jan 23, 2013 at 03:51:12PM +0800, Liu Ying wrote:
>> 2013/1/23 Sascha Hauer <s.hauer@pengutronix.de>:
>> > On Wed, Jan 23, 2013 at 02:32:44PM +0800, Liu Ying wrote:
>> >> This patch adds at24c512b i2c device to the device tree
>> >> along with the necessary i2c device node and pinctrl
>> >> settings for i2c bus.
>> >> The eeprom chip is populated on the accessory board of
>> >> the imx51-babbage board.
>> >
>> > Given that it's optional should the binding be here anyway? I don't have
>> > this accessory board and this may conflict with the boards other people
>> > have connected on this port.
>> >
>> > Sascha
>>
>> Understand your concern. Is there any way to handle this? How can we support
>> the present accessory board correctly? More generally, not all main boards can
>> figure out what kind of accessory board is attached to them, at least, some main
>> boards can only figure out limited number of accessory boards by using some ways
>> of board ID check.
>
> We don't have support for such things atm. We'll have to wait for
>
> OF: Introduce DT overlay support.
>
> Pantelis Antoniou is working on this currently.
>
> Sascha
>
>
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Good to know that. Thanks.
--
Best Regards,
Liu Ying
^ permalink raw reply
* [PATCH 1/2 net-next] net: fec: add napi support to improve proformance
From: Frank Li @ 2013-01-23 7:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130123063744.GA16454@ppwaskie-mobl2.amr.corp.intel.com>
2013/1/23 Waskiewicz Jr, Peter P <peter.p.waskiewicz.jr@intel.com>:
> On Wed, Jan 23, 2013 at 12:12:10PM +0800, Frank Li wrote:
>
> [...]
>
>> diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
>> index f52ba33..8fa420c 100644
>> --- a/drivers/net/ethernet/freescale/fec.c
>> +++ b/drivers/net/ethernet/freescale/fec.c
>> @@ -67,6 +67,8 @@
>> #endif
>>
>> #define DRIVER_NAME "fec"
>> +#define FEC_NAPI_WEIGHT 64
>> +#define INT32_MAX 0x7FFFFFFF
>
> This seems awfully big as an upper-limit to your ISR processing. See below
> for more comments.
>
>>
>> /* Pause frame feild and FIFO threshold */
>> #define FEC_ENET_FCE (1 << 5)
>> @@ -565,6 +567,20 @@ fec_timeout(struct net_device *ndev)
>> }
>>
>> static void
>> +fec_enet_rx_int_is_enabled(struct net_device *ndev, bool enabled)
>> +{
>> + struct fec_enet_private *fep = netdev_priv(ndev);
>> + uint int_events;
>> +
>> + int_events = readl(fep->hwp + FEC_IMASK);
>> + if (enabled)
>> + int_events |= FEC_ENET_RXF;
>> + else
>> + int_events &= ~FEC_ENET_RXF;
>> + writel(int_events, fep->hwp + FEC_IMASK);
>> +}
>> +
>> +static void
>> fec_enet_tx(struct net_device *ndev)
>> {
>> struct fec_enet_private *fep;
>> @@ -656,8 +672,8 @@ fec_enet_tx(struct net_device *ndev)
>> * not been given to the system, we just set the empty indicator,
>> * effectively tossing the packet.
>> */
>> -static void
>> -fec_enet_rx(struct net_device *ndev)
>> +static int
>> +fec_enet_rx(struct net_device *ndev, int budget)
>> {
>> struct fec_enet_private *fep = netdev_priv(ndev);
>> const struct platform_device_id *id_entry =
>> @@ -667,13 +683,12 @@ fec_enet_rx(struct net_device *ndev)
>> struct sk_buff *skb;
>> ushort pkt_len;
>> __u8 *data;
>> + int pkt_received = 0;
>>
>> #ifdef CONFIG_M532x
>> flush_cache_all();
>> #endif
>>
>> - spin_lock(&fep->hw_lock);
>> -
>> /* First, grab all of the stats for the incoming packet.
>> * These get messed up if we get called due to a busy condition.
>> */
>> @@ -681,6 +696,10 @@ fec_enet_rx(struct net_device *ndev)
>>
>> while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
>>
>> + if (pkt_received >= budget)
>> + break;
>> + pkt_received++;
>> +
>
> This seems wrong given how it's called from the ISR when NAPI isn't being
> used. If you have continuous packets coming in, you won't exit your ISR
> and release your spin_lock until you hit INT32_MAX.
I just the keep original execute path if napi disabled.
Original code will progress all packages in queue.
FEC is 1G network, must receive speed around 500Mbps.
CPU speed is much faster than received package.
and RX queue only 8 entry, I think it is impossible to run loop more than 10.
why I set to INT32_MAX is keep the original execute path when napi disable.
INT32_MAX is impossible value to exit loop for this case.
>
>> /* Since we have allocated space to hold a complete frame,
>> * the last indicator should be set.
>> */
>> @@ -796,7 +815,7 @@ rx_processing_done:
>> }
>> fep->cur_rx = bdp;
>>
>> - spin_unlock(&fep->hw_lock);
>> + return pkt_received;
>> }
>>
>> static irqreturn_t
>> @@ -805,6 +824,7 @@ fec_enet_interrupt(int irq, void *dev_id)
>> struct net_device *ndev = dev_id;
>> struct fec_enet_private *fep = netdev_priv(ndev);
>> uint int_events;
>> + ulong flags;
>> irqreturn_t ret = IRQ_NONE;
>>
>> do {
>> @@ -813,7 +833,18 @@ fec_enet_interrupt(int irq, void *dev_id)
>>
>> if (int_events & FEC_ENET_RXF) {
>> ret = IRQ_HANDLED;
>> - fec_enet_rx(ndev);
>> + spin_lock_irqsave(&fep->hw_lock, flags);
>> +
>> + if (fep->use_napi) {
>> + /* Disable the RX interrupt */
>> + if (napi_schedule_prep(&fep->napi)) {
>> + fec_enet_rx_int_is_enabled(ndev, false);
>> + __napi_schedule(&fep->napi);
>> + }
>> + } else
>> + fec_enet_rx(ndev, INT32_MAX);
>
> As mentioned above, you may want to check this a bit closer since this
> can run for a very, very long time if you have constant packets flowing
> when not using NAPI.
>
> Also, the code formatting here should also have braces around the else
> clause since the if clause has them.
Okay, I will update in v2 patch.
>
>> +
>> + spin_unlock_irqrestore(&fep->hw_lock, flags);
>> }
>>
>> /* Transmit OK, or non-fatal error. Update the buffer
>> @@ -834,7 +865,16 @@ fec_enet_interrupt(int irq, void *dev_id)
>> return ret;
>> }
>>
>> -
>> +static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
>> +{
>> + struct net_device *ndev = napi->dev;
>> + int pkgs = fec_enet_rx(ndev, budget);
>> + if (pkgs < budget) {
>> + napi_complete(napi);
>> + fec_enet_rx_int_is_enabled(ndev, true);
>> + }
>> + return pkgs;
>> +}
>>
>> /* ------------------------------------------------------------------------- */
>> static void fec_get_mac(struct net_device *ndev)
>> @@ -1392,6 +1432,9 @@ fec_enet_open(struct net_device *ndev)
>> struct fec_enet_private *fep = netdev_priv(ndev);
>> int ret;
>>
>> + if (fep->use_napi)
>> + napi_enable(&fep->napi);
>> +
>> /* I should reset the ring buffers here, but I don't yet know
>> * a simple way to do that.
>> */
>> @@ -1604,6 +1647,11 @@ static int fec_enet_init(struct net_device *ndev)
>> ndev->netdev_ops = &fec_netdev_ops;
>> ndev->ethtool_ops = &fec_enet_ethtool_ops;
>>
>> + if (fep->use_napi) {
>> + fec_enet_rx_int_is_enabled(ndev, false);
>> + netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, fep->napi_weight);
>
> Make sure not to exceed 80 characters here.
>
Okay, I will update in v2 patch.
>> + }
>> +
>> /* Initialize the receive buffer descriptors. */
>> bdp = fep->rx_bd_base;
>> for (i = 0; i < RX_RING_SIZE; i++) {
>> @@ -1698,6 +1746,7 @@ fec_probe(struct platform_device *pdev)
>> static int dev_id;
>> struct pinctrl *pinctrl;
>> struct regulator *reg_phy;
>> + struct device_node *np = pdev->dev.of_node;
>>
>> of_id = of_match_device(fec_dt_ids, &pdev->dev);
>> if (of_id)
>> @@ -1811,6 +1860,11 @@ fec_probe(struct platform_device *pdev)
>> }
>> }
>>
>> + fep->use_napi = !of_property_read_bool(np, "disable_napi");
>> +
>> + if (of_property_read_u32(np, "napi_weight", &fep->napi_weight))
>> + fep->napi_weight = FEC_NAPI_WEIGHT; /*using default value*/
>> +
>> fec_reset_phy(pdev);
>>
>> ret = fec_enet_init(ndev);
>> diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
>> index 2ebedaf..31fcdd0 100644
>> --- a/drivers/net/ethernet/freescale/fec.h
>> +++ b/drivers/net/ethernet/freescale/fec.h
>> @@ -249,6 +249,10 @@ struct fec_enet_private {
>> int bufdesc_ex;
>> int pause_flag;
>>
>> + struct napi_struct napi;
>> + int napi_weight;
>> + bool use_napi;
>> +
>> struct ptp_clock *ptp_clock;
>> struct ptp_clock_info ptp_caps;
>> unsigned long last_overflow_check;
>> --
>> 1.7.1
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 2/2] ARM: dts: imx51-babbage: Add at24c512b eeprom support
From: Sascha Hauer @ 2013-01-23 7:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+8Hj80ceGEUtzfvvEuH7ZftWGydzd9pHK_FxfE59WBxOst4rQ@mail.gmail.com>
On Wed, Jan 23, 2013 at 03:51:12PM +0800, Liu Ying wrote:
> 2013/1/23 Sascha Hauer <s.hauer@pengutronix.de>:
> > On Wed, Jan 23, 2013 at 02:32:44PM +0800, Liu Ying wrote:
> >> This patch adds at24c512b i2c device to the device tree
> >> along with the necessary i2c device node and pinctrl
> >> settings for i2c bus.
> >> The eeprom chip is populated on the accessory board of
> >> the imx51-babbage board.
> >
> > Given that it's optional should the binding be here anyway? I don't have
> > this accessory board and this may conflict with the boards other people
> > have connected on this port.
> >
> > Sascha
>
> Understand your concern. Is there any way to handle this? How can we support
> the present accessory board correctly? More generally, not all main boards can
> figure out what kind of accessory board is attached to them, at least, some main
> boards can only figure out limited number of accessory boards by using some ways
> of board ID check.
We don't have support for such things atm. We'll have to wait for
OF: Introduce DT overlay support.
Pantelis Antoniou is working on this currently.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH 1/2 net-next] net: fec: add napi support to improve proformance
From: Sascha Hauer @ 2013-01-23 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAHrpEqQ3-prqJaCmt1hfOr4GzDVyuRNvko1SCyQZHdALhHkhkw@mail.gmail.com>
On Wed, Jan 23, 2013 at 03:44:53PM +0800, Frank Li wrote:
> > This comment seems rather unnecessary. Also it should be
> >
> > /* space left and right /*
> >
> > devicetree bindings should use '-' instead of '_'. The binding
> > Documentation should be in the patch adding the bindings. Also
> > make sure the devicetree parsing is outside of the path for platform
> > based probing.
> >
> > With this particular binding I'm unsure it should exist anyway since
> > it's configuration rather than hardware description. The devicetree
> > normally is for hardware description only.
> >
>
> What's your opinion?
> Using module parameter, device-tree to config it or the other method?
Why do you want to make it configurable anyway? So far no other driver
seems to need this. My suggestion is to make it unconfigurable.
For adding properties like this to the devicetree remember that they
should be OS agnostic. napi is a implementation detail relevant only
for Linux. And even Linux may decide to drop napi support in favour for
something better in the future.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH 1/2 net-next] net: fec: add napi support to improve proformance
From: David Miller @ 2013-01-23 7:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAHrpEqQ3-prqJaCmt1hfOr4GzDVyuRNvko1SCyQZHdALhHkhkw@mail.gmail.com>
NAPI should not be configurable, all device drivers should be NAPI
only.
^ permalink raw reply
* [PATCH 2/2] ARM: dts: imx51-babbage: Add at24c512b eeprom support
From: Liu Ying @ 2013-01-23 7:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130123073059.GP1906@pengutronix.de>
2013/1/23 Sascha Hauer <s.hauer@pengutronix.de>:
> On Wed, Jan 23, 2013 at 02:32:44PM +0800, Liu Ying wrote:
>> This patch adds at24c512b i2c device to the device tree
>> along with the necessary i2c device node and pinctrl
>> settings for i2c bus.
>> The eeprom chip is populated on the accessory board of
>> the imx51-babbage board.
>
> Given that it's optional should the binding be here anyway? I don't have
> this accessory board and this may conflict with the boards other people
> have connected on this port.
>
> Sascha
Understand your concern. Is there any way to handle this? How can we support
the present accessory board correctly? More generally, not all main boards can
figure out what kind of accessory board is attached to them, at least, some main
boards can only figure out limited number of accessory boards by using some ways
of board ID check.
>
>>
>> Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
>> ---
>> arch/arm/boot/dts/imx51-babbage.dts | 12 ++++++++++++
>> arch/arm/boot/dts/imx51.dtsi | 9 +++++++++
>> 2 files changed, 21 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
>> index 567e7ee..4f0fc75 100644
>> --- a/arch/arm/boot/dts/imx51-babbage.dts
>> +++ b/arch/arm/boot/dts/imx51-babbage.dts
>> @@ -241,6 +241,18 @@
>> };
>> };
>>
>> + i2c at 83fc8000 { /* I2C1 */
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_i2c1_1>;
>> + status = "okay";
>> +
>> + at24 at 50 {
>> + compatible = "at24,24c512b";
>> + pagesize = <128>;
>> + reg = <0x50>;
>> + };
>> + };
>> +
>> audmux at 83fd0000 {
>> pinctrl-names = "default";
>> pinctrl-0 = <&pinctrl_audmux_1>;
>> diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
>> index 1f5d45e..6495c69 100644
>> --- a/arch/arm/boot/dts/imx51.dtsi
>> +++ b/arch/arm/boot/dts/imx51.dtsi
>> @@ -311,6 +311,15 @@
>> };
>> };
>>
>> + i2c1 {
>> + pinctrl_i2c1_1: i2c1grp-1 {
>> + fsl,pins = <
>> + 4 0x400001ed /* MX51_PAD_EIM_D16__I2C1_SDA */
>> + 23 0x400001ed /* MX51_PAD_EIM_D19__I2C1_SCL */
>> + >;
>> + };
>> + };
>> +
>> i2c2 {
>> pinctrl_i2c2_1: i2c2grp-1 {
>> fsl,pins = <
>> --
>> 1.7.1
>>
>>
>>
>
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
--
Best Regards,
Liu Ying
^ permalink raw reply
* [PATCH 0/4] TI LCDC DRM driver
From: Sascha Hauer @ 2013-01-23 7:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358894185-21617-1-git-send-email-robdclark@gmail.com>
Hi Rob,
On Tue, Jan 22, 2013 at 04:36:21PM -0600, Rob Clark wrote:
>
> drivers/gpu/drm/Kconfig | 2 +
> drivers/gpu/drm/Makefile | 1 +
> drivers/gpu/drm/i2c/Makefile | 3 +
> drivers/gpu/drm/i2c/tda998x_drv.c | 908 +++++++++++++++++++++++++++++++++
> drivers/gpu/drm/tilcdc/Kconfig | 25 +
> drivers/gpu/drm/tilcdc/Makefile | 10 +
> drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 597 ++++++++++++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_drv.c | 611 ++++++++++++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_drv.h | 159 ++++++
> drivers/gpu/drm/tilcdc/tilcdc_panel.c | 443 ++++++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_panel.h | 26 +
> drivers/gpu/drm/tilcdc/tilcdc_regs.h | 154 ++++++
> drivers/gpu/drm/tilcdc/tilcdc_slave.c | 380 ++++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_slave.h | 26 +
> drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 423 +++++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_tfp410.h | 26 +
> 16 files changed, 3794 insertions(+)
> create mode 100644 drivers/gpu/drm/i2c/tda998x_drv.c
> create mode 100644 drivers/gpu/drm/tilcdc/Kconfig
> create mode 100644 drivers/gpu/drm/tilcdc/Makefile
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_drv.c
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_drv.h
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_panel.c
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_panel.h
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_regs.h
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.c
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.h
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.h
I'm missing Documentation/devicetree/bindings/drm/tilcdc/ in the
diffstat. This is required for adding devicetree bindings.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH 1/2 net-next] net: fec: add napi support to improve proformance
From: Frank Li @ 2013-01-23 7:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130123072635.GO1906@pengutronix.de>
> This comment seems rather unnecessary. Also it should be
>
> /* space left and right /*
>
> devicetree bindings should use '-' instead of '_'. The binding
> Documentation should be in the patch adding the bindings. Also
> make sure the devicetree parsing is outside of the path for platform
> based probing.
>
> With this particular binding I'm unsure it should exist anyway since
> it's configuration rather than hardware description. The devicetree
> normally is for hardware description only.
>
What's your opinion?
Using module parameter, device-tree to config it or the other method?
best regards
Frank Li
^ permalink raw reply
* [PATCH 2/4] drm/i2c: nxp-tda998x (v2)
From: Koen Kooi @ 2013-01-23 7:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358894185-21617-3-git-send-email-robdclark@gmail.com>
Op 22 jan. 2013, om 23:36 heeft Rob Clark <robdclark@gmail.com> het volgende geschreven:
> Driver for the NXP TDA998X i2c hdmi encoder slave.
>
> v1: original
> v2: fix npix/nline programming
>
> Signed-off-by: Rob Clark <robdclark@gmail.com>
Tested on a beaglebone-black:
Tested-by: Koen Kooi <koen@dominion.thruhere.net>
^ permalink raw reply
* [PATCH 1/4] drm/tilcdc: add TI LCD Controller DRM driver (v3)
From: Koen Kooi @ 2013-01-23 7:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358894185-21617-2-git-send-email-robdclark@gmail.com>
Op 22 jan. 2013, om 23:36 heeft Rob Clark <robdclark@gmail.com> het volgende geschreven:
> A simple DRM/KMS driver for the TI LCD Controller found in various
> smaller TI parts (AM33xx, OMAPL138, etc). This driver uses the
> CMA helpers. Currently only the TFP410 DVI encoder is supported
> (tested with beaglebone + DVI cape). There are also various LCD
> displays, for which support can be added (as I get hw to test on),
> and an external i2c HDMI encoder found on some boards.
>
> The display controller supports a single CRTC. And the encoder+
> connector are split out into sub-devices. Depending on which LCD
> or external encoder is actually present, the appropriate output
> module(s) will be loaded.
>
> v1: original
> v2: fix fb refcnting and few other cleanups
> v3: get +/- vsync/hsync from timings rather than panel-info, add
> option DT max-bandwidth field so driver doesn't attempt to
> pick a display mode with too high memory bandwidth, and other
> small cleanups
>
> Signed-off-by: Rob Clark <robdclark@gmail.com>
Tested on a beaglebone and beaglebone-black:
Tested-by: Koen Kooi <koen@dominion.thruhere.net>
^ permalink raw reply
* [PATCH 1/2 net-next] net: fec: add napi support to improve proformance
From: Frank Li @ 2013-01-23 7:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358922071.12374.743.camel@edumazet-glaptop>
2013/1/23 Eric Dumazet <eric.dumazet@gmail.com>:
> On Wed, 2013-01-23 at 12:12 +0800, Frank Li wrote:
>> Add napi support
>>
>> Before this patch
>>
>> iperf -s -i 1
>> ------------------------------------------------------------
>> Server listening on TCP port 5001
>> TCP window size: 85.3 KByte (default)
>> ------------------------------------------------------------
>> [ 4] local 10.192.242.153 port 5001 connected with 10.192.242.138 port 50004
>> [ ID] Interval Transfer Bandwidth
>> [ 4] 0.0- 1.0 sec 41.2 MBytes 345 Mbits/sec
>> [ 4] 1.0- 2.0 sec 43.7 MBytes 367 Mbits/sec
>> [ 4] 2.0- 3.0 sec 42.8 MBytes 359 Mbits/sec
>> [ 4] 3.0- 4.0 sec 43.7 MBytes 367 Mbits/sec
>> [ 4] 4.0- 5.0 sec 42.7 MBytes 359 Mbits/sec
>> [ 4] 5.0- 6.0 sec 43.8 MBytes 367 Mbits/sec
>> [ 4] 6.0- 7.0 sec 43.0 MBytes 361 Mbits/sec
>>
>> After this patch
>> [ 4] 2.0- 3.0 sec 51.6 MBytes 433 Mbits/sec
>> [ 4] 3.0- 4.0 sec 51.8 MBytes 435 Mbits/sec
>> [ 4] 4.0- 5.0 sec 52.2 MBytes 438 Mbits/sec
>> [ 4] 5.0- 6.0 sec 52.1 MBytes 437 Mbits/sec
>> [ 4] 6.0- 7.0 sec 52.1 MBytes 437 Mbits/sec
>> [ 4] 7.0- 8.0 sec 52.3 MBytes 439 Mbits/sec
>
> Strange, as you still call netif_rx()
>
> NAPI should call netif_receive_skb() instead
>
Thank you point out.
After re-test, I found performance is almost no change if use netif_receive_skb.
I am not sure if it is my NAPI implement problem.
napi_gro_received is better than netif_receive_skb, but worse than netif_rx.
>From performance point view,
netif_rx --- fastest
napi_gro_received --- middle, near to netif_rx
netif_receive_skb --- slowest, almost the same as original no-napi version.
Do you have any idea about this phenomena?
best regards
Frank Li
>
>
^ permalink raw reply
* [PATCH 2/2] ARM: dts: imx51-babbage: Add at24c512b eeprom support
From: Sascha Hauer @ 2013-01-23 7:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358922764-31654-2-git-send-email-Ying.Liu@freescale.com>
On Wed, Jan 23, 2013 at 02:32:44PM +0800, Liu Ying wrote:
> This patch adds at24c512b i2c device to the device tree
> along with the necessary i2c device node and pinctrl
> settings for i2c bus.
> The eeprom chip is populated on the accessory board of
> the imx51-babbage board.
Given that it's optional should the binding be here anyway? I don't have
this accessory board and this may conflict with the boards other people
have connected on this port.
Sascha
>
> Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
> ---
> arch/arm/boot/dts/imx51-babbage.dts | 12 ++++++++++++
> arch/arm/boot/dts/imx51.dtsi | 9 +++++++++
> 2 files changed, 21 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
> index 567e7ee..4f0fc75 100644
> --- a/arch/arm/boot/dts/imx51-babbage.dts
> +++ b/arch/arm/boot/dts/imx51-babbage.dts
> @@ -241,6 +241,18 @@
> };
> };
>
> + i2c at 83fc8000 { /* I2C1 */
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_i2c1_1>;
> + status = "okay";
> +
> + at24 at 50 {
> + compatible = "at24,24c512b";
> + pagesize = <128>;
> + reg = <0x50>;
> + };
> + };
> +
> audmux at 83fd0000 {
> pinctrl-names = "default";
> pinctrl-0 = <&pinctrl_audmux_1>;
> diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
> index 1f5d45e..6495c69 100644
> --- a/arch/arm/boot/dts/imx51.dtsi
> +++ b/arch/arm/boot/dts/imx51.dtsi
> @@ -311,6 +311,15 @@
> };
> };
>
> + i2c1 {
> + pinctrl_i2c1_1: i2c1grp-1 {
> + fsl,pins = <
> + 4 0x400001ed /* MX51_PAD_EIM_D16__I2C1_SDA */
> + 23 0x400001ed /* MX51_PAD_EIM_D19__I2C1_SCL */
> + >;
> + };
> + };
> +
> i2c2 {
> pinctrl_i2c2_1: i2c2grp-1 {
> fsl,pins = <
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH 1/2 net-next] net: fec: add napi support to improve proformance
From: Sascha Hauer @ 2013-01-23 7:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358914330-3768-1-git-send-email-Frank.Li@freescale.com>
On Wed, Jan 23, 2013 at 12:12:10PM +0800, Frank Li wrote:
> Add napi support
>
> Before this patch
>
> iperf -s -i 1
> ------------------------------------------------------------
> Server listening on TCP port 5001
> TCP window size: 85.3 KByte (default)
> ------------------------------------------------------------
> [ 4] local 10.192.242.153 port 5001 connected with 10.192.242.138 port 50004
> [ ID] Interval Transfer Bandwidth
> [ 4] 0.0- 1.0 sec 41.2 MBytes 345 Mbits/sec
> [ 4] 1.0- 2.0 sec 43.7 MBytes 367 Mbits/sec
> [ 4] 2.0- 3.0 sec 42.8 MBytes 359 Mbits/sec
> [ 4] 3.0- 4.0 sec 43.7 MBytes 367 Mbits/sec
> [ 4] 4.0- 5.0 sec 42.7 MBytes 359 Mbits/sec
> [ 4] 5.0- 6.0 sec 43.8 MBytes 367 Mbits/sec
> [ 4] 6.0- 7.0 sec 43.0 MBytes 361 Mbits/sec
>
> After this patch
> [ 4] 2.0- 3.0 sec 51.6 MBytes 433 Mbits/sec
> [ 4] 3.0- 4.0 sec 51.8 MBytes 435 Mbits/sec
> [ 4] 4.0- 5.0 sec 52.2 MBytes 438 Mbits/sec
> [ 4] 5.0- 6.0 sec 52.1 MBytes 437 Mbits/sec
> [ 4] 6.0- 7.0 sec 52.1 MBytes 437 Mbits/sec
> [ 4] 7.0- 8.0 sec 52.3 MBytes 439 Mbits/sec
>
> Signed-off-by: Frank Li <Frank.Li@freescale.com>
> Signed-off-by: Fugang Duan <B38611@freescale.com>
> ---
> drivers/net/ethernet/freescale/fec.c | 68 ++++++++++++++++++++++++++++++---
> drivers/net/ethernet/freescale/fec.h | 4 ++
> 2 files changed, 65 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
> index f52ba33..8fa420c 100644
> --- a/drivers/net/ethernet/freescale/fec.c
> +++ b/drivers/net/ethernet/freescale/fec.c
> @@ -67,6 +67,8 @@
> #endif
>
> #define DRIVER_NAME "fec"
> +#define FEC_NAPI_WEIGHT 64
> +#define INT32_MAX 0x7FFFFFFF
>
> /* Pause frame feild and FIFO threshold */
> #define FEC_ENET_FCE (1 << 5)
> @@ -565,6 +567,20 @@ fec_timeout(struct net_device *ndev)
> }
>
> static void
> +fec_enet_rx_int_is_enabled(struct net_device *ndev, bool enabled)
> +{
> + struct fec_enet_private *fep = netdev_priv(ndev);
> + uint int_events;
> +
> + int_events = readl(fep->hwp + FEC_IMASK);
> + if (enabled)
> + int_events |= FEC_ENET_RXF;
> + else
> + int_events &= ~FEC_ENET_RXF;
> + writel(int_events, fep->hwp + FEC_IMASK);
> +}
> +
> +static void
> fec_enet_tx(struct net_device *ndev)
> {
> struct fec_enet_private *fep;
> @@ -656,8 +672,8 @@ fec_enet_tx(struct net_device *ndev)
> * not been given to the system, we just set the empty indicator,
> * effectively tossing the packet.
> */
> -static void
> -fec_enet_rx(struct net_device *ndev)
> +static int
> +fec_enet_rx(struct net_device *ndev, int budget)
> {
> struct fec_enet_private *fep = netdev_priv(ndev);
> const struct platform_device_id *id_entry =
> @@ -667,13 +683,12 @@ fec_enet_rx(struct net_device *ndev)
> struct sk_buff *skb;
> ushort pkt_len;
> __u8 *data;
> + int pkt_received = 0;
>
> #ifdef CONFIG_M532x
> flush_cache_all();
> #endif
>
> - spin_lock(&fep->hw_lock);
> -
> /* First, grab all of the stats for the incoming packet.
> * These get messed up if we get called due to a busy condition.
> */
> @@ -681,6 +696,10 @@ fec_enet_rx(struct net_device *ndev)
>
> while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
>
> + if (pkt_received >= budget)
> + break;
> + pkt_received++;
> +
> /* Since we have allocated space to hold a complete frame,
> * the last indicator should be set.
> */
> @@ -796,7 +815,7 @@ rx_processing_done:
> }
> fep->cur_rx = bdp;
>
> - spin_unlock(&fep->hw_lock);
> + return pkt_received;
> }
>
> static irqreturn_t
> @@ -805,6 +824,7 @@ fec_enet_interrupt(int irq, void *dev_id)
> struct net_device *ndev = dev_id;
> struct fec_enet_private *fep = netdev_priv(ndev);
> uint int_events;
> + ulong flags;
> irqreturn_t ret = IRQ_NONE;
>
> do {
> @@ -813,7 +833,18 @@ fec_enet_interrupt(int irq, void *dev_id)
>
> if (int_events & FEC_ENET_RXF) {
> ret = IRQ_HANDLED;
> - fec_enet_rx(ndev);
> + spin_lock_irqsave(&fep->hw_lock, flags);
> +
> + if (fep->use_napi) {
> + /* Disable the RX interrupt */
> + if (napi_schedule_prep(&fep->napi)) {
> + fec_enet_rx_int_is_enabled(ndev, false);
> + __napi_schedule(&fep->napi);
> + }
> + } else
> + fec_enet_rx(ndev, INT32_MAX);
> +
> + spin_unlock_irqrestore(&fep->hw_lock, flags);
> }
>
> /* Transmit OK, or non-fatal error. Update the buffer
> @@ -834,7 +865,16 @@ fec_enet_interrupt(int irq, void *dev_id)
> return ret;
> }
>
> -
> +static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
> +{
> + struct net_device *ndev = napi->dev;
> + int pkgs = fec_enet_rx(ndev, budget);
> + if (pkgs < budget) {
> + napi_complete(napi);
> + fec_enet_rx_int_is_enabled(ndev, true);
> + }
> + return pkgs;
> +}
>
> /* ------------------------------------------------------------------------- */
> static void fec_get_mac(struct net_device *ndev)
> @@ -1392,6 +1432,9 @@ fec_enet_open(struct net_device *ndev)
> struct fec_enet_private *fep = netdev_priv(ndev);
> int ret;
>
> + if (fep->use_napi)
> + napi_enable(&fep->napi);
> +
> /* I should reset the ring buffers here, but I don't yet know
> * a simple way to do that.
> */
> @@ -1604,6 +1647,11 @@ static int fec_enet_init(struct net_device *ndev)
> ndev->netdev_ops = &fec_netdev_ops;
> ndev->ethtool_ops = &fec_enet_ethtool_ops;
>
> + if (fep->use_napi) {
> + fec_enet_rx_int_is_enabled(ndev, false);
> + netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, fep->napi_weight);
> + }
> +
> /* Initialize the receive buffer descriptors. */
> bdp = fep->rx_bd_base;
> for (i = 0; i < RX_RING_SIZE; i++) {
> @@ -1698,6 +1746,7 @@ fec_probe(struct platform_device *pdev)
> static int dev_id;
> struct pinctrl *pinctrl;
> struct regulator *reg_phy;
> + struct device_node *np = pdev->dev.of_node;
>
> of_id = of_match_device(fec_dt_ids, &pdev->dev);
> if (of_id)
> @@ -1811,6 +1860,11 @@ fec_probe(struct platform_device *pdev)
> }
> }
>
> + fep->use_napi = !of_property_read_bool(np, "disable_napi");
> +
> + if (of_property_read_u32(np, "napi_weight", &fep->napi_weight))
> + fep->napi_weight = FEC_NAPI_WEIGHT; /*using default value*/
This comment seems rather unnecessary. Also it should be
/* space left and right /*
devicetree bindings should use '-' instead of '_'. The binding
Documentation should be in the patch adding the bindings. Also
make sure the devicetree parsing is outside of the path for platform
based probing.
With this particular binding I'm unsure it should exist anyway since
it's configuration rather than hardware description. The devicetree
normally is for hardware description only.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH 1/2] usb: host: tegra: don't touch EMC clock
From: Venu Byravarasu @ 2013-01-23 6:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358900903-27654-1-git-send-email-swarren@wwwdotorg.org>
> -----Original Message-----
> From: linux-tegra-owner at vger.kernel.org [mailto:linux-tegra-
> owner at vger.kernel.org] On Behalf Of Stephen Warren
> Sent: Wednesday, January 23, 2013 5:58 AM
> To: Alan Stern; Greg Kroah-Hartman; Stephen Warren
> Cc: Venu Byravarasu; linux-tegra at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-usb at vger.kernel.org; Stephen Warren
> Subject: [PATCH 1/2] usb: host: tegra: don't touch EMC clock
>
> From: Stephen Warren <swarren@nvidia.com>
>
> Clock "emc" is for the External Memory Controller. The USB driver has no
> business touching this clock directly. Remove the code that does so.
Stephen,
This was primarily done to make sure that EMC is set to a minimum
frequency, below which data errors may occur during USB transfers.
If we plan to remove this, how should we make sure that the EMC
is programmed for the required frequency during USB transfers?
>
> Signed-off-by: Stephen Warren <swarren@nvidia.com>
> ---
> Greg, Alan, I'd like to take this patch through the Tegra tree to avoid
> any merge conflicts with the Tegra USB changes that have recently
> happened there.
>
> Venu, When creating your patch to convert the Tegra USB PHY driver to a
> platform driver, can you assume these patches are applied first? Thanks.
> I assume that these patches make sense to you; could you ack them if so.
> ---
> drivers/usb/host/ehci-tegra.c | 17 -----------------
> 1 file changed, 17 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
> index 1f596fb..b02622a 100644
> --- a/drivers/usb/host/ehci-tegra.c
> +++ b/drivers/usb/host/ehci-tegra.c
> @@ -44,7 +44,6 @@ struct tegra_ehci_hcd {
> struct ehci_hcd *ehci;
> struct tegra_usb_phy *phy;
> struct clk *clk;
> - struct clk *emc_clk;
> struct usb_phy *transceiver;
> int host_resumed;
> int port_resuming;
> @@ -56,7 +55,6 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd)
> {
> struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
>
> - clk_prepare_enable(tegra->emc_clk);
> clk_prepare_enable(tegra->clk);
> usb_phy_set_suspend(&tegra->phy->u_phy, 0);
> tegra->host_resumed = 1;
> @@ -69,7 +67,6 @@ static void tegra_ehci_power_down(struct usb_hcd
> *hcd)
> tegra->host_resumed = 0;
> usb_phy_set_suspend(&tegra->phy->u_phy, 1);
> clk_disable_unprepare(tegra->clk);
> - clk_disable_unprepare(tegra->emc_clk);
> }
>
> static int tegra_ehci_internal_port_reset(
> @@ -694,16 +691,6 @@ static int tegra_ehci_probe(struct platform_device
> *pdev)
> if (err)
> goto fail_clk;
>
> - tegra->emc_clk = devm_clk_get(&pdev->dev, "emc");
> - if (IS_ERR(tegra->emc_clk)) {
> - dev_err(&pdev->dev, "Can't get emc clock\n");
> - err = PTR_ERR(tegra->emc_clk);
> - goto fail_emc_clk;
> - }
> -
> - clk_prepare_enable(tegra->emc_clk);
> - clk_set_rate(tegra->emc_clk, 400000000);
> -
> tegra->needs_double_reset = of_property_read_bool(pdev-
> >dev.of_node,
> "nvidia,needs-double-reset");
>
> @@ -813,8 +800,6 @@ fail:
> #endif
> usb_phy_shutdown(&tegra->phy->u_phy);
> fail_io:
> - clk_disable_unprepare(tegra->emc_clk);
> -fail_emc_clk:
> clk_disable_unprepare(tegra->clk);
> fail_clk:
> usb_put_hcd(hcd);
> @@ -842,8 +827,6 @@ static int tegra_ehci_remove(struct platform_device
> *pdev)
>
> clk_disable_unprepare(tegra->clk);
>
> - clk_disable_unprepare(tegra->emc_clk);
> -
> return 0;
> }
>
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 2/2] ARM: tegra: add clocks properties to USB PHY nodes
From: Venu Byravarasu @ 2013-01-23 6:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50FF2FD0.2090003@wwwdotorg.org>
> -----Original Message-----
> From: Stephen Warren [mailto:swarren at wwwdotorg.org]
> Sent: Wednesday, January 23, 2013 6:03 AM
> To: Venu Byravarasu
> Cc: Alan Stern; Greg Kroah-Hartman; linux-tegra at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-usb at vger.kernel.org; Stephen Warren
> Subject: Re: [PATCH 2/2] ARM: tegra: add clocks properties to USB PHY nodes
>
> On 01/22/2013 05:28 PM, Stephen Warren wrote:
> > The patch to add USB PHY nodes to device tree was written before Tegra
> > supported the clocks property in device tree. Now that it does, add the
> > required clocks properties to these nodes.
> >
> > This will allow all clk_get_sys() calls in tegra_usb_phy.c to be replaced
> > by clk_get(phy->dev, clock_name), as part of converting the PHY driver to
> > a platform driver.
>
> > diff --git a/arch/arm/boot/dts/tegra20.dtsi
> b/arch/arm/boot/dts/tegra20.dtsi
>
> > + clocks = <&tegra_car 22>, <&tegra_car 127>;
> > + clock-names = "utmi", "pll_u";
> ...
> > + clocks = <&tegra_car 94>, <&tegra_car 127>;
> > + clock-names = "ulpi", "pll_u";
>
> Hmmm. Thinking about that first clock more, if we name it just "phy" in
> both the UTMI and ULPI PHY nodes, we could make tegra_phy_init() perform
> the clk_get() for all PHY types, and use the same clock name everywhere,
> and hence remove the type-specific clk_get()s from tegra_phy_init() and
> utmip_pad_open().
>
> Venu, will this work for other chips such as Tegra30/Tegra114 and so on
> into the future, or do chips after Tegra20 introduce any new clocks, and
> hence break this scheme?
Should be fine, as same clocks are used across all chips.
Acked-by: Venu Byravarasu <vbyravarasu@nvidia.com>
^ permalink raw reply
* [PATCH 1/2 net-next] net: fec: add napi support to improve proformance
From: Waskiewicz Jr, Peter P @ 2013-01-23 6:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358914330-3768-1-git-send-email-Frank.Li@freescale.com>
On Wed, Jan 23, 2013 at 12:12:10PM +0800, Frank Li wrote:
[...]
> diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
> index f52ba33..8fa420c 100644
> --- a/drivers/net/ethernet/freescale/fec.c
> +++ b/drivers/net/ethernet/freescale/fec.c
> @@ -67,6 +67,8 @@
> #endif
>
> #define DRIVER_NAME "fec"
> +#define FEC_NAPI_WEIGHT 64
> +#define INT32_MAX 0x7FFFFFFF
This seems awfully big as an upper-limit to your ISR processing. See below
for more comments.
>
> /* Pause frame feild and FIFO threshold */
> #define FEC_ENET_FCE (1 << 5)
> @@ -565,6 +567,20 @@ fec_timeout(struct net_device *ndev)
> }
>
> static void
> +fec_enet_rx_int_is_enabled(struct net_device *ndev, bool enabled)
> +{
> + struct fec_enet_private *fep = netdev_priv(ndev);
> + uint int_events;
> +
> + int_events = readl(fep->hwp + FEC_IMASK);
> + if (enabled)
> + int_events |= FEC_ENET_RXF;
> + else
> + int_events &= ~FEC_ENET_RXF;
> + writel(int_events, fep->hwp + FEC_IMASK);
> +}
> +
> +static void
> fec_enet_tx(struct net_device *ndev)
> {
> struct fec_enet_private *fep;
> @@ -656,8 +672,8 @@ fec_enet_tx(struct net_device *ndev)
> * not been given to the system, we just set the empty indicator,
> * effectively tossing the packet.
> */
> -static void
> -fec_enet_rx(struct net_device *ndev)
> +static int
> +fec_enet_rx(struct net_device *ndev, int budget)
> {
> struct fec_enet_private *fep = netdev_priv(ndev);
> const struct platform_device_id *id_entry =
> @@ -667,13 +683,12 @@ fec_enet_rx(struct net_device *ndev)
> struct sk_buff *skb;
> ushort pkt_len;
> __u8 *data;
> + int pkt_received = 0;
>
> #ifdef CONFIG_M532x
> flush_cache_all();
> #endif
>
> - spin_lock(&fep->hw_lock);
> -
> /* First, grab all of the stats for the incoming packet.
> * These get messed up if we get called due to a busy condition.
> */
> @@ -681,6 +696,10 @@ fec_enet_rx(struct net_device *ndev)
>
> while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
>
> + if (pkt_received >= budget)
> + break;
> + pkt_received++;
> +
This seems wrong given how it's called from the ISR when NAPI isn't being
used. If you have continuous packets coming in, you won't exit your ISR
and release your spin_lock until you hit INT32_MAX.
> /* Since we have allocated space to hold a complete frame,
> * the last indicator should be set.
> */
> @@ -796,7 +815,7 @@ rx_processing_done:
> }
> fep->cur_rx = bdp;
>
> - spin_unlock(&fep->hw_lock);
> + return pkt_received;
> }
>
> static irqreturn_t
> @@ -805,6 +824,7 @@ fec_enet_interrupt(int irq, void *dev_id)
> struct net_device *ndev = dev_id;
> struct fec_enet_private *fep = netdev_priv(ndev);
> uint int_events;
> + ulong flags;
> irqreturn_t ret = IRQ_NONE;
>
> do {
> @@ -813,7 +833,18 @@ fec_enet_interrupt(int irq, void *dev_id)
>
> if (int_events & FEC_ENET_RXF) {
> ret = IRQ_HANDLED;
> - fec_enet_rx(ndev);
> + spin_lock_irqsave(&fep->hw_lock, flags);
> +
> + if (fep->use_napi) {
> + /* Disable the RX interrupt */
> + if (napi_schedule_prep(&fep->napi)) {
> + fec_enet_rx_int_is_enabled(ndev, false);
> + __napi_schedule(&fep->napi);
> + }
> + } else
> + fec_enet_rx(ndev, INT32_MAX);
As mentioned above, you may want to check this a bit closer since this
can run for a very, very long time if you have constant packets flowing
when not using NAPI.
Also, the code formatting here should also have braces around the else
clause since the if clause has them.
> +
> + spin_unlock_irqrestore(&fep->hw_lock, flags);
> }
>
> /* Transmit OK, or non-fatal error. Update the buffer
> @@ -834,7 +865,16 @@ fec_enet_interrupt(int irq, void *dev_id)
> return ret;
> }
>
> -
> +static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
> +{
> + struct net_device *ndev = napi->dev;
> + int pkgs = fec_enet_rx(ndev, budget);
> + if (pkgs < budget) {
> + napi_complete(napi);
> + fec_enet_rx_int_is_enabled(ndev, true);
> + }
> + return pkgs;
> +}
>
> /* ------------------------------------------------------------------------- */
> static void fec_get_mac(struct net_device *ndev)
> @@ -1392,6 +1432,9 @@ fec_enet_open(struct net_device *ndev)
> struct fec_enet_private *fep = netdev_priv(ndev);
> int ret;
>
> + if (fep->use_napi)
> + napi_enable(&fep->napi);
> +
> /* I should reset the ring buffers here, but I don't yet know
> * a simple way to do that.
> */
> @@ -1604,6 +1647,11 @@ static int fec_enet_init(struct net_device *ndev)
> ndev->netdev_ops = &fec_netdev_ops;
> ndev->ethtool_ops = &fec_enet_ethtool_ops;
>
> + if (fep->use_napi) {
> + fec_enet_rx_int_is_enabled(ndev, false);
> + netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, fep->napi_weight);
Make sure not to exceed 80 characters here.
> + }
> +
> /* Initialize the receive buffer descriptors. */
> bdp = fep->rx_bd_base;
> for (i = 0; i < RX_RING_SIZE; i++) {
> @@ -1698,6 +1746,7 @@ fec_probe(struct platform_device *pdev)
> static int dev_id;
> struct pinctrl *pinctrl;
> struct regulator *reg_phy;
> + struct device_node *np = pdev->dev.of_node;
>
> of_id = of_match_device(fec_dt_ids, &pdev->dev);
> if (of_id)
> @@ -1811,6 +1860,11 @@ fec_probe(struct platform_device *pdev)
> }
> }
>
> + fep->use_napi = !of_property_read_bool(np, "disable_napi");
> +
> + if (of_property_read_u32(np, "napi_weight", &fep->napi_weight))
> + fep->napi_weight = FEC_NAPI_WEIGHT; /*using default value*/
> +
> fec_reset_phy(pdev);
>
> ret = fec_enet_init(ndev);
> diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
> index 2ebedaf..31fcdd0 100644
> --- a/drivers/net/ethernet/freescale/fec.h
> +++ b/drivers/net/ethernet/freescale/fec.h
> @@ -249,6 +249,10 @@ struct fec_enet_private {
> int bufdesc_ex;
> int pause_flag;
>
> + struct napi_struct napi;
> + int napi_weight;
> + bool use_napi;
> +
> struct ptp_clock *ptp_clock;
> struct ptp_clock_info ptp_caps;
> unsigned long last_overflow_check;
> --
> 1.7.1
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox