* [RFC PATCH 4/6] ARM: kirkwood: nsa310: convert to pinctrl
From: Jason Cooper @ 2013-01-23 23:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358983578.git.jason@lakedaemon.net>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
arch/arm/boot/dts/kirkwood-nsa310.dts | 99 +++++++++++++++++++++++++++++++++++
arch/arm/mach-kirkwood/board-dt.c | 3 --
arch/arm/mach-kirkwood/board-nsa310.c | 26 ---------
arch/arm/mach-kirkwood/common.h | 6 ---
4 files changed, 99 insertions(+), 35 deletions(-)
diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts
index dbb3551..3a178cf 100644
--- a/arch/arm/boot/dts/kirkwood-nsa310.dts
+++ b/arch/arm/boot/dts/kirkwood-nsa310.dts
@@ -16,6 +16,105 @@
};
ocp at f1000000 {
+ pinctrl: pinctrl at 10000 {
+ pinctrl-0 = < &pmx_led_esata_green
+ &pmx_led_esata_red
+ &pmx_led_usb_green
+ &pmx_led_usb_red
+ &pmx_usb_power_off
+ &pmx_led_sys_green
+ &pmx_led_sys_red
+ &pmx_btn_reset
+ &pmx_btn_copy
+ &pmx_led_copy_green
+ &pmx_led_copy_red
+ &pmx_led_hdd_green
+ &pmx_led_hdd_red
+ &pmx_unknown
+ &pmx_btn_power
+ &pmx_pwr_off >;
+ pinctrl-names = "default";
+
+ pmx_led_esata_green: pmx-led-esata-green {
+ marvell,pins = "mpp12";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_esata_red: pmx-led-esata-red {
+ marvell,pins = "mpp13";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_usb_green: pmx-led-usb-green {
+ marvell,pins = "mpp15";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_usb_red: pmx-led-usb-red {
+ marvell,pins = "mpp16";
+ marvell,function = "gpio";
+ };
+
+ pmx_usb_power_off: pmx-usb-power-off {
+ marvell,pins = "mpp21";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_green: pmx-led-sys-green {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_sys_red: pmx-led-sys-red {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_btn_reset: pmx-btn-reset {
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+
+ pmx_btn_copy: pmx-btn-copy {
+ marvell,pins = "mpp37";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_copy_green: pmx-led-copy-green {
+ marvell,pins = "mpp39";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_copy_red: pmx-led-copy-red {
+ marvell,pins = "mpp40";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_hdd_green: pmx-led-hdd-green {
+ marvell,pins = "mpp41";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_hdd_red: pmx-led-hdd-red {
+ marvell,pins = "mpp42";
+ marvell,function = "gpio";
+ };
+
+ pmx_unknown: pmx-unknown {
+ marvell,pins = "mpp44";
+ marvell,function = "gpio";
+ };
+
+ pmx_btn_power: pmx-btn-power {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+
+ pmx_pwr_off: pmx-pwr-off {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+ };
serial at 12000 {
clock-frequency = <200000000>;
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 8eac548..8b35157 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -141,9 +141,6 @@ static void __init kirkwood_dt_init(void)
if (of_machine_is_compatible("usi,topkick"))
usi_topkick_init();
- if (of_machine_is_compatible("zyxel,nsa310"))
- nsa310_init();
-
of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
}
diff --git a/arch/arm/mach-kirkwood/board-nsa310.c b/arch/arm/mach-kirkwood/board-nsa310.c
index 0b99533..55ade93 100644
--- a/arch/arm/mach-kirkwood/board-nsa310.c
+++ b/arch/arm/mach-kirkwood/board-nsa310.c
@@ -13,32 +13,6 @@
#include <mach/kirkwood.h>
#include <linux/of.h>
#include "common.h"
-#include "mpp.h"
-
-static unsigned int nsa310_mpp_config[] __initdata = {
- MPP12_GPIO, /* led esata green */
- MPP13_GPIO, /* led esata red */
- MPP15_GPIO, /* led usb green */
- MPP16_GPIO, /* led usb red */
- MPP21_GPIO, /* control usb power off */
- MPP28_GPIO, /* led sys green */
- MPP29_GPIO, /* led sys red */
- MPP36_GPIO, /* key reset */
- MPP37_GPIO, /* key copy */
- MPP39_GPIO, /* led copy green */
- MPP40_GPIO, /* led copy red */
- MPP41_GPIO, /* led hdd green */
- MPP42_GPIO, /* led hdd red */
- MPP44_GPIO, /* ?? */
- MPP46_GPIO, /* key power */
- MPP48_GPIO, /* control power off */
- 0
-};
-
-void __init nsa310_init(void)
-{
- kirkwood_mpp_conf(nsa310_mpp_config);
-}
static int __init nsa310_pci_init(void)
{
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index e956d02..1c42cb8 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -130,12 +130,6 @@ void ns2_init(void);
static inline void ns2_init(void) {};
#endif
-#ifdef CONFIG_MACH_NSA310_DT
-void nsa310_init(void);
-#else
-static inline void nsa310_init(void) {};
-#endif
-
#ifdef CONFIG_MACH_OPENBLOCKS_A6_DT
void openblocks_a6_init(void);
#else
--
1.8.1.1
^ permalink raw reply related
* [RFC PATCH 5/6] ARM: kirkwood: consolidate DT init of pcie
From: Jason Cooper @ 2013-01-23 23:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358983578.git.jason@lakedaemon.net>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
arch/arm/mach-kirkwood/Makefile | 1 -
arch/arm/mach-kirkwood/board-dt.c | 23 +++++++++++++++++++++++
arch/arm/mach-kirkwood/board-iconnect.c | 9 ---------
arch/arm/mach-kirkwood/board-mplcec4.c | 1 -
arch/arm/mach-kirkwood/board-nsa310.c | 25 -------------------------
arch/arm/mach-kirkwood/board-ts219.c | 13 -------------
6 files changed, 23 insertions(+), 49 deletions(-)
delete mode 100644 arch/arm/mach-kirkwood/board-nsa310.c
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index d665309..ee3aa77 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -36,6 +36,5 @@ obj-$(CONFIG_MACH_NETSPACE_V2_DT) += board-ns2.o
obj-$(CONFIG_MACH_NETSPACE_MAX_V2_DT) += board-ns2.o
obj-$(CONFIG_MACH_NETSPACE_LITE_V2_DT) += board-ns2.o
obj-$(CONFIG_MACH_NETSPACE_MINI_V2_DT) += board-ns2.o
-obj-$(CONFIG_MACH_NSA310_DT) += board-nsa310.o
obj-$(CONFIG_MACH_OPENBLOCKS_A6_DT) += board-openblocks_a6.o
obj-$(CONFIG_MACH_TOPKICK_DT) += board-usi_topkick.o
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 8b35157..73b76e4 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -70,6 +70,29 @@ static void __init kirkwood_of_clk_init(void)
kirkwood_legacy_clk_init();
}
+static const char * const kirkwood_dt_pcie0_compat[] = {
+ "iom,iconnect",
+ "mpl,cec4",
+ "qnap,ts219",
+ "zyxel,nsa310",
+ NULL
+};
+
+static int __init kirkwood_pcie_dt_init(void)
+{
+ int i;
+
+ for (i = 0; kirkwood_dt_pcie0_compat[i] != NULL; i++) {
+ if (of_machine_is_compatible(kirkwood_dt_pcie0_compat[i])) {
+ kirkwood_pcie_init(KW_PCIE0);
+ break;
+ }
+ }
+
+ return 0;
+}
+subsys_initcall(kirkwood_pcie_dt_init);
+
static void __init kirkwood_dt_init(void)
{
pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk);
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c
index c8ebde4..ff042dc 100644
--- a/arch/arm/mach-kirkwood/board-iconnect.c
+++ b/arch/arm/mach-kirkwood/board-iconnect.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/of.h>
#include <linux/mv643xx_eth.h>
#include "common.h"
@@ -22,11 +21,3 @@ void __init iconnect_init(void)
{
kirkwood_ge00_init(&iconnect_ge00_data);
}
-
-static int __init iconnect_pci_init(void)
-{
- if (of_machine_is_compatible("iom,iconnect"))
- kirkwood_pcie_init(KW_PCIE0);
- return 0;
-}
-subsys_initcall(iconnect_pci_init);
diff --git a/arch/arm/mach-kirkwood/board-mplcec4.c b/arch/arm/mach-kirkwood/board-mplcec4.c
index 7d6dc66..938712e 100644
--- a/arch/arm/mach-kirkwood/board-mplcec4.c
+++ b/arch/arm/mach-kirkwood/board-mplcec4.c
@@ -29,7 +29,6 @@ void __init mplcec4_init(void)
*/
kirkwood_ge00_init(&mplcec4_ge00_data);
kirkwood_ge01_init(&mplcec4_ge01_data);
- kirkwood_pcie_init(KW_PCIE0);
}
diff --git a/arch/arm/mach-kirkwood/board-nsa310.c b/arch/arm/mach-kirkwood/board-nsa310.c
deleted file mode 100644
index 55ade93..0000000
--- a/arch/arm/mach-kirkwood/board-nsa310.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/nsa-310-setup.c
- *
- * ZyXEL NSA-310 Setup
- *
- * 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/init.h>
-#include <mach/kirkwood.h>
-#include <linux/of.h>
-#include "common.h"
-
-static int __init nsa310_pci_init(void)
-{
- if (of_machine_is_compatible("zyxel,nsa310"))
- kirkwood_pcie_init(KW_PCIE0);
-
- return 0;
-}
-
-subsys_initcall(nsa310_pci_init);
diff --git a/arch/arm/mach-kirkwood/board-ts219.c b/arch/arm/mach-kirkwood/board-ts219.c
index 10fb397..f00c0a9 100644
--- a/arch/arm/mach-kirkwood/board-ts219.c
+++ b/arch/arm/mach-kirkwood/board-ts219.c
@@ -17,10 +17,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
#include <linux/mv643xx_eth.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
#include "common.h"
@@ -38,13 +35,3 @@ void __init qnap_dt_ts219_init(void)
kirkwood_ge00_init(&qnap_ts219_ge00_data);
}
-
-/* FIXME: Will not work with DT. Maybe use MPP40_GPIO? */
-static int __init ts219_pci_init(void)
-{
- if (machine_is_ts219())
- kirkwood_pcie_init(KW_PCIE0);
-
- return 0;
-}
-subsys_initcall(ts219_pci_init);
--
1.8.1.1
^ permalink raw reply related
* [RFC PATCH 6/6] ARM: kirkwood: consolidate mv643xx_eth init for DT
From: Jason Cooper @ 2013-01-23 23:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358983578.git.jason@lakedaemon.net>
replace a lot of unneeded code and files with a lookup table.
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
arch/arm/mach-kirkwood/Kconfig | 101 ------------------------
arch/arm/mach-kirkwood/Makefile | 14 ----
arch/arm/mach-kirkwood/board-dnskw.c | 7 --
arch/arm/mach-kirkwood/board-dockstar.c | 32 --------
arch/arm/mach-kirkwood/board-dreamplug.c | 35 --------
arch/arm/mach-kirkwood/board-dt.c | 114 +++++++++++++++++++--------
arch/arm/mach-kirkwood/board-goflexnet.c | 34 --------
arch/arm/mach-kirkwood/board-ib62x0.c | 29 -------
arch/arm/mach-kirkwood/board-iconnect.c | 23 ------
arch/arm/mach-kirkwood/board-lsxl.c | 36 ---------
arch/arm/mach-kirkwood/board-mplcec4.c | 35 --------
arch/arm/mach-kirkwood/board-ns2.c | 34 --------
arch/arm/mach-kirkwood/board-openblocks_a6.c | 26 ------
arch/arm/mach-kirkwood/board-usi_topkick.c | 29 -------
arch/arm/mach-kirkwood/common.h | 63 ---------------
15 files changed, 81 insertions(+), 531 deletions(-)
delete mode 100644 arch/arm/mach-kirkwood/board-dockstar.c
delete mode 100644 arch/arm/mach-kirkwood/board-dreamplug.c
delete mode 100644 arch/arm/mach-kirkwood/board-goflexnet.c
delete mode 100644 arch/arm/mach-kirkwood/board-ib62x0.c
delete mode 100644 arch/arm/mach-kirkwood/board-iconnect.c
delete mode 100644 arch/arm/mach-kirkwood/board-lsxl.c
delete mode 100644 arch/arm/mach-kirkwood/board-mplcec4.c
delete mode 100644 arch/arm/mach-kirkwood/board-ns2.c
delete mode 100644 arch/arm/mach-kirkwood/board-openblocks_a6.c
delete mode 100644 arch/arm/mach-kirkwood/board-usi_topkick.c
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index 432bee0..188651b 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -58,19 +58,6 @@ config ARCH_KIRKWOOD_DT
Say 'Y' here if you want your kernel to support the
Marvell Kirkwood using flattened device tree.
-config MACH_DREAMPLUG_DT
- bool "Marvell DreamPlug (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the
- Marvell DreamPlug (Flattened Device Tree).
-
-config MACH_ICONNECT_DT
- bool "Iomega Iconnect (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here to enable Iomega Iconnect support.
-
config MACH_DLINK_KIRKWOOD_DT
bool "D-Link Kirkwood-based NAS (Flattened Device Tree)"
select ARCH_KIRKWOOD_DT
@@ -79,14 +66,6 @@ config MACH_DLINK_KIRKWOOD_DT
Kirkwood-based D-Link NASes such as DNS-320 & DNS-325,
using Flattened Device Tree.
-config MACH_IB62X0_DT
- bool "RaidSonic IB-NAS6210, IB-NAS6220 (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the
- RaidSonic IB-NAS6210 & IB-NAS6220 devices, using
- Flattened Device Tree.
-
config MACH_TS219_DT
bool "Device Tree for QNAP TS-11X, TS-21X NAS"
select ARCH_KIRKWOOD_DT
@@ -102,29 +81,6 @@ config MACH_TS219_DT
or MV6282. If you have the wrong one, the buttons will not
work.
-config MACH_DOCKSTAR_DT
- bool "Seagate FreeAgent Dockstar (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the
- Seagate FreeAgent Dockstar (Flattened Device Tree).
-
-config MACH_GOFLEXNET_DT
- bool "Seagate GoFlex Net (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the
- Seagate GoFlex Net (Flattened Device Tree).
-
-config MACH_LSXL_DT
- bool "Buffalo Linkstation LS-XHL, LS-CHLv2 (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- select POWER_RESET_RESTART
- help
- Say 'Y' here if you want your kernel to support the
- Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using
- Flattened Device Tree.
-
config MACH_IOMEGA_IX2_200_DT
bool "Iomega StorCenter ix2-200 (Flattened Device Tree)"
select ARCH_KIRKWOOD_DT
@@ -139,63 +95,6 @@ config MACH_KM_KIRKWOOD_DT
Say 'Y' here if you want your kernel to support the
Keymile Kirkwood Reference Desgin, using Flattened Device Tree.
-config MACH_INETSPACE_V2_DT
- bool "LaCie Internet Space v2 NAS (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the LaCie
- Internet Space v2 NAS, using Flattened Device Tree.
-
-config MACH_MPLCEC4_DT
- bool "MPL CEC4 (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the
- MPL CEC4 (Flattened Device Tree).
-
-config MACH_NETSPACE_V2_DT
- bool "LaCie Network Space v2 NAS (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the LaCie
- Network Space v2 NAS, using Flattened Device Tree.
-
-config MACH_NETSPACE_MAX_V2_DT
- bool "LaCie Network Space Max v2 NAS (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the LaCie
- Network Space Max v2 NAS, using Flattened Device Tree.
-
-config MACH_NETSPACE_LITE_V2_DT
- bool "LaCie Network Space Lite v2 NAS (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the LaCie
- Network Space Lite v2 NAS, using Flattened Device Tree.
-
-config MACH_NETSPACE_MINI_V2_DT
- bool "LaCie Network Space Mini v2 NAS (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the LaCie
- Network Space Mini v2 NAS (aka SafeBox), using Flattened
- Device Tree.
-
-config MACH_OPENBLOCKS_A6_DT
- bool "Plat'Home OpenBlocks A6 (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the
- Plat'Home OpenBlocks A6 (Flattened Device Tree).
-
-config MACH_TOPKICK_DT
- bool "USI Topkick (Flattened Device Tree)"
- select ARCH_KIRKWOOD_DT
- help
- Say 'Y' here if you want your kernel to support the
- USI Topkick, using Flattened Device Tree
-
config MACH_TS219
bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS"
help
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index ee3aa77..ab739b0 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -20,21 +20,7 @@ obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
obj-$(CONFIG_MACH_T5325) += t5325-setup.o
obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o
-obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o
-obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o
obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o
-obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o
obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o
-obj-$(CONFIG_MACH_DOCKSTAR_DT) += board-dockstar.o
-obj-$(CONFIG_MACH_GOFLEXNET_DT) += board-goflexnet.o
-obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o
obj-$(CONFIG_MACH_IOMEGA_IX2_200_DT) += board-iomega_ix2_200.o
obj-$(CONFIG_MACH_KM_KIRKWOOD_DT) += board-km_kirkwood.o
-obj-$(CONFIG_MACH_INETSPACE_V2_DT) += board-ns2.o
-obj-$(CONFIG_MACH_MPLCEC4_DT) += board-mplcec4.o
-obj-$(CONFIG_MACH_NETSPACE_V2_DT) += board-ns2.o
-obj-$(CONFIG_MACH_NETSPACE_MAX_V2_DT) += board-ns2.o
-obj-$(CONFIG_MACH_NETSPACE_LITE_V2_DT) += board-ns2.o
-obj-$(CONFIG_MACH_NETSPACE_MINI_V2_DT) += board-ns2.o
-obj-$(CONFIG_MACH_OPENBLOCKS_A6_DT) += board-openblocks_a6.o
-obj-$(CONFIG_MACH_TOPKICK_DT) += board-usi_topkick.o
diff --git a/arch/arm/mach-kirkwood/board-dnskw.c b/arch/arm/mach-kirkwood/board-dnskw.c
index a1aa87f..2af7a95 100644
--- a/arch/arm/mach-kirkwood/board-dnskw.c
+++ b/arch/arm/mach-kirkwood/board-dnskw.c
@@ -14,14 +14,9 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include "common.h"
-static struct mv643xx_eth_platform_data dnskw_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
/* Register any GPIO for output and set the value */
static void __init dnskw_gpio_register(unsigned gpio, char *name, int def)
{
@@ -36,8 +31,6 @@ static void __init dnskw_gpio_register(unsigned gpio, char *name, int def)
void __init dnskw_init(void)
{
- kirkwood_ge00_init(&dnskw_ge00_data);
-
/* Set NAS to turn back on after a power failure */
dnskw_gpio_register(37, "dnskw:power:recover", 1);
}
diff --git a/arch/arm/mach-kirkwood/board-dockstar.c b/arch/arm/mach-kirkwood/board-dockstar.c
deleted file mode 100644
index d7196db..0000000
--- a/arch/arm/mach-kirkwood/board-dockstar.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/board-dockstar.c
- *
- * Seagate FreeAgent Dockstar Board Init for drivers not converted to
- * flattened device tree yet.
- *
- * 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.
- *
- * Copied and modified for Seagate GoFlex Net support by
- * Joshua Coombs <josh.coombs@gmail.com> based on ArchLinux ARM's
- * GoFlex kernel patches.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mv643xx_eth.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data dockstar_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
-};
-
-void __init dockstar_dt_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
- kirkwood_ge00_init(&dockstar_ge00_data);
-}
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c
deleted file mode 100644
index 0903242..0000000
--- a/arch/arm/mach-kirkwood/board-dreamplug.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
- *
- * arch/arm/mach-kirkwood/board-dreamplug.c
- *
- * Marvell DreamPlug Reference Board Init for drivers not converted to
- * flattened device tree yet.
- *
- * 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/init.h>
-#include <linux/mv643xx_eth.h>
-#include <linux/gpio.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data dreamplug_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
-};
-
-static struct mv643xx_eth_platform_data dreamplug_ge01_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(1),
-};
-
-void __init dreamplug_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
- kirkwood_ge00_init(&dreamplug_ge00_data);
- kirkwood_ge01_init(&dreamplug_ge01_data);
-}
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 73b76e4..f5bd640 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -93,6 +93,86 @@ static int __init kirkwood_pcie_dt_init(void)
}
subsys_initcall(kirkwood_pcie_dt_init);
+struct kirkwood_dt_gige {
+ const char *compatible;
+ int phy_addr00;
+ int phy_addr01;
+};
+
+static struct kirkwood_dt_gige kw_dt_gige[] = {
+ { .compatible = "buffalo,lsxl",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
+ .phy_addr01 = MV643XX_ETH_PHY_ADDR(8) },
+ { .compatible = "dlink,dns-kirkwood",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "globalscale,dreamplug",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
+ .phy_addr01 = MV643XX_ETH_PHY_ADDR(1) },
+ { .compatible = "iom,iconnect",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(11),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "lacie,inetspace_v2",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "lacie,netspace_v2",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "lacie,netspace_max_v2",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "lacie,netspace_lite_v2",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "lacie,netspace_mini_v2",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "mpl,cec4",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(1),
+ .phy_addr01 = MV643XX_ETH_PHY_ADDR(2) },
+ { .compatible = "plathome,openblocks-a6",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "raidsonic,ib-nas62x0",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "seagate,dockstar",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "seagate,goflexnet",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { .compatible = "usi,topkick",
+ .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
+ .phy_addr01 = MV643XX_ETH_PHY_NONE },
+ { NULL, MV643XX_ETH_PHY_NONE, MV643XX_ETH_PHY_NONE },
+};
+
+static void kirkwood_gige_dt_init(void) {
+ int i;
+
+ for (i = 0; kw_dt_gige[i].compatible != NULL; i++) {
+ if (of_machine_is_compatible(kw_dt_gige[i].compatible)) {
+
+ if (kw_dt_gige[i].phy_addr00 != MV643XX_ETH_PHY_NONE) {
+ struct mv643xx_eth_platform_data d = {
+ .phy_addr = kw_dt_gige[i].phy_addr00,
+ };
+ kirkwood_ge00_init(&d);
+ }
+
+ if (kw_dt_gige[i].phy_addr01 != MV643XX_ETH_PHY_NONE) {
+ struct mv643xx_eth_platform_data d = {
+ .phy_addr = kw_dt_gige[i].phy_addr01,
+ };
+ kirkwood_ge01_init(&d);
+ }
+
+ break;
+ }
+ }
+}
+
static void __init kirkwood_dt_init(void)
{
pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk);
@@ -118,52 +198,20 @@ static void __init kirkwood_dt_init(void)
kexec_reinit = kirkwood_enable_pcie;
#endif
- if (of_machine_is_compatible("globalscale,dreamplug"))
- dreamplug_init();
+ kirkwood_gige_dt_init();
if (of_machine_is_compatible("dlink,dns-kirkwood"))
dnskw_init();
- if (of_machine_is_compatible("iom,iconnect"))
- iconnect_init();
-
- if (of_machine_is_compatible("raidsonic,ib-nas62x0"))
- ib62x0_init();
-
if (of_machine_is_compatible("qnap,ts219"))
qnap_dt_ts219_init();
- if (of_machine_is_compatible("seagate,dockstar"))
- dockstar_dt_init();
-
- if (of_machine_is_compatible("seagate,goflexnet"))
- goflexnet_init();
-
- if (of_machine_is_compatible("buffalo,lsxl"))
- lsxl_init();
-
if (of_machine_is_compatible("iom,ix2-200"))
iomega_ix2_200_init();
if (of_machine_is_compatible("keymile,km_kirkwood"))
km_kirkwood_init();
- if (of_machine_is_compatible("lacie,inetspace_v2") ||
- of_machine_is_compatible("lacie,netspace_v2") ||
- of_machine_is_compatible("lacie,netspace_max_v2") ||
- of_machine_is_compatible("lacie,netspace_lite_v2") ||
- of_machine_is_compatible("lacie,netspace_mini_v2"))
- ns2_init();
-
- if (of_machine_is_compatible("mpl,cec4"))
- mplcec4_init();
-
- if (of_machine_is_compatible("plathome,openblocks-a6"))
- openblocks_a6_init();
-
- if (of_machine_is_compatible("usi,topkick"))
- usi_topkick_init();
-
of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
}
diff --git a/arch/arm/mach-kirkwood/board-goflexnet.c b/arch/arm/mach-kirkwood/board-goflexnet.c
deleted file mode 100644
index 9db979a..0000000
--- a/arch/arm/mach-kirkwood/board-goflexnet.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
- *
- * arch/arm/mach-kirkwood/board-goflexnet.c
- *
- * Seagate GoFlext Net Board Init for drivers not converted to
- * flattened device tree yet.
- *
- * 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.
- *
- * Copied and modified for Seagate GoFlex Net support by
- * Joshua Coombs <josh.coombs@gmail.com> based on ArchLinux ARM's
- * GoFlex kernel patches.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mv643xx_eth.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data goflexnet_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
-};
-
-void __init goflexnet_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
- kirkwood_ge00_init(&goflexnet_ge00_data);
-}
diff --git a/arch/arm/mach-kirkwood/board-ib62x0.c b/arch/arm/mach-kirkwood/board-ib62x0.c
deleted file mode 100644
index 9a857ae..0000000
--- a/arch/arm/mach-kirkwood/board-ib62x0.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2012 (C), Simon Baatz <gmbnomis@gmail.com>
- *
- * arch/arm/mach-kirkwood/board-ib62x0.c
- *
- * RaidSonic ICY BOX IB-NAS6210 & IB-NAS6220 init for drivers not
- * converted to flattened device tree yet.
- *
- * 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/init.h>
-#include <linux/mv643xx_eth.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data ib62x0_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
-void __init ib62x0_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
- kirkwood_ge00_init(&ib62x0_ge00_data);
-}
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c
deleted file mode 100644
index ff042dc..0000000
--- a/arch/arm/mach-kirkwood/board-iconnect.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/board-iconnect.c
- *
- * Iomega i-connect Board Setup
- *
- * 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/init.h>
-#include <linux/mv643xx_eth.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data iconnect_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(11),
-};
-
-void __init iconnect_init(void)
-{
- kirkwood_ge00_init(&iconnect_ge00_data);
-}
diff --git a/arch/arm/mach-kirkwood/board-lsxl.c b/arch/arm/mach-kirkwood/board-lsxl.c
deleted file mode 100644
index 3483952..0000000
--- a/arch/arm/mach-kirkwood/board-lsxl.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2012 (C), Michael Walle <michael@walle.cc>
- *
- * arch/arm/mach-kirkwood/board-lsxl.c
- *
- * Buffalo Linkstation LS-XHL and LS-CHLv2 init for drivers not
- * converted to flattened device tree yet.
- *
- * 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/init.h>
-#include <linux/platform_device.h>
-#include <linux/mv643xx_eth.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data lsxl_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
-};
-
-static struct mv643xx_eth_platform_data lsxl_ge01_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
-void __init lsxl_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
-
- kirkwood_ge00_init(&lsxl_ge00_data);
- kirkwood_ge01_init(&lsxl_ge01_data);
-}
diff --git a/arch/arm/mach-kirkwood/board-mplcec4.c b/arch/arm/mach-kirkwood/board-mplcec4.c
deleted file mode 100644
index 938712e..0000000
--- a/arch/arm/mach-kirkwood/board-mplcec4.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 MPL AG, Switzerland
- * Stefan Peter <s.peter@mpl.ch>
- *
- * arch/arm/mach-kirkwood/board-mplcec4.c
- *
- * 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/init.h>
-#include <linux/mv643xx_eth.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data mplcec4_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(1),
-};
-
-static struct mv643xx_eth_platform_data mplcec4_ge01_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(2),
-};
-
-void __init mplcec4_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
- kirkwood_ge00_init(&mplcec4_ge00_data);
- kirkwood_ge01_init(&mplcec4_ge01_data);
-}
-
-
-
diff --git a/arch/arm/mach-kirkwood/board-ns2.c b/arch/arm/mach-kirkwood/board-ns2.c
deleted file mode 100644
index f2ea3b7..0000000
--- a/arch/arm/mach-kirkwood/board-ns2.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2012 (C), Simon Guinot <simon.guinot@sequanux.org>
- *
- * arch/arm/mach-kirkwood/board-ns2.c
- *
- * LaCie Network Space v2 board (and parents) initialization for drivers
- * not converted to flattened device tree yet.
- *
- * 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/init.h>
-#include <linux/platform_device.h>
-#include <linux/mv643xx_eth.h>
-#include <linux/of.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data ns2_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
-void __init ns2_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
- if (of_machine_is_compatible("lacie,netspace_lite_v2") ||
- of_machine_is_compatible("lacie,netspace_mini_v2"))
- ns2_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
- kirkwood_ge00_init(&ns2_ge00_data);
-}
diff --git a/arch/arm/mach-kirkwood/board-openblocks_a6.c b/arch/arm/mach-kirkwood/board-openblocks_a6.c
deleted file mode 100644
index b11d8fd..0000000
--- a/arch/arm/mach-kirkwood/board-openblocks_a6.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2012 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
- *
- * arch/arm/mach-kirkwood/board-openblocks_a6.c
- *
- * 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/init.h>
-#include <linux/mv643xx_eth.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data openblocks_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
-};
-
-void __init openblocks_a6_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
- kirkwood_ge00_init(&openblocks_ge00_data);
-}
diff --git a/arch/arm/mach-kirkwood/board-usi_topkick.c b/arch/arm/mach-kirkwood/board-usi_topkick.c
deleted file mode 100644
index 1cc04ec..0000000
--- a/arch/arm/mach-kirkwood/board-usi_topkick.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
- *
- * arch/arm/mach-kirkwood/board-usi_topkick.c
- *
- * USI Topkick Init for drivers not converted to flattened device tree yet.
- *
- * 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/init.h>
-#include <linux/mv643xx_eth.h>
-#include <linux/gpio.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data topkick_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
-};
-
-void __init usi_topkick_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
- kirkwood_ge00_init(&topkick_ge00_data);
-}
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 1c42cb8..ba6eb9c 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -55,11 +55,6 @@ void kirkwood_restart(char, const char *);
void kirkwood_clk_init(void);
/* board init functions for boards not fully converted to fdt */
-#ifdef CONFIG_MACH_DREAMPLUG_DT
-void dreamplug_init(void);
-#else
-static inline void dreamplug_init(void) {};
-#endif
#ifdef CONFIG_MACH_TS219_DT
void qnap_dt_ts219_init(void);
#else
@@ -72,36 +67,6 @@ void dnskw_init(void);
static inline void dnskw_init(void) {};
#endif
-#ifdef CONFIG_MACH_ICONNECT_DT
-void iconnect_init(void);
-#else
-static inline void iconnect_init(void) {};
-#endif
-
-#ifdef CONFIG_MACH_IB62X0_DT
-void ib62x0_init(void);
-#else
-static inline void ib62x0_init(void) {};
-#endif
-
-#ifdef CONFIG_MACH_DOCKSTAR_DT
-void dockstar_dt_init(void);
-#else
-static inline void dockstar_dt_init(void) {};
-#endif
-
-#ifdef CONFIG_MACH_GOFLEXNET_DT
-void goflexnet_init(void);
-#else
-static inline void goflexnet_init(void) {};
-#endif
-
-#ifdef CONFIG_MACH_LSXL_DT
-void lsxl_init(void);
-#else
-static inline void lsxl_init(void) {};
-#endif
-
#ifdef CONFIG_MACH_IOMEGA_IX2_200_DT
void iomega_ix2_200_init(void);
#else
@@ -114,34 +79,6 @@ void km_kirkwood_init(void);
static inline void km_kirkwood_init(void) {};
#endif
-#ifdef CONFIG_MACH_MPLCEC4_DT
-void mplcec4_init(void);
-#else
-static inline void mplcec4_init(void) {};
-#endif
-
-#if defined(CONFIG_MACH_INETSPACE_V2_DT) || \
- defined(CONFIG_MACH_NETSPACE_V2_DT) || \
- defined(CONFIG_MACH_NETSPACE_MAX_V2_DT) || \
- defined(CONFIG_MACH_NETSPACE_LITE_V2_DT) || \
- defined(CONFIG_MACH_NETSPACE_MINI_V2_DT)
-void ns2_init(void);
-#else
-static inline void ns2_init(void) {};
-#endif
-
-#ifdef CONFIG_MACH_OPENBLOCKS_A6_DT
-void openblocks_a6_init(void);
-#else
-static inline void openblocks_a6_init(void) {};
-#endif
-
-#ifdef CONFIG_MACH_TOPKICK_DT
-void usi_topkick_init(void);
-#else
-static inline void usi_topkick_init(void) {};
-#endif
-
/* early init functions not converted to fdt yet */
char *kirkwood_id(void);
void kirkwood_l2_init(void);
--
1.8.1.1
^ permalink raw reply related
* [PATCH v9 20/20] mdf: omap-usb-host: get rid of build warning
From: Mike Turquette @ 2013-01-23 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358937492-8129-21-git-send-email-rogerq@ti.com>
Quoting Roger Quadros (2013-01-23 02:38:12)
> Fixes the below build warning when driver is built-in.
>
> drivers/mfd/omap-usb-host.c:750:12: warning:
> ?usbhs_omap_remove? defined but not used [-Wunused-function]
>
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> Reviewed-by: Felipe Balbi <balbi@ti.com>
Hi Roger,
I just noticed that $SUBJECT says "mdf" instead of "mfd" ;)
Regards,
Mike
> ---
> drivers/mfd/omap-usb-host.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
> index b21ca76..6b5edf6 100644
> --- a/drivers/mfd/omap-usb-host.c
> +++ b/drivers/mfd/omap-usb-host.c
> @@ -791,7 +791,7 @@ static struct platform_driver usbhs_omap_driver = {
> .owner = THIS_MODULE,
> .pm = &usbhsomap_dev_pm_ops,
> },
> - .remove = __exit_p(usbhs_omap_remove),
> + .remove = usbhs_omap_remove,
> };
>
> MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [v4 PATCH 06/12] spi/atmel_spi: add dmaengine support
From: Yang, Wenyou @ 2013-01-24 0:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACQ1gAji8w-H_vPchw5cY8QK0b8+VOBCi=22AvmeCrmZszHSXA@mail.gmail.com>
Thanks a lot for so much comments
> -----Original Message-----
> From: Richard Genoud [mailto:richard.genoud at gmail.com]
> Sent: 2013?1?24? 0:25
> To: Yang, Wenyou
> Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Ferre,
> Nicolas; plagnioj at jcrosoft.com; Lin, JM; grant.likely at secretlab.ca;
> spi-devel-general at lists.sourceforge.net
> Subject: Re: [v4 PATCH 06/12] spi/atmel_spi: add dmaengine support
>
> 2013/1/14 Wenyou Yang <wenyou.yang@atmel.com>:
> > From: Nicolas Ferre <nicolas.ferre@atmel.com>
> >
> > Add dmaengine support.
> >
> > For different SoC, the "has_dma_support" is used to select
> > the transfer mode: dmaengine or PDC.
> >
> > For the dmaengine transfer mode, if it fails to config dmaengine,
> > or if the message len less than 16 bytes, it will use the PIO transfer mode.
> >
> > Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> > [wenyou.yang at atmel.com: using "has_dma_support" to select DMA as the
> spi xfer mode]
> > [wenyou.yang at atmel.com: add support NPCS1,2,3 chip select other than
> NPCS0]
> > [wenyou.yang at atmel.com: fix DMA: OOPS if buffer > 4096 bytes]
> > Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> > Cc: grant.likely at secretlab.ca
> > Cc: spi-devel-general at lists.sourceforge.net
> > Cc: richard.genoud at gmail.com
> > ---
> > This patch is based on the original patch from Nicolas
> > [PATCH] spi/atmel_spi: add dmaengine support
> > and merge the patches from Richard Genoud <richard.genoud@gmail.com>
> > [PATCH] spi-atmel: update with dmaengine interface
> > [PATCH] spi-atmel: fix __init/__devinit sections mismatch
> > and Wenyou Yang add the code to support selecting the spi transfer mode,
> > add support NPCS1,2,3 chip select other than NPCS0.
> > fix DMA: OOPS if buffer > 4096 bytes.
> >
> > diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
> > index 43c1f63..0d242dc 100644
> > --- a/drivers/spi/spi-atmel.c
> > +++ b/drivers/spi/spi-atmel.c
> > @@ -15,11 +15,13 @@
> > #include <linux/platform_device.h>
> > #include <linux/delay.h>
> > #include <linux/dma-mapping.h>
> > +#include <linux/dmaengine.h>
> > #include <linux/err.h>
> > #include <linux/interrupt.h>
> > #include <linux/spi/spi.h>
> > #include <linux/slab.h>
> > #include <linux/platform_data/atmel.h>
> > +#include <linux/platform_data/dma-atmel.h>
> > #include <linux/of.h>
> >
> > #include <asm/io.h>
> > @@ -182,6 +184,19 @@
> > #define spi_writel(port,reg,value) \
> > __raw_writel((value), (port)->regs + SPI_##reg)
> >
> > +/* use PIO for small transfers, avoiding DMA setup/teardown overhead and
> > + * cache operations; better heuristics consider wordsize and bitrate.
> > + */
> > +#define DMA_MIN_BYTES 16
> > +
> > +struct atmel_spi_dma {
> > + struct dma_chan *chan_rx;
> > + struct dma_chan *chan_tx;
> > + struct scatterlist sgrx;
> > + struct scatterlist sgtx;
> > + struct dma_async_tx_descriptor *data_desc_rx;
> > + struct dma_async_tx_descriptor *data_desc_tx;
> > +};
> >
> > /*
> > * The core SPI transfer engine just talks to a register bank to set up
> > @@ -192,6 +207,7 @@ struct atmel_spi_pdata {
> > u8 version;
> > bool has_dma_support;
> > bool has_wdrbt;
> > + struct at_dma_slave dma_slave;
> > };
> >
> > struct atmel_spi {
> > @@ -207,6 +223,7 @@ struct atmel_spi {
> >
> > u8 stopping;
> > struct list_head queue;
> > + struct tasklet_struct tasklet;
> > struct spi_transfer *current_transfer;
> > unsigned long current_remaining_bytes;
> > struct spi_transfer *next_transfer;
> > @@ -214,8 +231,15 @@ struct atmel_spi {
> > int done_status;
> > struct atmel_spi_pdata *pdata;
> >
> > + bool use_dma;
> > + bool use_pdc;
> > +
> > + /* scratch buffer */
> > void *buffer;
> > dma_addr_t buffer_dma;
> > +
> > + /* dmaengine data */
> > + struct atmel_spi_dma dma;
> > };
> >
> > /* Controller-specific per-slave state */
> > @@ -328,9 +352,7 @@ static bool atmel_spi_is_v2(struct atmel_spi *as)
> > * and (c) will trigger that first erratum in some cases.
> > *
> > * TODO: Test if the atmel_spi_is_v2() branch below works on
> > - * AT91RM9200 if we use some other register than CSR0. However, don't
> > - * do this unconditionally since AP7000 has an errata where the BITS
> > - * field in CSR0 overrides all other CSRs.
> > + * AT91RM9200 if we use some other register than CSR0.
> > */
> >
> > static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
> > @@ -340,18 +362,16 @@ static void cs_activate(struct atmel_spi *as,
> struct spi_device *spi)
> > u32 mr;
> >
> > if (atmel_spi_is_v2(as)) {
> > - /*
> > - * Always use CSR0. This ensures that the clock
> > - * switches to the correct idle polarity before we
> > - * toggle the CS.
> > - */
> > - spi_writel(as, CSR0, asd->csr);
> > + spi_writel(as, CSR0 + 4 * spi->chip_select, asd->csr);
> >
> > if (as->pdata->has_wdrbt)
> > - spi_writel(as, MR, SPI_BF(PCS, 0x0e) |
> SPI_BIT(MSTR)
> > - | SPI_BIT(MODFDIS) |
> SPI_BIT(WDRBT));
> > + spi_writel(as, MR,
> > + SPI_BF(PCS, ~(0x01 <<
> spi->chip_select))
> > + | SPI_BIT(MSTR) |
> SPI_BIT(MODFDIS)
> > + | SPI_BIT(WDRBT));
> > else
> > - spi_writel(as, MR, SPI_BF(PCS, 0x0e)
> > + spi_writel(as, MR,
> > + SPI_BF(PCS, ~(0x01 <<
> spi->chip_select))
> > | SPI_BIT(MSTR) |
> SPI_BIT(MODFDIS));
> >
> > mr = spi_readl(as, MR);
> > @@ -414,6 +434,12 @@ static void atmel_spi_unlock(struct atmel_spi *as)
> > spin_unlock_irqrestore(&as->lock, as->flags);
> > }
> >
> > +static inline bool atmel_spi_use_dma(struct atmel_spi *as,
> > + struct spi_transfer *xfer)
> > +{
> > + return as->use_dma && xfer->len >= DMA_MIN_BYTES;
> > +}
> > +
> > static inline int atmel_spi_xfer_is_last(struct spi_message *msg,
> > struct spi_transfer *xfer)
> > {
> > @@ -425,6 +451,220 @@ static inline int
> atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer)
> > return xfer->delay_usecs == 0 && !xfer->cs_change;
> > }
> >
> > +static bool filter(struct dma_chan *chan, void *slave)
> > +{
> > + struct at_dma_slave *sl = slave;
> > +
> > + if (sl->dma_dev == chan->device->dev) {
> > + chan->private = sl;
> > + return true;
> > + } else {
> > + return false;
> > + }
> > +}
> > +
> > +static int __devinit atmel_spi_configure_dma(struct atmel_spi *as)
> > +{
> > + struct at_dma_slave *sdata
> > + = (struct at_dma_slave
> *)&as->pdata->dma_slave;
> > +
> > + if (sdata && sdata->dma_dev) {
> > + dma_cap_mask_t mask;
> > +
> > + /* setup DMA addresses */
> > + sdata->rx_reg = (dma_addr_t)as->phybase + SPI_RDR;
> > + sdata->tx_reg = (dma_addr_t)as->phybase + SPI_TDR;
> > +
> > + /* Try to grab two DMA channels */
> > + dma_cap_zero(mask);
> > + dma_cap_set(DMA_SLAVE, mask);
> > + as->dma.chan_tx = dma_request_channel(mask, filter,
> sdata);
> > + if (as->dma.chan_tx)
> > + as->dma.chan_rx =
> > + dma_request_channel(mask, filter,
> sdata);
> > + }
> > + if (!as->dma.chan_rx || !as->dma.chan_tx) {
> > + if (as->dma.chan_rx)
> > + dma_release_channel(as->dma.chan_rx);
> > + if (as->dma.chan_tx)
> > + dma_release_channel(as->dma.chan_tx);
> > + dev_err(&as->pdev->dev,
> > + "DMA channel not available, unable to use
> SPI\n");
> > + return -EBUSY;
> > + }
> > +
> > + dev_info(&as->pdev->dev,
> > + "Using %s (tx) and %s (rx) for DMA
> transfers\n",
> > + dma_chan_name(as->dma.chan_tx),
> > + dma_chan_name(as->dma.chan_rx));
> > +
> > + return 0;
> > +}
> > +
> > +static void atmel_spi_stop_dma(struct atmel_spi *as)
> > +{
> > + if (as->dma.chan_rx)
> > +
> as->dma.chan_rx->device->device_control(as->dma.chan_rx,
> > +
> DMA_TERMINATE_ALL, 0);
> > + if (as->dma.chan_tx)
> > +
> as->dma.chan_tx->device->device_control(as->dma.chan_tx,
> > +
> DMA_TERMINATE_ALL, 0);
> > +}
> > +
> > +static void atmel_spi_release_dma(struct atmel_spi *as)
> > +{
> > + if (as->dma.chan_rx)
> > + dma_release_channel(as->dma.chan_rx);
> > + if (as->dma.chan_tx)
> > + dma_release_channel(as->dma.chan_tx);
> > +}
> > +
> > +/* This function is called by the DMA driver from tasklet context */
> > +static void dma_callback(void *data)
> > +{
> > + struct spi_master *master = data;
> > + struct atmel_spi *as = spi_master_get_devdata(master);
> > +
> > + /* trigger SPI tasklet */
> > + tasklet_schedule(&as->tasklet);
> > +}
> > +
> > +/*
> > + * Next transfer using PIO.
> > + * lock is held, spi tasklet is blocked
> > + */
> > +static void atmel_spi_next_xfer_pio(struct spi_master *master,
> > + struct spi_transfer *xfer)
> > +{
> > + struct atmel_spi *as = spi_master_get_devdata(master);
> > +
> > + dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_pio\n");
> > +
> > + as->current_remaining_bytes = xfer->len;
> > +
> > + /* Make sure data is not remaining in RDR */
> > + spi_readl(as, RDR);
> > + while (spi_readl(as, SR) & SPI_BIT(RDRF)) {
> > + spi_readl(as, RDR);
> > + cpu_relax();
> > + }
> > +
> > + if (xfer->tx_buf)
> > + spi_writel(as, TDR, *(u8 *)(xfer->tx_buf));
> > + else
> > + spi_writel(as, TDR, 0);
> > +
> > + dev_dbg(master->dev.parent,
> > + " start pio xfer %p: len %u tx %p rx %p\n",
> > + xfer, xfer->len, xfer->tx_buf, xfer->rx_buf);
> > +
> > + /* Enable relevant interrupts */
> > + spi_writel(as, IER, SPI_BIT(RDRF) | SPI_BIT(OVRES));
> > +}
> > +
> > +/*
> > + * Submit next transfer for DMA.
> > + * lock is held, spi tasklet is blocked
> > + */
> > +static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
> > + struct spi_transfer *xfer,
> > + u32 *plen)
> > +{
> > + struct atmel_spi *as = spi_master_get_devdata(master);
> > + struct dma_chan *rxchan = as->dma.chan_rx;
> > + struct dma_chan *txchan = as->dma.chan_tx;
> > + struct dma_async_tx_descriptor *rxdesc;
> > + struct dma_async_tx_descriptor *txdesc;
> > + dma_cookie_t cookie;
> > + u32 len = *plen;
> > +
> > + dev_vdbg(master->dev.parent,
> "atmel_spi_next_xfer_dma_submit\n");
> > +
> > + /* Check that the channels are available */
> > + if (!rxchan || !txchan)
> > + return -ENODEV;
> > +
> > + /* release lock for DMA operations */
> > + atmel_spi_unlock(as);
> > +
> > + /* prepare the RX dma transfer */
> > + sg_init_table(&as->dma.sgrx, 1);
> > + if (xfer->rx_buf)
> > + as->dma.sgrx.dma_address = xfer->rx_dma + xfer->len -
> *plen;
> > + else {
> > + as->dma.sgrx.dma_address = as->buffer_dma;
> > + if (len > BUFFER_SIZE)
> > + len = BUFFER_SIZE;
> > + }
> You should use brackets before the "else" also.
> cf Documentation/CodingStyle line 169 :
>
> This does not apply if only one branch of a conditional statement is a single
> statement; in the latter case use braces in both branches:
>
> if (condition) {
> do_this();
> do_that();
> } else {
> otherwise();
> }
>
>
> > +
> > + /* prepare the TX dma transfer */
> > + sg_init_table(&as->dma.sgtx, 1);
> > + if (xfer->tx_buf) {
> > + as->dma.sgtx.dma_address = xfer->tx_dma + xfer->len -
> *plen;
> > + } else {
> > + as->dma.sgtx.dma_address = as->buffer_dma;
> > + if (len > BUFFER_SIZE)
> > + len = BUFFER_SIZE;
> > + memset(as->buffer, 0, len);
> > + }
> > +
> > + sg_dma_len(&as->dma.sgtx) = len;
> > + sg_dma_len(&as->dma.sgrx) = len;
> > +
> > + *plen = len;
> > +
> > + /* Send both scatterlists */
> > + rxdesc = rxchan->device->device_prep_slave_sg(rxchan,
> > + &as->dma.sgrx,
> > + 1,
> > + DMA_FROM_DEVICE,
> > + DMA_PREP_INTERRUPT |
> DMA_CTRL_ACK,
> > + NULL);
> > + if (!rxdesc)
> > + goto err_dma;
> > +
> > + txdesc = txchan->device->device_prep_slave_sg(txchan,
> > + &as->dma.sgtx,
> > + 1,
> > + DMA_TO_DEVICE,
> > + DMA_PREP_INTERRUPT |
> DMA_CTRL_ACK,
> > + NULL);
> > + if (!txdesc)
> > + goto err_dma;
> > +
> > + dev_dbg(master->dev.parent,
> > + " start dma xfer %p: len %u tx %p/%08x rx %p/%08x\n",
> > + xfer, xfer->len, xfer->tx_buf, xfer->tx_dma,
> > + xfer->rx_buf, xfer->rx_dma);
> > +
> > + /* Enable relevant interrupts */
> > + spi_writel(as, IER, SPI_BIT(OVRES));
> > +
> > + /* Put the callback on the RX transfer only, that should finish last */
> > + rxdesc->callback = dma_callback;
> > + rxdesc->callback_param = master;
> > +
> > + /* Submit and fire RX and TX with TX last so we're ready to read! */
> > + cookie = rxdesc->tx_submit(rxdesc);
> > + if (dma_submit_error(cookie))
> > + goto err_dma;
> > + cookie = txdesc->tx_submit(txdesc);
> > + if (dma_submit_error(cookie))
> > + goto err_dma;
> > + rxchan->device->device_issue_pending(rxchan);
> > + txchan->device->device_issue_pending(txchan);
> > +
> > + /* take back lock */
> > + atmel_spi_lock(as);
> > + return 0;
> > +
> > +err_dma:
> > + spi_writel(as, IDR, SPI_BIT(OVRES));
> > + atmel_spi_stop_dma(as);
> > + atmel_spi_lock(as);
> > + return -ENOMEM;
> > +}
> > +
> > static void atmel_spi_next_xfer_data(struct spi_master *master,
> > struct spi_transfer *xfer,
> > dma_addr_t *tx_dma,
> > @@ -457,10 +697,10 @@ static void atmel_spi_next_xfer_data(struct
> spi_master *master,
> > }
> >
> > /*
> > - * Submit next transfer for DMA.
> > + * Submit next transfer for PDC.
> > * lock is held, spi irq is blocked
> > */
> > -static void atmel_spi_next_xfer(struct spi_master *master,
> > +static void atmel_spi_next_xfer_pdc(struct spi_master *master,
> > struct spi_message *msg)
> > {
> > struct atmel_spi *as = spi_master_get_devdata(master);
> > @@ -557,6 +797,49 @@ static void atmel_spi_next_xfer(struct spi_master
> *master,
> > spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN));
> > }
> >
> > +/*
> > + * Choose way to submit next transfer and start it.
> > + * lock is held, spi tasklet is blocked
> > + */
> > +static void atmel_spi_next_xfer_dma(struct spi_master *master,
> > + struct spi_message *msg)
> > +{
> > + struct atmel_spi *as = spi_master_get_devdata(master);
> > + struct spi_transfer *xfer;
> > + u32 remaining, len;
> > +
> > + dev_vdbg(&msg->spi->dev, "atmel_spi_next_xfer\n");
> > +
> > + remaining = as->current_remaining_bytes;
> > + if (remaining) {
> > + xfer = as->current_transfer;
> > + len = remaining;
> > + } else {
> > + if (!as->current_transfer)
> > + xfer = list_entry(msg->transfers.next,
> > + struct spi_transfer, transfer_list);
> > + else
> > + xfer = list_entry(
> > +
> as->current_transfer->transfer_list.next,
> > + struct spi_transfer,
> transfer_list);
> > +
> > + as->current_transfer = xfer;
> > + len = xfer->len;
> > + }
> > +
> > + if (atmel_spi_use_dma(as, xfer)) {
> > + u32 total = len;
> > + if (!atmel_spi_next_xfer_dma_submit(master, xfer, &len))
> {
> > + as->current_remaining_bytes = total - len;
> > + return;
> > + } else
> > + dev_err(&msg->spi->dev, "unable to use DMA,
> fallback to PIO\n");
> same here.
> > + }
> > +
> > + /* use PIO if error appened using DMA */
> > + atmel_spi_next_xfer_pio(master, xfer);
> > +}
> > +
> > static void atmel_spi_next_message(struct spi_master *master)
> > {
> > struct atmel_spi *as = spi_master_get_devdata(master);
> > @@ -581,7 +864,10 @@ static void atmel_spi_next_message(struct
> spi_master *master)
> > } else
> > cs_activate(as, spi);
> >
> > - atmel_spi_next_xfer(master, msg);
> > + if (as->use_pdc)
> > + atmel_spi_next_xfer_pdc(master, msg);
> > + else
> > + atmel_spi_next_xfer_dma(master, msg);
> > }
> >
> > /*
> > @@ -634,6 +920,11 @@ static void atmel_spi_dma_unmap_xfer(struct
> spi_master *master,
> > xfer->len, DMA_FROM_DEVICE);
> > }
> >
> > +static void atmel_spi_disable_pdc_transfer(struct atmel_spi *as)
> > +{
> > + spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
> > +}
> > +
> > static void
> > atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,
> > struct spi_message *msg, int stay)
> > @@ -659,19 +950,175 @@ atmel_spi_msg_done(struct spi_master *master,
> struct atmel_spi *as,
> > as->done_status = 0;
> >
> > /* continue if needed */
> > - if (list_empty(&as->queue) || as->stopping)
> > - spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
> > - else
> > + if (list_empty(&as->queue) || as->stopping) {
> > + if (as->use_pdc)
> > + atmel_spi_disable_pdc_transfer(as);
> > + } else
> > atmel_spi_next_message(master);
> same.
> > }
> >
> > -static irqreturn_t
> > -atmel_spi_interrupt(int irq, void *dev_id)
> > +/* Called from IRQ
> > + * lock is held
> > + *
> > + * Must update "current_remaining_bytes" to keep track of data
> > + * to transfer.
> > + */
> > +static void
> > +atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer)
> > {
> > - struct spi_master *master = dev_id;
> > + u8 *txp;
> > + u8 *rxp;
> > + unsigned long xfer_pos = xfer->len -
> as->current_remaining_bytes;
> > +
> > + if (xfer->rx_buf) {
> > + rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
> > + *rxp = spi_readl(as, RDR);
> > + } else {
> > + spi_readl(as, RDR);
> > + }
> > +
> > + as->current_remaining_bytes--;
> > +
> > + if (as->current_remaining_bytes) {
> > + if (xfer->tx_buf) {
> > + txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1;
> > + spi_writel(as, TDR, *txp);
> > + } else {
> > + spi_writel(as, TDR, 0);
> > + }
> > + }
> > +}
> > +
> > +/* Tasklet
> > + * Called from DMA callback + pio transfer and overrun IRQ.
> > + */
> > +static void atmel_spi_tasklet_func(unsigned long data)
> > +{
> > + struct spi_master *master = (struct spi_master *)data;
> > struct atmel_spi *as = spi_master_get_devdata(master);
> > struct spi_message *msg;
> > struct spi_transfer *xfer;
> > +
> > + dev_vdbg(master->dev.parent, "atmel_spi_tasklet_func\n");
> > +
> > + atmel_spi_lock(as);
> > +
> > + xfer = as->current_transfer;
> > +
> > + if (xfer == NULL)
> > + /* already been there */
> > + goto tasklet_out;
> > +
> > + msg = list_entry(as->queue.next, struct spi_message, queue);
> > +
> > + if (as->current_remaining_bytes == 0) {
> > + if (as->done_status < 0) {
> > + /* error happened (overrun) */
> > + if (atmel_spi_use_dma(as, xfer))
> > + atmel_spi_stop_dma(as);
> > + } else
> > + /* only update length if no error */
> > + msg->actual_length += xfer->len;
> same
> > +
> > + if (atmel_spi_use_dma(as, xfer))
> > + if (!msg->is_dma_mapped)
> > + atmel_spi_dma_unmap_xfer(master,
> xfer);
> > +
> > + if (xfer->delay_usecs)
> > + udelay(xfer->delay_usecs);
> > +
> > + if (atmel_spi_xfer_is_last(msg, xfer) || as->done_status <
> 0)
> > + /* report completed (or erroneous) message */
> > + atmel_spi_msg_done(master, as, msg,
> xfer->cs_change);
> > + else {
> same
> > + if (xfer->cs_change) {
> > + cs_deactivate(as, msg->spi);
> > + udelay(1);
> > + cs_activate(as, msg->spi);
> > + }
> > +
> > + /*
> > + * Not done yet. Submit the next transfer.
> > + *
> > + * FIXME handle protocol options for xfer
> > + */
> > + atmel_spi_next_xfer_dma(master, msg);
> > + }
> > + } else
> same
> > + /*
> > + * Keep going, we still have data to send in
> > + * the current transfer.
> > + */
> > + atmel_spi_next_xfer_dma(master, msg);
> > +
> > +tasklet_out:
> > + atmel_spi_unlock(as);
> > +}
> > +
> > +static int atmel_spi_interrupt_dma(struct atmel_spi *as,
> > + struct spi_master *master)
> > +{
> > + u32 status, pending, imr;
> > + struct spi_transfer *xfer;
> > + int ret = IRQ_NONE;
> > +
> > + imr = spi_readl(as, IMR);
> > + status = spi_readl(as, SR);
> > + pending = status & imr;
> > +
> > + if (pending & SPI_BIT(OVRES)) {
> > + ret = IRQ_HANDLED;
> > + spi_writel(as, IDR, SPI_BIT(OVRES));
> > + dev_warn(master->dev.parent, "overrun\n");
> > +
> > + /*
> > + * When we get an overrun, we disregard the current
> > + * transfer. Data will not be copied back from any
> > + * bounce buffer and msg->actual_len will not be
> > + * updated with the last xfer.
> > + *
> > + * We will also not process any remaning transfers in
> > + * the message.
> > + *
> > + * All actions are done in tasklet with done_status
> indication
> > + */
> > + as->done_status = -EIO;
> > + smp_wmb();
> > +
> > + /* Clear any overrun happening while cleaning up */
> > + spi_readl(as, SR);
> > +
> > + tasklet_schedule(&as->tasklet);
> > +
> > + } else if (pending & SPI_BIT(RDRF)) {
> > + atmel_spi_lock(as);
> > +
> > + if (as->current_remaining_bytes) {
> > + ret = IRQ_HANDLED;
> > + xfer = as->current_transfer;
> > + atmel_spi_pump_pio_data(as, xfer);
> > + if (!as->current_remaining_bytes) {
> > + /* no more data to xfer, kick tasklet */
> > + spi_writel(as, IDR, pending);
> > + tasklet_schedule(&as->tasklet);
> > + }
> > + }
> > +
> > + atmel_spi_unlock(as);
> > + } else {
> > + WARN_ONCE(pending, "IRQ not handled, pending
> = %x\n", pending);
> > + ret = IRQ_HANDLED;
> > + spi_writel(as, IDR, pending);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static int atmel_spi_interrupt_pdc(struct atmel_spi *as,
> > + struct spi_master *master)
> > +{
> > + struct spi_message *msg;
> > + struct spi_transfer *xfer;
> > u32 status, pending, imr;
> > int ret = IRQ_NONE;
> >
> > @@ -767,14 +1214,14 @@ atmel_spi_interrupt(int irq, void *dev_id)
> > *
> > * FIXME handle protocol options for
> xfer
> > */
> > - atmel_spi_next_xfer(master, msg);
> > + atmel_spi_next_xfer_pdc(master,
> msg);
> > }
> > } else {
> > /*
> > * Keep going, we still have data to send in
> > * the current transfer.
> > */
> > - atmel_spi_next_xfer(master, msg);
> > + atmel_spi_next_xfer_pdc(master, msg);
> > }
> > }
> >
> > @@ -783,6 +1230,27 @@ atmel_spi_interrupt(int irq, void *dev_id)
> > return ret;
> > }
> >
> > +/* Interrupt
> > + *
> > + * No need for locking in this Interrupt handler: done_status is the
> > + * only information modified. What we need is the update of this field
> > + * before tasklet runs. This is ensured by using barrier.
> > + */
> > +static irqreturn_t
> > +atmel_spi_interrupt(int irq, void *dev_id)
> > +{
> > + struct spi_master *master = dev_id;
> > + struct atmel_spi *as = spi_master_get_devdata(master);
> > + int ret;
> > +
> > + if (as->use_pdc)
> > + ret = atmel_spi_interrupt_pdc(as, master);
> > + else
> > + ret = atmel_spi_interrupt_dma(as, master);
> > +
> > + return ret;
> > +}
> > +
> > static int atmel_spi_setup(struct spi_device *spi)
> > {
> > struct atmel_spi *as;
> > @@ -945,13 +1413,10 @@ static int atmel_spi_transfer(struct spi_device
> *spi, struct spi_message *msg)
> >
> > /*
> > * DMA map early, for performance (empties dcache
> ASAP) and
> > - * better fault reporting. This is a DMA-only driver.
> > - *
> > - * NOTE that if dma_unmap_single() ever starts to do
> work on
> > - * platforms supported by this driver, we would need to
> clean
> > - * up mappings for previously-mapped transfers.
> > + * better fault reporting.
> > */
> > - if (!msg->is_dma_mapped) {
> > + if ((!msg->is_dma_mapped) && (atmel_spi_use_dma(as,
> xfer)
> > + || as->use_pdc)) {
> > if (atmel_spi_dma_map_xfer(as, xfer) < 0)
> > return -ENOMEM;
> > }
> > @@ -1068,6 +1533,8 @@ static int atmel_spi_probe(struct platform_device
> *pdev)
> >
> > spin_lock_init(&as->lock);
> > INIT_LIST_HEAD(&as->queue);
> > + tasklet_init(&as->tasklet, atmel_spi_tasklet_func,
> > + (unsigned long)master);
> > as->pdev = pdev;
> > as->regs = ioremap(regs->start, resource_size(regs));
> > if (!as->regs)
> > @@ -1096,7 +1563,15 @@ static int atmel_spi_probe(struct
> platform_device *pdev)
> > else
> > spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS));
> >
> > - spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
> > + as->use_dma = false;
> > + as->use_pdc = false;
> > +
> > + if (as->pdata->has_dma_support) {
> > + if (atmel_spi_configure_dma(as) == 0)
> > + as->use_dma = true;
> > + } else
> > + as->use_pdc = true;
> same.
>
> Maybe you should add a little dev_info in case both use_dma and
> use_pcd are null:
> if (!as->use_dma && !as->use_pdc)
> dev_info(&pdev->dev, "Atmel SPI Controller: Using PIO only for transferts");
>
> I tested it on sam9g35.
> It's working *almost* all right.
> I've got a problem with the ioctl SPI_IOC_MESSAGE().
> (cf Documentation/spi/spidev_fdx.c)
> I'm reading on spidev something like that :
> struct spi_ioc_transfer xfer[3];
> memset(xfer, 0, sizeof(xfer));
> xfer[0].tx_buf = (unsigned long)&tx_header;
> xer[0].rx_buf = (unsigned long)&rx_header;
> xfer[0].len = 2;
> xfer[1].rx_buf = (unsigned long)rx_buf;
> xfer[1].len = 124;
> xfer[2].tx_buf = (unsigned long)&tx_footer;
> xfer[2].rx_buf = (unsigned long)&rx_footer;
> xfer[2].len = 2;
>
> nb = ioctl(spi_data->fd, SPI_IOC_MESSAGE(3), xfer);
>
> If I force DMA all the time with
> #define DMA_MIN_BYTES 1
> I haven't got any problem, all works ok.
> If I for PIO all the time with
> #define DMA_MIN_BYTES 1000
> I'ts woking also without any problem.
>
> BUT
> When the DMA_MIN_BYTES are at 16 (so, xfer[0] is transfered by PIO,
> xfer[1] by DMA and xfer[2] by PIO), I've got a lot of errors in my
> rx_buffer.
> ie, I'm not receiving what I should.
>
> Did you experience anything like that ?
No, I didn't try it. I will do next week.
>
> Regards,
> Richard
Best Regards,
Wenyou Yang
^ permalink raw reply
* [PATCH v3 0/3] introduce static_vm for ARM-specific static mapped area
From: Joonsoo Kim @ 2013-01-24 1:28 UTC (permalink / raw)
To: linux-arm-kernel
In current implementation, we used ARM-specific flag, that is,
VM_ARM_STATIC_MAPPING, for distinguishing ARM specific static mapped area.
The purpose of static mapped area is to re-use static mapped area when
entire physical address range of the ioremap request can be covered
by this area.
This implementation causes needless overhead for some cases.
For example, assume that there is only one static mapped area and
vmlist has 300 areas. Every time we call ioremap, we check 300 areas for
deciding whether it is matched or not. Moreover, even if there is
no static mapped area and vmlist has 300 areas, every time we call
ioremap, we check 300 areas in now.
If we construct a extra list for static mapped area, we can eliminate
above mentioned overhead.
With a extra list, if there is one static mapped area,
we just check only one area and proceed next operation quickly.
In fact, it is not a critical problem, because ioremap is not frequently
used. But reducing overhead is better idea.
Another reason for doing this work is for removing vm_struct list management,
entirely. For more information, look at the following link.
http://lkml.org/lkml/2012/12/6/184
Changelog
v2->v3:
coverletter: refer a link related to this work
[2/3]: drop @flags of find_static_vm_vaddr
Rebased on v3.8-rc4
v1->v2:
[2/3]: patch description is improved.
Rebased on v3.7-rc7
Joonsoo Kim (3):
ARM: vmregion: remove vmregion code entirely
ARM: static_vm: introduce an infrastructure for static mapped area
ARM: mm: use static_vm for managing static mapped areas
arch/arm/include/asm/mach/static_vm.h | 51 ++++++++
arch/arm/mm/Makefile | 2 +-
arch/arm/mm/ioremap.c | 69 ++++-------
arch/arm/mm/mm.h | 10 --
arch/arm/mm/mmu.c | 54 +++++----
arch/arm/mm/static_vm.c | 94 +++++++++++++++
arch/arm/mm/vmregion.c | 205 ---------------------------------
arch/arm/mm/vmregion.h | 31 -----
8 files changed, 204 insertions(+), 312 deletions(-)
create mode 100644 arch/arm/include/asm/mach/static_vm.h
create mode 100644 arch/arm/mm/static_vm.c
delete mode 100644 arch/arm/mm/vmregion.c
delete mode 100644 arch/arm/mm/vmregion.h
--
1.7.9.5
^ permalink raw reply
* [PATCH v3 1/3] ARM: vmregion: remove vmregion code entirely
From: Joonsoo Kim @ 2013-01-24 1:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358990934-4893-1-git-send-email-iamjoonsoo.kim@lge.com>
From: Joonsoo Kim <js1304@gmail.com>
Now, there is no user for vmregion.
So remove it.
Signed-off-by: Joonsoo Kim <js1304@gmail.com>
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 8a9c4cb..4e333fa 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -6,7 +6,7 @@ obj-y := dma-mapping.o extable.o fault.o init.o \
iomap.o
obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \
- mmap.o pgd.o mmu.o vmregion.o
+ mmap.o pgd.o mmu.o
ifneq ($(CONFIG_MMU),y)
obj-y += nommu.o
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
deleted file mode 100644
index a631016..0000000
--- a/arch/arm/mm/vmregion.c
+++ /dev/null
@@ -1,205 +0,0 @@
-#include <linux/fs.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-
-#include "vmregion.h"
-
-/*
- * VM region handling support.
- *
- * This should become something generic, handling VM region allocations for
- * vmalloc and similar (ioremap, module space, etc).
- *
- * I envisage vmalloc()'s supporting vm_struct becoming:
- *
- * struct vm_struct {
- * struct vmregion region;
- * unsigned long flags;
- * struct page **pages;
- * unsigned int nr_pages;
- * unsigned long phys_addr;
- * };
- *
- * get_vm_area() would then call vmregion_alloc with an appropriate
- * struct vmregion head (eg):
- *
- * struct vmregion vmalloc_head = {
- * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list),
- * .vm_start = VMALLOC_START,
- * .vm_end = VMALLOC_END,
- * };
- *
- * However, vmalloc_head.vm_start is variable (typically, it is dependent on
- * the amount of RAM found at boot time.) I would imagine that get_vm_area()
- * would have to initialise this each time prior to calling vmregion_alloc().
- */
-
-struct arm_vmregion *
-arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
- size_t size, gfp_t gfp, const void *caller)
-{
- unsigned long start = head->vm_start, addr = head->vm_end;
- unsigned long flags;
- struct arm_vmregion *c, *new;
-
- if (head->vm_end - head->vm_start < size) {
- printk(KERN_WARNING "%s: allocation too big (requested %#x)\n",
- __func__, size);
- goto out;
- }
-
- new = kmalloc(sizeof(struct arm_vmregion), gfp);
- if (!new)
- goto out;
-
- new->caller = caller;
-
- spin_lock_irqsave(&head->vm_lock, flags);
-
- addr = rounddown(addr - size, align);
- list_for_each_entry_reverse(c, &head->vm_list, vm_list) {
- if (addr >= c->vm_end)
- goto found;
- addr = rounddown(c->vm_start - size, align);
- if (addr < start)
- goto nospc;
- }
-
- found:
- /*
- * Insert this entry after the one we found.
- */
- list_add(&new->vm_list, &c->vm_list);
- new->vm_start = addr;
- new->vm_end = addr + size;
- new->vm_active = 1;
-
- spin_unlock_irqrestore(&head->vm_lock, flags);
- return new;
-
- nospc:
- spin_unlock_irqrestore(&head->vm_lock, flags);
- kfree(new);
- out:
- return NULL;
-}
-
-static struct arm_vmregion *__arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr)
-{
- struct arm_vmregion *c;
-
- list_for_each_entry(c, &head->vm_list, vm_list) {
- if (c->vm_active && c->vm_start == addr)
- goto out;
- }
- c = NULL;
- out:
- return c;
-}
-
-struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr)
-{
- struct arm_vmregion *c;
- unsigned long flags;
-
- spin_lock_irqsave(&head->vm_lock, flags);
- c = __arm_vmregion_find(head, addr);
- spin_unlock_irqrestore(&head->vm_lock, flags);
- return c;
-}
-
-struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *head, unsigned long addr)
-{
- struct arm_vmregion *c;
- unsigned long flags;
-
- spin_lock_irqsave(&head->vm_lock, flags);
- c = __arm_vmregion_find(head, addr);
- if (c)
- c->vm_active = 0;
- spin_unlock_irqrestore(&head->vm_lock, flags);
- return c;
-}
-
-void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&head->vm_lock, flags);
- list_del(&c->vm_list);
- spin_unlock_irqrestore(&head->vm_lock, flags);
-
- kfree(c);
-}
-
-#ifdef CONFIG_PROC_FS
-static int arm_vmregion_show(struct seq_file *m, void *p)
-{
- struct arm_vmregion *c = list_entry(p, struct arm_vmregion, vm_list);
-
- seq_printf(m, "0x%08lx-0x%08lx %7lu", c->vm_start, c->vm_end,
- c->vm_end - c->vm_start);
- if (c->caller)
- seq_printf(m, " %pS", (void *)c->caller);
- seq_putc(m, '\n');
- return 0;
-}
-
-static void *arm_vmregion_start(struct seq_file *m, loff_t *pos)
-{
- struct arm_vmregion_head *h = m->private;
- spin_lock_irq(&h->vm_lock);
- return seq_list_start(&h->vm_list, *pos);
-}
-
-static void *arm_vmregion_next(struct seq_file *m, void *p, loff_t *pos)
-{
- struct arm_vmregion_head *h = m->private;
- return seq_list_next(p, &h->vm_list, pos);
-}
-
-static void arm_vmregion_stop(struct seq_file *m, void *p)
-{
- struct arm_vmregion_head *h = m->private;
- spin_unlock_irq(&h->vm_lock);
-}
-
-static const struct seq_operations arm_vmregion_ops = {
- .start = arm_vmregion_start,
- .stop = arm_vmregion_stop,
- .next = arm_vmregion_next,
- .show = arm_vmregion_show,
-};
-
-static int arm_vmregion_open(struct inode *inode, struct file *file)
-{
- struct arm_vmregion_head *h = PDE(inode)->data;
- int ret = seq_open(file, &arm_vmregion_ops);
- if (!ret) {
- struct seq_file *m = file->private_data;
- m->private = h;
- }
- return ret;
-}
-
-static const struct file_operations arm_vmregion_fops = {
- .open = arm_vmregion_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
-{
- proc_create_data(path, S_IRUSR, NULL, &arm_vmregion_fops, h);
- return 0;
-}
-#else
-int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
-{
- return 0;
-}
-#endif
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
deleted file mode 100644
index 0f5a5f2..0000000
--- a/arch/arm/mm/vmregion.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef VMREGION_H
-#define VMREGION_H
-
-#include <linux/spinlock.h>
-#include <linux/list.h>
-
-struct page;
-
-struct arm_vmregion_head {
- spinlock_t vm_lock;
- struct list_head vm_list;
- unsigned long vm_start;
- unsigned long vm_end;
-};
-
-struct arm_vmregion {
- struct list_head vm_list;
- unsigned long vm_start;
- unsigned long vm_end;
- int vm_active;
- const void *caller;
-};
-
-struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t, const void *);
-struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
-struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
-void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);
-
-int arm_vmregion_create_proc(const char *, struct arm_vmregion_head *);
-
-#endif
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 2/3] ARM: static_vm: introduce an infrastructure for static mapped area
From: Joonsoo Kim @ 2013-01-24 1:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358990934-4893-1-git-send-email-iamjoonsoo.kim@lge.com>
From: Joonsoo Kim <js1304@gmail.com>
In current implementation, we used ARM-specific flag, that is,
VM_ARM_STATIC_MAPPING, for distinguishing ARM specific static mapped area.
The purpose of static mapped area is to re-use static mapped area when
entire physical address range of the ioremap request can be covered
by this area.
This implementation causes needless overhead for some cases.
For example, assume that there is only one static mapped area and
vmlist has 300 areas. Every time we call ioremap, we check 300 areas for
deciding whether it is matched or not. Moreover, even if there is
no static mapped area and vmlist has 300 areas, every time we call
ioremap, we check 300 areas in now.
If we construct a extra list for static mapped area, we can eliminate
above mentioned overhead.
With a extra list, if there is one static mapped area,
we just check only one area and proceed next operation quickly.
In fact, it is not a critical problem, because ioremap is not frequently
used. But reducing overhead is better idea.
Another reason for doing this work is for removing architecture dependency
on vmalloc layer. I think that vmlist and vmlist_lock is internal data
structure for vmalloc layer. Some codes for debugging and stat inevitably
use vmlist and vmlist_lock. But it is preferable that they are used
as least as possible in outside of vmalloc.c
Now, I introduce an ARM-specific infrastructure for static mapped area. In
the following patch, we will use this and resolve above mentioned problem.
Signed-off-by: Joonsoo Kim <js1304@gmail.com>
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
diff --git a/arch/arm/include/asm/mach/static_vm.h b/arch/arm/include/asm/mach/static_vm.h
new file mode 100644
index 0000000..72c8339
--- /dev/null
+++ b/arch/arm/include/asm/mach/static_vm.h
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/include/asm/mach/static_vm.h
+ *
+ * Copyright (C) 2012 LG Electronics, Joonsoo Kim <iamjoonsoo.kim@lge.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 _ASM_MACH_STATIC_VM_H
+#define _ASM_MACH_STATIC_VM_H
+
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+struct static_vm {
+ struct static_vm *next;
+ void *vaddr;
+ unsigned long size;
+ unsigned long flags;
+ phys_addr_t paddr;
+ const void *caller;
+};
+
+extern struct static_vm *static_vmlist;
+extern spinlock_t static_vmlist_lock;
+
+extern struct static_vm *find_static_vm_paddr(phys_addr_t paddr,
+ size_t size, unsigned long flags);
+extern struct static_vm *find_static_vm_vaddr(void *vaddr);
+extern void init_static_vm(struct static_vm *static_vm,
+ struct vm_struct *vm, unsigned long flags);
+extern void insert_static_vm(struct static_vm *vm);
+
+#endif /* _ASM_MACH_STATIC_VM_H */
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 4e333fa..57b329a 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -6,7 +6,7 @@ obj-y := dma-mapping.o extable.o fault.o init.o \
iomap.o
obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \
- mmap.o pgd.o mmu.o
+ mmap.o pgd.o mmu.o static_vm.o
ifneq ($(CONFIG_MMU),y)
obj-y += nommu.o
diff --git a/arch/arm/mm/static_vm.c b/arch/arm/mm/static_vm.c
new file mode 100644
index 0000000..265d8e9
--- /dev/null
+++ b/arch/arm/mm/static_vm.c
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mm/static_vm.c
+ *
+ * Copyright (C) 2012 LG Electronics, Joonsoo Kim <iamjoonsoo.kim@lge.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/spinlock.h>
+
+#include <asm/mach/static_vm.h>
+
+struct static_vm *static_vmlist;
+DEFINE_SPINLOCK(static_vmlist_lock);
+
+struct static_vm *find_static_vm_paddr(phys_addr_t paddr,
+ size_t size, unsigned long flags)
+{
+ struct static_vm *area;
+
+ spin_lock(&static_vmlist_lock);
+ for (area = static_vmlist; area; area = area->next) {
+ if ((area->flags & flags) != flags)
+ continue;
+
+ if (area->paddr > paddr ||
+ paddr + size - 1 > area->paddr + area->size - 1)
+ continue;
+
+ spin_unlock(&static_vmlist_lock);
+ return area;
+ }
+ spin_unlock(&static_vmlist_lock);
+
+ return NULL;
+}
+
+struct static_vm *find_static_vm_vaddr(void *vaddr)
+{
+ struct static_vm *area;
+
+ spin_lock(&static_vmlist_lock);
+ for (area = static_vmlist; area; area = area->next) {
+ /* static_vmlist is ascending order */
+ if (area->vaddr > vaddr)
+ break;
+
+ if (area->vaddr <= vaddr && area->vaddr + area->size > vaddr) {
+ spin_unlock(&static_vmlist_lock);
+ return area;
+ }
+ }
+ spin_unlock(&static_vmlist_lock);
+
+ return NULL;
+}
+
+void init_static_vm(struct static_vm *static_vm,
+ struct vm_struct *vm, unsigned long flags)
+{
+ static_vm->vaddr = vm->addr;
+ static_vm->size = vm->size;
+ static_vm->paddr = vm->phys_addr;
+ static_vm->caller = vm->caller;
+ static_vm->flags = flags;
+}
+
+void insert_static_vm(struct static_vm *vm)
+{
+ struct static_vm *tmp, **p;
+
+ spin_lock(&static_vmlist_lock);
+ for (p = &static_vmlist; (tmp = *p) != NULL; p = &tmp->next) {
+ if (tmp->vaddr >= vm->vaddr) {
+ BUG_ON(tmp->vaddr < vm->vaddr + vm->size);
+ break;
+ } else
+ BUG_ON(tmp->vaddr + tmp->size > vm->vaddr);
+ }
+ vm->next = *p;
+ *p = vm;
+ spin_unlock(&static_vmlist_lock);
+}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 3/3] ARM: mm: use static_vm for managing static mapped areas
From: Joonsoo Kim @ 2013-01-24 1:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358990934-4893-1-git-send-email-iamjoonsoo.kim@lge.com>
From: Joonsoo Kim <js1304@gmail.com>
A static mapped area is ARM-specific, so it is better not to use
generic vmalloc data structure, that is, vmlist and vmlist_lock
for managing static mapped area. And it causes some needless overhead and
reducing this overhead is better idea.
Now, we have newly introduced static_vm infrastructure.
With it, we don't need to iterate all mapped areas. Instead, we just
iterate static mapped areas. It helps to reduce an overhead of finding
matched area. And architecture dependency on vmalloc layer is removed,
so it will help to maintainability for vmalloc layer.
Signed-off-by: Joonsoo Kim <js1304@gmail.com>
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
diff --git a/arch/arm/include/asm/mach/static_vm.h b/arch/arm/include/asm/mach/static_vm.h
index 72c8339..24672b1 100644
--- a/arch/arm/include/asm/mach/static_vm.h
+++ b/arch/arm/include/asm/mach/static_vm.h
@@ -32,6 +32,12 @@ struct static_vm {
const void *caller;
};
+#define STATIC_VM_MEM 0x00000001
+#define STATIC_VM_EMPTY 0x00000002
+
+/* mtype should be less than 28 */
+#define STATIC_VM_MTYPE(mt) (1UL << ((mt) + 4))
+
extern struct static_vm *static_vmlist;
extern spinlock_t static_vmlist_lock;
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 88fd86c..2c0d3a1 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -36,6 +36,7 @@
#include <asm/system_info.h>
#include <asm/mach/map.h>
+#include <asm/mach/static_vm.h>
#include <asm/mach/pci.h>
#include "mm.h"
@@ -197,7 +198,8 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
const struct mem_type *type;
int err;
unsigned long addr;
- struct vm_struct * area;
+ struct vm_struct *area;
+ phys_addr_t paddr = __pfn_to_phys(pfn);
#ifndef CONFIG_ARM_LPAE
/*
@@ -219,24 +221,17 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
/*
* Try to reuse one of the static mapping whenever possible.
*/
- read_lock(&vmlist_lock);
- for (area = vmlist; area; area = area->next) {
- if (!size || (sizeof(phys_addr_t) == 4 && pfn >= 0x100000))
- break;
- if (!(area->flags & VM_ARM_STATIC_MAPPING))
- continue;
- if ((area->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype))
- continue;
- if (__phys_to_pfn(area->phys_addr) > pfn ||
- __pfn_to_phys(pfn) + size-1 > area->phys_addr + area->size-1)
- continue;
- /* we can drop the lock here as we know *area is static */
- read_unlock(&vmlist_lock);
- addr = (unsigned long)area->addr;
- addr += __pfn_to_phys(pfn) - area->phys_addr;
- return (void __iomem *) (offset + addr);
+ if (size && !((sizeof(phys_addr_t) == 4 && pfn >= 0x100000))) {
+ struct static_vm *static_vm;
+
+ static_vm = find_static_vm_paddr(__pfn_to_phys(pfn), size,
+ STATIC_VM_MEM | STATIC_VM_MTYPE(mtype));
+ if (static_vm) {
+ addr = (unsigned long)static_vm->vaddr;
+ addr += paddr - static_vm->paddr;
+ return (void __iomem *) (offset + addr);
+ }
}
- read_unlock(&vmlist_lock);
/*
* Don't allow RAM to be mapped - this causes problems with ARMv6+
@@ -248,7 +243,7 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
if (!area)
return NULL;
addr = (unsigned long)area->addr;
- area->phys_addr = __pfn_to_phys(pfn);
+ area->phys_addr = paddr;
#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
if (DOMAIN_IO == 0 &&
@@ -346,34 +341,20 @@ __arm_ioremap_exec(unsigned long phys_addr, size_t size, bool cached)
void __iounmap(volatile void __iomem *io_addr)
{
void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
- struct vm_struct *vm;
-
- read_lock(&vmlist_lock);
- for (vm = vmlist; vm; vm = vm->next) {
- if (vm->addr > addr)
- break;
- if (!(vm->flags & VM_IOREMAP))
- continue;
- /* If this is a static mapping we must leave it alone */
- if ((vm->flags & VM_ARM_STATIC_MAPPING) &&
- (vm->addr <= addr) && (vm->addr + vm->size > addr)) {
- read_unlock(&vmlist_lock);
- return;
- }
+ struct static_vm *static_vm;
+
+ static_vm = find_static_vm_vaddr(addr);
+ if (static_vm)
+ return;
+
#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
- /*
- * If this is a section based mapping we need to handle it
- * specially as the VM subsystem does not know how to handle
- * such a beast.
- */
- if ((vm->addr == addr) &&
- (vm->flags & VM_ARM_SECTION_MAPPING)) {
+ {
+ struct vm_struct *vm;
+ vm = find_vm_area(addr);
+ if (vm && (vm->flags & VM_ARM_SECTION_MAPPING))
unmap_area_sections((unsigned long)vm->addr, vm->size);
- break;
- }
-#endif
}
- read_unlock(&vmlist_lock);
+#endif
vunmap(addr);
}
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index a8ee92d..3ae75e5 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -52,16 +52,6 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
/* (super)section-mapped I/O regions used by ioremap()/iounmap() */
#define VM_ARM_SECTION_MAPPING 0x80000000
-/* permanent static mappings from iotable_init() */
-#define VM_ARM_STATIC_MAPPING 0x40000000
-
-/* empty mapping */
-#define VM_ARM_EMPTY_MAPPING 0x20000000
-
-/* mapping type (attributes) for permanent static mappings */
-#define VM_ARM_MTYPE(mt) ((mt) << 20)
-#define VM_ARM_MTYPE_MASK (0x1f << 20)
-
/* consistent regions used by dma_alloc_attrs() */
#define VM_ARM_DMA_CONSISTENT 0x20000000
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9f06102..b799b69 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -31,6 +31,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/mach/static_vm.h>
#include <asm/mach/pci.h>
#include "mm.h"
@@ -757,21 +758,28 @@ void __init iotable_init(struct map_desc *io_desc, int nr)
{
struct map_desc *md;
struct vm_struct *vm;
+ struct static_vm *static_vm;
if (!nr)
return;
vm = early_alloc_aligned(sizeof(*vm) * nr, __alignof__(*vm));
+ static_vm = early_alloc_aligned(sizeof(*static_vm) * nr,
+ __alignof__(*static_vm));
for (md = io_desc; nr; md++, nr--) {
create_mapping(md);
+
vm->addr = (void *)(md->virtual & PAGE_MASK);
vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
vm->phys_addr = __pfn_to_phys(md->pfn);
- vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
- vm->flags |= VM_ARM_MTYPE(md->type);
+ vm->flags = VM_IOREMAP;
vm->caller = iotable_init;
+
+ init_static_vm(static_vm, vm, STATIC_VM_MEM |
+ STATIC_VM_MTYPE(md->type));
vm_area_add_early(vm++);
+ insert_static_vm(static_vm++);
}
}
@@ -779,13 +787,20 @@ void __init vm_reserve_area_early(unsigned long addr, unsigned long size,
void *caller)
{
struct vm_struct *vm;
+ struct static_vm *static_vm;
vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));
+ static_vm = early_alloc_aligned(sizeof(*static_vm),
+ __alignof__(*static_vm));
+
vm->addr = (void *)addr;
vm->size = size;
- vm->flags = VM_IOREMAP | VM_ARM_EMPTY_MAPPING;
+ vm->flags = VM_IOREMAP;
vm->caller = caller;
+
+ init_static_vm(static_vm, vm, STATIC_VM_EMPTY);
vm_area_add_early(vm);
+ insert_static_vm(static_vm);
}
#ifndef CONFIG_ARM_LPAE
@@ -810,15 +825,19 @@ static void __init pmd_empty_section_gap(unsigned long addr)
static void __init fill_pmd_gaps(void)
{
- struct vm_struct *vm;
+ struct static_vm *area;
unsigned long addr, next = 0;
pmd_t *pmd;
- /* we're still single threaded hence no lock needed here */
- for (vm = vmlist; vm; vm = vm->next) {
- if (!(vm->flags & (VM_ARM_STATIC_MAPPING | VM_ARM_EMPTY_MAPPING)))
- continue;
- addr = (unsigned long)vm->addr;
+ /*
+ * We should not take a lock here, because pmd_empty_section_gap()
+ * invokes vm_reserve_area_early(), and then it call insert_static_vm()
+ * which try to take a lock.
+ * We're still single thread, so traverse whole list without a lock
+ * is safe for now. And inserting new entry is also safe.
+ */
+ for (area = static_vmlist; area; area = area->next) {
+ addr = (unsigned long)area->vaddr;
if (addr < next)
continue;
@@ -838,7 +857,7 @@ static void __init fill_pmd_gaps(void)
* If so and the second section entry for this PMD is empty
* then we block the corresponding virtual address.
*/
- addr += vm->size;
+ addr += area->size;
if ((addr & ~PMD_MASK) == SECTION_SIZE) {
pmd = pmd_off_k(addr) + 1;
if (pmd_none(*pmd))
@@ -857,19 +876,12 @@ static void __init fill_pmd_gaps(void)
#if defined(CONFIG_PCI) && !defined(CONFIG_NEED_MACH_IO_H)
static void __init pci_reserve_io(void)
{
- struct vm_struct *vm;
- unsigned long addr;
+ struct static_vm *static_vm;
- /* we're still single threaded hence no lock needed here */
- for (vm = vmlist; vm; vm = vm->next) {
- if (!(vm->flags & VM_ARM_STATIC_MAPPING))
- continue;
- addr = (unsigned long)vm->addr;
- addr &= ~(SZ_2M - 1);
- if (addr == PCI_IO_VIRT_BASE)
- return;
+ static_vm = find_static_vm_vaddr((void *)PCI_IO_VIRT_BASE);
+ if (static_vm)
+ return;
- }
vm_reserve_area_early(PCI_IO_VIRT_BASE, SZ_2M, pci_reserve_io);
}
#else
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 0/6] ARM: kirkwood: cleanup DT conversion
From: Jason Cooper @ 2013-01-24 1:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358983578.git.jason@lakedaemon.net>
On Wed, Jan 23, 2013 at 11:34:18PM +0000, Jason Cooper wrote:
> All,
>
> This is a first cut at cleaning up mach-kirkwood/. There are a few DT
> conversions (topkick -> mvsdio, pinctrl) which, once reviewed, I'll put in the
> normal pull request cycle.
>
> The others which remove board-*.c files, I'll keep updating against
> mvebu/for-next, and then apply at the end of the merge window.
>
> Please test as you are able.
I should also mention, this was built against mvebu/for-next (not
stable) which is just the merging of all the mvebu/* branches and
arm-soc/for-next into one branch.
thx,
Jason.
^ permalink raw reply
* [V4 PATCH 18/26] usb: phy: mv_usb2_phy: add externel chip support
From: Chao Xie @ 2013-01-24 1:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130123114725.GH29258@arwen.pp.htv.fi>
On Wed, Jan 23, 2013 at 7:47 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Tue, Jan 22, 2013 at 10:51:32AM +0800, Chao Xie wrote:
>> On Mon, Jan 21, 2013 at 11:51 PM, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > On Mon, Jan 21, 2013 at 05:07:36AM -0500, Chao Xie wrote:
>> >> + mv_phy->extern_chip.head = devm_kzalloc(&pdev->dev,
>> >> + sizeof(*mv_phy->extern_chip.head),
>> >> + GFP_KERNEL);
>> >> + if (mv_phy->extern_chip.head == NULL)
>> >> + return -ENOMEM;
>> >> + ATOMIC_INIT_NOTIFIER_HEAD(mv_phy->extern_chip.head);
>> >
>> > Why do you need to allocate an atomic notifier list head as an entirely
>> > separate data structure?
>> > --
>> > To unsubscribe from this list: send the line "unsubscribe linux-usb" in
>> > the body of a message to majordomo at vger.kernel.org
>> > More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>> Th reason is that the original code seperate the extern_chip and phy
>> support. So it depends
>> on the ->head to detect whether extern_chip is initialized or not.
>> Now it is combined with phy, the ->phy pointer can do the job.
>
> does that need to be dynamically allocated ?
>
> --
> balbi
hi
It does not need to be dynamically allocated. I will modify it, and
send out V5 today. Thanks for Russell's review.
^ permalink raw reply
* [RFC PATCH 6/6] ARM: kirkwood: consolidate mv643xx_eth init for DT
From: Jason Cooper @ 2013-01-24 1:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ecb64cdf824399badaf9d659177811d8cb091156.1358983578.git.jason@lakedaemon.net>
On Wed, Jan 23, 2013 at 11:34:24PM +0000, Jason Cooper wrote:
> replace a lot of unneeded code and files with a lookup table.
>
> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
> ---
> arch/arm/mach-kirkwood/Kconfig | 101 ------------------------
> arch/arm/mach-kirkwood/Makefile | 14 ----
> arch/arm/mach-kirkwood/board-dnskw.c | 7 --
> arch/arm/mach-kirkwood/board-dockstar.c | 32 --------
> arch/arm/mach-kirkwood/board-dreamplug.c | 35 --------
> arch/arm/mach-kirkwood/board-dt.c | 114 +++++++++++++++++++--------
> arch/arm/mach-kirkwood/board-goflexnet.c | 34 --------
> arch/arm/mach-kirkwood/board-ib62x0.c | 29 -------
> arch/arm/mach-kirkwood/board-iconnect.c | 23 ------
> arch/arm/mach-kirkwood/board-lsxl.c | 36 ---------
> arch/arm/mach-kirkwood/board-mplcec4.c | 35 --------
> arch/arm/mach-kirkwood/board-ns2.c | 34 --------
> arch/arm/mach-kirkwood/board-openblocks_a6.c | 26 ------
> arch/arm/mach-kirkwood/board-usi_topkick.c | 29 -------
> arch/arm/mach-kirkwood/common.h | 63 ---------------
> 15 files changed, 81 insertions(+), 531 deletions(-)
> delete mode 100644 arch/arm/mach-kirkwood/board-dockstar.c
> delete mode 100644 arch/arm/mach-kirkwood/board-dreamplug.c
> delete mode 100644 arch/arm/mach-kirkwood/board-goflexnet.c
> delete mode 100644 arch/arm/mach-kirkwood/board-ib62x0.c
> delete mode 100644 arch/arm/mach-kirkwood/board-iconnect.c
> delete mode 100644 arch/arm/mach-kirkwood/board-lsxl.c
> delete mode 100644 arch/arm/mach-kirkwood/board-mplcec4.c
> delete mode 100644 arch/arm/mach-kirkwood/board-ns2.c
> delete mode 100644 arch/arm/mach-kirkwood/board-openblocks_a6.c
> delete mode 100644 arch/arm/mach-kirkwood/board-usi_topkick.c
>
> diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
> index 432bee0..188651b 100644
> --- a/arch/arm/mach-kirkwood/Kconfig
> +++ b/arch/arm/mach-kirkwood/Kconfig
> @@ -58,19 +58,6 @@ config ARCH_KIRKWOOD_DT
> Say 'Y' here if you want your kernel to support the
> Marvell Kirkwood using flattened device tree.
>
> -config MACH_DREAMPLUG_DT
> - bool "Marvell DreamPlug (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the
> - Marvell DreamPlug (Flattened Device Tree).
> -
> -config MACH_ICONNECT_DT
> - bool "Iomega Iconnect (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here to enable Iomega Iconnect support.
> -
> config MACH_DLINK_KIRKWOOD_DT
> bool "D-Link Kirkwood-based NAS (Flattened Device Tree)"
> select ARCH_KIRKWOOD_DT
> @@ -79,14 +66,6 @@ config MACH_DLINK_KIRKWOOD_DT
> Kirkwood-based D-Link NASes such as DNS-320 & DNS-325,
> using Flattened Device Tree.
>
> -config MACH_IB62X0_DT
> - bool "RaidSonic IB-NAS6210, IB-NAS6220 (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the
> - RaidSonic IB-NAS6210 & IB-NAS6220 devices, using
> - Flattened Device Tree.
> -
> config MACH_TS219_DT
> bool "Device Tree for QNAP TS-11X, TS-21X NAS"
> select ARCH_KIRKWOOD_DT
> @@ -102,29 +81,6 @@ config MACH_TS219_DT
> or MV6282. If you have the wrong one, the buttons will not
> work.
>
> -config MACH_DOCKSTAR_DT
> - bool "Seagate FreeAgent Dockstar (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the
> - Seagate FreeAgent Dockstar (Flattened Device Tree).
> -
> -config MACH_GOFLEXNET_DT
> - bool "Seagate GoFlex Net (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the
> - Seagate GoFlex Net (Flattened Device Tree).
> -
> -config MACH_LSXL_DT
> - bool "Buffalo Linkstation LS-XHL, LS-CHLv2 (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - select POWER_RESET_RESTART
> - help
> - Say 'Y' here if you want your kernel to support the
> - Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using
> - Flattened Device Tree.
> -
> config MACH_IOMEGA_IX2_200_DT
> bool "Iomega StorCenter ix2-200 (Flattened Device Tree)"
> select ARCH_KIRKWOOD_DT
> @@ -139,63 +95,6 @@ config MACH_KM_KIRKWOOD_DT
> Say 'Y' here if you want your kernel to support the
> Keymile Kirkwood Reference Desgin, using Flattened Device Tree.
>
> -config MACH_INETSPACE_V2_DT
> - bool "LaCie Internet Space v2 NAS (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the LaCie
> - Internet Space v2 NAS, using Flattened Device Tree.
> -
> -config MACH_MPLCEC4_DT
> - bool "MPL CEC4 (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the
> - MPL CEC4 (Flattened Device Tree).
> -
> -config MACH_NETSPACE_V2_DT
> - bool "LaCie Network Space v2 NAS (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the LaCie
> - Network Space v2 NAS, using Flattened Device Tree.
> -
> -config MACH_NETSPACE_MAX_V2_DT
> - bool "LaCie Network Space Max v2 NAS (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the LaCie
> - Network Space Max v2 NAS, using Flattened Device Tree.
> -
> -config MACH_NETSPACE_LITE_V2_DT
> - bool "LaCie Network Space Lite v2 NAS (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the LaCie
> - Network Space Lite v2 NAS, using Flattened Device Tree.
> -
> -config MACH_NETSPACE_MINI_V2_DT
> - bool "LaCie Network Space Mini v2 NAS (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the LaCie
> - Network Space Mini v2 NAS (aka SafeBox), using Flattened
> - Device Tree.
> -
> -config MACH_OPENBLOCKS_A6_DT
> - bool "Plat'Home OpenBlocks A6 (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the
> - Plat'Home OpenBlocks A6 (Flattened Device Tree).
> -
> -config MACH_TOPKICK_DT
> - bool "USI Topkick (Flattened Device Tree)"
> - select ARCH_KIRKWOOD_DT
> - help
> - Say 'Y' here if you want your kernel to support the
> - USI Topkick, using Flattened Device Tree
> -
> config MACH_TS219
> bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS"
> help
> diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
> index ee3aa77..ab739b0 100644
> --- a/arch/arm/mach-kirkwood/Makefile
> +++ b/arch/arm/mach-kirkwood/Makefile
> @@ -20,21 +20,7 @@ obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
> obj-$(CONFIG_MACH_T5325) += t5325-setup.o
>
> obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o
> -obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o
> -obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o
> obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o
> -obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o
> obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o
> -obj-$(CONFIG_MACH_DOCKSTAR_DT) += board-dockstar.o
> -obj-$(CONFIG_MACH_GOFLEXNET_DT) += board-goflexnet.o
> -obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o
> obj-$(CONFIG_MACH_IOMEGA_IX2_200_DT) += board-iomega_ix2_200.o
> obj-$(CONFIG_MACH_KM_KIRKWOOD_DT) += board-km_kirkwood.o
> -obj-$(CONFIG_MACH_INETSPACE_V2_DT) += board-ns2.o
> -obj-$(CONFIG_MACH_MPLCEC4_DT) += board-mplcec4.o
> -obj-$(CONFIG_MACH_NETSPACE_V2_DT) += board-ns2.o
> -obj-$(CONFIG_MACH_NETSPACE_MAX_V2_DT) += board-ns2.o
> -obj-$(CONFIG_MACH_NETSPACE_LITE_V2_DT) += board-ns2.o
> -obj-$(CONFIG_MACH_NETSPACE_MINI_V2_DT) += board-ns2.o
> -obj-$(CONFIG_MACH_OPENBLOCKS_A6_DT) += board-openblocks_a6.o
> -obj-$(CONFIG_MACH_TOPKICK_DT) += board-usi_topkick.o
> diff --git a/arch/arm/mach-kirkwood/board-dnskw.c b/arch/arm/mach-kirkwood/board-dnskw.c
> index a1aa87f..2af7a95 100644
> --- a/arch/arm/mach-kirkwood/board-dnskw.c
> +++ b/arch/arm/mach-kirkwood/board-dnskw.c
> @@ -14,14 +14,9 @@
> #include <linux/kernel.h>
> #include <linux/init.h>
> #include <linux/platform_device.h>
> -#include <linux/mv643xx_eth.h>
> #include <linux/gpio.h>
> #include "common.h"
>
> -static struct mv643xx_eth_platform_data dnskw_ge00_data = {
> - .phy_addr = MV643XX_ETH_PHY_ADDR(8),
> -};
> -
> /* Register any GPIO for output and set the value */
> static void __init dnskw_gpio_register(unsigned gpio, char *name, int def)
> {
> @@ -36,8 +31,6 @@ static void __init dnskw_gpio_register(unsigned gpio, char *name, int def)
>
> void __init dnskw_init(void)
> {
> - kirkwood_ge00_init(&dnskw_ge00_data);
> -
> /* Set NAS to turn back on after a power failure */
> dnskw_gpio_register(37, "dnskw:power:recover", 1);
> }
> diff --git a/arch/arm/mach-kirkwood/board-dockstar.c b/arch/arm/mach-kirkwood/board-dockstar.c
> deleted file mode 100644
> index d7196db..0000000
> --- a/arch/arm/mach-kirkwood/board-dockstar.c
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -/*
> - * arch/arm/mach-kirkwood/board-dockstar.c
> - *
> - * Seagate FreeAgent Dockstar Board Init for drivers not converted to
> - * flattened device tree yet.
> - *
> - * 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.
> - *
> - * Copied and modified for Seagate GoFlex Net support by
> - * Joshua Coombs <josh.coombs@gmail.com> based on ArchLinux ARM's
> - * GoFlex kernel patches.
> - *
> - */
> -
> -#include <linux/kernel.h>
> -#include <linux/init.h>
> -#include <linux/mv643xx_eth.h>
> -#include "common.h"
> -
> -static struct mv643xx_eth_platform_data dockstar_ge00_data = {
> - .phy_addr = MV643XX_ETH_PHY_ADDR(0),
> -};
> -
> -void __init dockstar_dt_init(void)
> -{
> - /*
> - * Basic setup. Needs to be called early.
> - */
> - kirkwood_ge00_init(&dockstar_ge00_data);
> -}
> diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c
> deleted file mode 100644
> index 0903242..0000000
> --- a/arch/arm/mach-kirkwood/board-dreamplug.c
> +++ /dev/null
> @@ -1,35 +0,0 @@
> -/*
> - * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
> - *
> - * arch/arm/mach-kirkwood/board-dreamplug.c
> - *
> - * Marvell DreamPlug Reference Board Init for drivers not converted to
> - * flattened device tree yet.
> - *
> - * 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/init.h>
> -#include <linux/mv643xx_eth.h>
> -#include <linux/gpio.h>
> -#include "common.h"
> -
> -static struct mv643xx_eth_platform_data dreamplug_ge00_data = {
> - .phy_addr = MV643XX_ETH_PHY_ADDR(0),
> -};
> -
> -static struct mv643xx_eth_platform_data dreamplug_ge01_data = {
> - .phy_addr = MV643XX_ETH_PHY_ADDR(1),
> -};
> -
> -void __init dreamplug_init(void)
> -{
> - /*
> - * Basic setup. Needs to be called early.
> - */
> - kirkwood_ge00_init(&dreamplug_ge00_data);
> - kirkwood_ge01_init(&dreamplug_ge01_data);
> -}
> diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
> index 73b76e4..f5bd640 100644
> --- a/arch/arm/mach-kirkwood/board-dt.c
> +++ b/arch/arm/mach-kirkwood/board-dt.c
> @@ -93,6 +93,86 @@ static int __init kirkwood_pcie_dt_init(void)
> }
> subsys_initcall(kirkwood_pcie_dt_init);
>
> +struct kirkwood_dt_gige {
> + const char *compatible;
> + int phy_addr00;
> + int phy_addr01;
> +};
> +
> +static struct kirkwood_dt_gige kw_dt_gige[] = {
> + { .compatible = "buffalo,lsxl",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
> + .phy_addr01 = MV643XX_ETH_PHY_ADDR(8) },
> + { .compatible = "dlink,dns-kirkwood",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "globalscale,dreamplug",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
> + .phy_addr01 = MV643XX_ETH_PHY_ADDR(1) },
> + { .compatible = "iom,iconnect",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(11),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "lacie,inetspace_v2",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "lacie,netspace_v2",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "lacie,netspace_max_v2",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "lacie,netspace_lite_v2",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "lacie,netspace_mini_v2",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "mpl,cec4",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(1),
> + .phy_addr01 = MV643XX_ETH_PHY_ADDR(2) },
> + { .compatible = "plathome,openblocks-a6",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "raidsonic,ib-nas62x0",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(8),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "seagate,dockstar",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "seagate,goflexnet",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { .compatible = "usi,topkick",
> + .phy_addr00 = MV643XX_ETH_PHY_ADDR(0),
> + .phy_addr01 = MV643XX_ETH_PHY_NONE },
> + { NULL, MV643XX_ETH_PHY_NONE, MV643XX_ETH_PHY_NONE },
> +};
> +
> +static void kirkwood_gige_dt_init(void) {
> + int i;
> +
> + for (i = 0; kw_dt_gige[i].compatible != NULL; i++) {
> + if (of_machine_is_compatible(kw_dt_gige[i].compatible)) {
> +
> + if (kw_dt_gige[i].phy_addr00 != MV643XX_ETH_PHY_NONE) {
> + struct mv643xx_eth_platform_data d = {
> + .phy_addr = kw_dt_gige[i].phy_addr00,
> + };
> + kirkwood_ge00_init(&d);
> + }
> +
> + if (kw_dt_gige[i].phy_addr01 != MV643XX_ETH_PHY_NONE) {
> + struct mv643xx_eth_platform_data d = {
> + .phy_addr = kw_dt_gige[i].phy_addr01,
> + };
> + kirkwood_ge01_init(&d);
> + }
> +
> + break;
> + }
meh, hindsight is 50/50 :-) Much more readable this way, I think:
if (of_machine_is_compatible(kw_dt_gige[i].compatible)) {
struct mv643xx_eth_platform_data d;
if (kw_dt_gige[i].phy_addr00 != MV643XX_ETH_PHY_NONE) {
d.phy_addr = kw_dt_gige[i].phy_addr00,
kirkwood_ge00_init(&d);
}
if (kw_dt_gige[i].phy_addr01 != MV643XX_ETH_PHY_NONE) {
d.phy_addr = kw_dt_gige[i].phy_addr01,
kirkwood_ge01_init(&d);
}
break;
}
thx,
Jason.
^ permalink raw reply
* [PATCH 4/4] irqchip: gic: Perform the gic_secondary_init() call via CPU notifier
From: Viresh Kumar @ 2013-01-24 2:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358963974-5496-5-git-send-email-catalin.marinas@arm.com>
On Wed, Jan 23, 2013 at 11:29 PM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> All the calls to gic_secondary_init() pass 0 as the first argument.
> Since this function is called on each CPU when starting, it can be done
> in a platform-independent way via a CPU notifier registered by the GIC
> code.
> arch/arm/mach-spear13xx/platsmp.c | 8 --------
For SPEAr,
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
^ permalink raw reply
* [PATCH v3 1/1 net-next] net: fec: enable pause frame to improve rx prefomance for 1G network
From: Frank Li @ 2013-01-24 2:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358973584.2658.14.camel@bwh-desktop.uk.solarflarecom.com>
2013/1/24 Ben Hutchings <bhutchings@solarflare.com>:
> On Thu, 2013-01-17 at 10:55 +0800, Frank Li wrote:
>> The limition of imx6 internal bus cause fec can't achieve 1G perfomance.
>> There will be many packages lost because FIFO over run.
>>
>> This patch enable pause frame flow control.
> [...]
>> --- a/drivers/net/ethernet/freescale/fec.c
>> +++ b/drivers/net/ethernet/freescale/fec.c
> [...]
>> +static int fec_enet_set_pauseparam(struct net_device *ndev,
>> + struct ethtool_pauseparam *pause)
>> +{
>> + struct fec_enet_private *fep = netdev_priv(ndev);
>> +
>> + if (pause->tx_pause != pause->rx_pause) {
>> + netdev_info(ndev,
>> + "hardware only support enable/disable both tx and rx");
>> + return -EINVAL;
>> + }
>> +
>> + fep->pause_flag = 0;
>> +
>> + /* tx pause must be same as rx pause */
>> + fep->pause_flag |= pause->rx_pause ? FEC_PAUSE_FLAG_ENABLE : 0;
>> + fep->pause_flag |= pause->autoneg ? FEC_PAUSE_FLAG_AUTONEG : 0;
>> +
>> + if (pause->rx_pause || pause->autoneg) {
>> + fep->phy_dev->supported |= ADVERTISED_Pause;
>> + fep->phy_dev->advertising |= ADVERTISED_Pause;
>> + } else {
>> + fep->phy_dev->supported &= ~ADVERTISED_Pause;
>> + fep->phy_dev->advertising &= ~ADVERTISED_Pause;
>> + }
> [...]
>
> Why is this changing the supported flags, i.e. device capabilities? You
> need to leave those flags alone and reject an attempt to enable pause
> frames on a device that doesn't support them.
I go through phylib, I have not found good place set ADVERTISED_Pause
capabilities.
genphy_config_init never check Pause capabilities.
>
> Ben.
>
> --
> Ben Hutchings, Staff Engineer, Solarflare
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>
^ permalink raw reply
* [PATCH 1/2 net-next] net: fec: add napi support to improve proformance
From: Frank Li @ 2013-01-24 2:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358948954.12374.758.camel@edumazet-glaptop>
2013/1/23 Eric Dumazet <eric.dumazet@gmail.com>:
> On Wed, 2013-01-23 at 15:37 +0800, Frank Li wrote:
>> 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?
>
> No idea, you'll have to find out using perf tool if available.
>
> Is your machine SMP, and the application running on another cpu than the
> softirq handler for your device ?
Yes, we support SMP. Possibly run on another cpu. I will check.
>
> A NAPI driver must call netif_receive_skb(), especially if
> the RX path does a full copy of the frame : Its hot in cpu cache and
> should be processed at once.
How about napi_gro_receive? is it correct function? I found many driver use it.
>
> Escaping to netif_rx() is only adding an extra softirq and risk of data
> being evicted from cpu caches.
>
> Here your performance increase only comes from hw_lock being not anymore
> locked in RX path.
>
>
>
^ permalink raw reply
* [GIT PULL] CSR SiRFmarco SoC infrastructures for 3.9
From: Barry Song @ 2013-01-24 3:21 UTC (permalink / raw)
To: linux-arm-kernel
Hi Olof, Arnd,
pls pull the following changes for CSR SiRFmarco SoC. it has been
rebased againest arm-soc timer/cleanup tree.
since commit 90cf214d6a549bf482e3c5751ee256cc885b96ea:
ARM: at91: fix board-rm9200-dt after sys_timer conversion
(2013-01-14 10:14:04 -0800)
are available in the git repository at:
git://gitorious.org/sirfprima2-kernel/sirfprima2-kernel.git
marco-timer-cleanup-rebase
Barry Song (9):
ARM: PRIMA2: add CSR SiRFmarco device tree .dts
ARM: PRIMA2: enable AUTO_ZRELADDR for SIRF in Kconfig
ARM: PRIMA2: initialize l2x0 according to mach from DT
ARM: PRIMA2: mv timer to timer-prima2 as we will add timer-marco
ARM: PRIMA2: rstc: enable the support for Marco
ARM: PRIMA2: rtciobg: it is also compatible with marco
ARM: PRIMA2: irq: make prima2 irq can work even we enable GIC for Marco
ARM: PRIMA2: add new SiRFmarco SMP SoC infrastructures
ARM: PRIMA2: provide two DEBUG_LL ports for prima2 and marco
Documentation/devicetree/bindings/arm/sirf.txt | 10 +-
arch/arm/Kconfig | 1 +
arch/arm/Kconfig.debug | 14 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/marco-evb.dts | 54 ++
arch/arm/boot/dts/marco.dtsi | 756 ++++++++++++++++++++++
arch/arm/configs/prima2_defconfig | 3 +
arch/arm/mach-prima2/Kconfig | 10 +
arch/arm/mach-prima2/Makefile | 5 +-
arch/arm/mach-prima2/common.c | 45 ++-
arch/arm/mach-prima2/common.h | 15 +-
arch/arm/mach-prima2/headsmp.S | 79 +++
arch/arm/mach-prima2/hotplug.c | 41 ++
arch/arm/mach-prima2/include/mach/irqs.h | 4 +-
arch/arm/mach-prima2/include/mach/uart.h | 6 +
arch/arm/mach-prima2/include/mach/uncompress.h | 3 +
arch/arm/mach-prima2/irq.c | 16 +-
arch/arm/mach-prima2/l2x0.c | 29 +-
arch/arm/mach-prima2/platsmp.c | 163 +++++
arch/arm/mach-prima2/rstc.c | 45 +-
arch/arm/mach-prima2/rtciobrg.c | 1 +
arch/arm/mach-prima2/timer-marco.c | 316 +++++++++
arch/arm/mach-prima2/{timer.c => timer-prima2.c} | 6 +-
23 files changed, 1588 insertions(+), 35 deletions(-)
create mode 100644 arch/arm/boot/dts/marco-evb.dts
create mode 100644 arch/arm/boot/dts/marco.dtsi
create mode 100644 arch/arm/mach-prima2/headsmp.S
create mode 100644 arch/arm/mach-prima2/hotplug.c
create mode 100644 arch/arm/mach-prima2/platsmp.c
create mode 100644 arch/arm/mach-prima2/timer-marco.c
rename arch/arm/mach-prima2/{timer.c => timer-prima2.c} (98%)
Thanks
barry
^ permalink raw reply
* [GIT PULL] Renesas ARM-based SoC v3.9
From: Olof Johansson @ 2013-01-24 3:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130122091924.GB11708@linux-sh.org>
On Tue, Jan 22, 2013 at 1:19 AM, Paul Mundt <lethal@linux-sh.org> wrote:
> On Tue, Jan 22, 2013 at 12:21:23AM -0800, Olof Johansson wrote:
>> On Mon, Jan 21, 2013 at 04:31:43PM +0100, Laurent Pinchart wrote:
>> > Sure, we could push 1-6 through the ARM tree, wait until it reaches mainline,
>> > then push 7 through the pinctrl tree, wait until it reaches mainline, push 8
>> > through the SH tree and 9 through the ARM tree, wait until they reach
>> > mainline, and finally push 10 through the pinctrl tree again. We could even
>> > push each branch through the tree it belongs to, but I doubt we'll be able to
>> > push everything during a single merge window.
>>
>> Ah, ok -- you're suggesting bringing it _all_ in through arm-soc. We
>> can do so, I was of the initial impression from Simon's cover letter
>> that the arch/sh branches would also go through the SH tree.
>>
>> This seems to be a particularly hairy conversion, given that it touches two
>> architectures that need to be updated in lockstep. I guess we might be just as
>> well off pulling it in as-is (with below exceptions) to get it in.
>>
>> If you need the same contents in the SH tree due to dependencies and
>> later development, let me know and we can agree on a stable branch that
>> we both pick up in either tree that has all contents.
>>
> There isn't anything at the moment pending for the SH tree that cares
> about or conflicts with any of this work, so it's ok with me if this all
> goes through arm-soc. If there is any fallout we can take care of it
> later on in the merge window. This would seem to be a saner option than
> attempting to merge half a dozen branches with dependencies on each other
> in precise order, which doesn't leave a lot of time for fixing up
> any residual merge window damage.
Yup, that sounds good. Let's do it that way.
-Olof
^ permalink raw reply
* [PATCH v4 0/8] MFD: ti_am335x_tscadc: DT support and TSC features addition
From: Patil, Rachna @ 2013-01-24 3:45 UTC (permalink / raw)
To: linux-arm-kernel
From: "Patil, Rachna" <rachna@ti.com>
This patch set is a cumulative set of [1] and [2] sent earlier.
Note that there are no code changes in either of the patch set,
only rebased on top of Linus's v3.8-rc3 tag to make sure that
all the patches apply without any conflicts.
This patch set has been tested on AM335x EVM.
[1] http://www.spinics.net/lists/linux-input/msg23060.html
[2] http://www.spinics.net/lists/linux-input/msg23090.html
Changes in v4:
Subnodes and their properties documentation added.
Non-standard properties prefixed with vendor name.
Changes in v3:
No code change.
Changes in v2:
Patch "input: ti_am335x_tsc: Add variance filter"
from v1 has been dropped.
Add MFD device DT node in AM335x EVM.
Patil, Rachna (8):
input: ti_am335x_tsc: Step enable bits made configurable
input: ti_am335x_tsc: Order of TSC wires, made configurable
input: touchscreen: ti_tsc: remove unwanted fifo flush
MFD: ti_am335x_tscadc: add device tree binding information
MFD: ti_am335x_tscadc: Add DT support
input: ti_am335x_tsc: Add DT support
IIO: ti_am335x_adc: Add DT support
arm/dts: AM335x-evm: Add TSC/ADC MFD device support
.../devicetree/bindings/mfd/ti_am335x_tscadc.txt | 52 ++++
arch/arm/boot/dts/am335x-evm.dts | 13 +
arch/arm/boot/dts/am33xx.dtsi | 8 +
drivers/iio/adc/ti_am335x_adc.c | 26 +-
drivers/input/touchscreen/ti_am335x_tsc.c | 266 +++++++++++++++++---
drivers/mfd/ti_am335x_tscadc.c | 28 ++-
include/linux/input/ti_am335x_tsc.h | 12 +
include/linux/mfd/ti_am335x_tscadc.h | 11 +-
8 files changed, 364 insertions(+), 52 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/ti_am335x_tscadc.txt
--
1.7.9.5
^ permalink raw reply
* [PATCH v4 1/8] input: ti_am335x_tsc: Step enable bits made configurable
From: Patil, Rachna @ 2013-01-24 3:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358999112-31192-1-git-send-email-rachna@ti.com>
From: "Patil, Rachna" <rachna@ti.com>
Current code has hard coded value written to
step enable bits. Now the bits are updated based
on how many steps are needed to be configured got
from platform data.
The user needs to take care not to exceed
the count more than 16. While using ADC and TSC
one should take care to set this parameter correctly.
Signed-off-by: Patil, Rachna <rachna@ti.com>
---
drivers/input/touchscreen/ti_am335x_tsc.c | 10 ++++++++--
include/linux/mfd/ti_am335x_tscadc.h | 1 -
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index 51e7b87..da652e0 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -39,6 +39,7 @@ struct titsc {
unsigned int irq;
unsigned int wires;
unsigned int x_plate_resistance;
+ unsigned int enable_bits;
bool pen_down;
int steps_to_configure;
};
@@ -57,6 +58,7 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg,
static void titsc_step_config(struct titsc *ts_dev)
{
unsigned int config;
+ unsigned int stepenable = 0;
int i, total_steps;
/* Configure the Step registers */
@@ -128,7 +130,11 @@ static void titsc_step_config(struct titsc *ts_dev)
titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
STEPCONFIG_OPENDLY);
- titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
+ for (i = 0; i <= (total_steps + 2); i++)
+ stepenable |= 1 << i;
+ ts_dev->enable_bits = stepenable;
+
+ titsc_writel(ts_dev, REG_SE, ts_dev->enable_bits);
}
static void titsc_read_coordinates(struct titsc *ts_dev,
@@ -250,7 +256,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
- titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
+ titsc_writel(ts_dev, REG_SE, ts_dev->enable_bits);
return IRQ_HANDLED;
}
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index c79ad5d..23e4f33 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -47,7 +47,6 @@
#define STEPENB_MASK (0x1FFFF << 0)
#define STEPENB(val) ((val) << 0)
#define STPENB_STEPENB STEPENB(0x1FFFF)
-#define STPENB_STEPENB_TC STEPENB(0x1FFF)
/* IRQ enable */
#define IRQENB_HW_PEN BIT(0)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 2/8] input: ti_am335x_tsc: Order of TSC wires, made configurable
From: Patil, Rachna @ 2013-01-24 3:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358999112-31192-1-git-send-email-rachna@ti.com>
From: "Patil, Rachna" <rachna@ti.com>
The current driver expected touchscreen input
wires(XP,XN,YP,YN) to be connected in a particular order.
Making changes to accept this as platform data.
Signed-off-by: Patil, Rachna <rachna@ti.com>
---
drivers/input/touchscreen/ti_am335x_tsc.c | 156 ++++++++++++++++++++++++++---
include/linux/input/ti_am335x_tsc.h | 12 +++
include/linux/mfd/ti_am335x_tscadc.h | 10 +-
3 files changed, 159 insertions(+), 19 deletions(-)
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index da652e0..0c460f9 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -33,6 +33,17 @@
#define SEQ_SETTLE 275
#define MAX_12BIT ((1 << 12) - 1)
+/*
+ * Refer to function regbit_map() to
+ * map the values in the matrix.
+ */
+static int config[4][4] = {
+ {1, 0, 1, 0},
+ {2, 3, 2, 3},
+ {4, 5, 4, 5},
+ {0, 6, 0, 6}
+};
+
struct titsc {
struct input_dev *input;
struct ti_tscadc_dev *mfd_tscadc;
@@ -42,6 +53,9 @@ struct titsc {
unsigned int enable_bits;
bool pen_down;
int steps_to_configure;
+ int config_inp[20];
+ int bit_xp, bit_xn, bit_yp, bit_yn;
+ int inp_xp, inp_xn, inp_yp, inp_yn;
};
static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
@@ -55,6 +69,107 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg,
writel(val, tsc->mfd_tscadc->tscadc_base + reg);
}
+/*
+ * Each of the analog lines are mapped
+ * with one or two register bits,
+ * which can be either pulled high/low
+ * depending on the value to be read.
+ */
+static int regbit_map(int val)
+{
+ int map_bits = 0;
+
+ switch (val) {
+ case 1:
+ map_bits = XPP;
+ break;
+ case 2:
+ map_bits = XNP;
+ break;
+ case 3:
+ map_bits = XNN;
+ break;
+ case 4:
+ map_bits = YPP;
+ break;
+ case 5:
+ map_bits = YPN;
+ break;
+ case 6:
+ map_bits = YNN;
+ break;
+ }
+
+ return map_bits;
+}
+
+static int titsc_config_wires(struct titsc *ts_dev)
+{
+ int analog_line[10], wire_order[10];
+ int i, temp_bits, err;
+
+ for (i = 0; i < 4; i++) {
+ /*
+ * Get the order in which TSC wires are attached
+ * w.r.t. each of the analog input lines on the EVM.
+ */
+ analog_line[i] = ts_dev->config_inp[i] & 0xF0;
+ analog_line[i] = analog_line[i] >> 4;
+
+ wire_order[i] = ts_dev->config_inp[i] & 0x0F;
+ }
+
+ for (i = 0; i < 4; i++) {
+ switch (wire_order[i]) {
+ case 0:
+ temp_bits = config[analog_line[i]][0];
+ if (temp_bits == 0) {
+ err = -EINVAL;
+ goto ret;
+ } else {
+ ts_dev->bit_xp = regbit_map(temp_bits);
+ ts_dev->inp_xp = analog_line[i];
+ break;
+ }
+ case 1:
+ temp_bits = config[analog_line[i]][1];
+ if (temp_bits == 0) {
+ err = -EINVAL;
+ goto ret;
+ } else {
+ ts_dev->bit_xn = regbit_map(temp_bits);
+ ts_dev->inp_xn = analog_line[i];
+ break;
+ }
+ case 2:
+ temp_bits = config[analog_line[i]][2];
+ if (temp_bits == 0) {
+ err = -EINVAL;
+ goto ret;
+ } else {
+ ts_dev->bit_yp = regbit_map(temp_bits);
+ ts_dev->inp_yp = analog_line[i];
+ break;
+ }
+ case 3:
+ temp_bits = config[analog_line[i]][3];
+ if (temp_bits == 0) {
+ err = -EINVAL;
+ goto ret;
+ } else {
+ ts_dev->bit_yn = regbit_map(temp_bits);
+ ts_dev->inp_yn = analog_line[i];
+ break;
+ }
+ }
+ }
+
+ return 0;
+
+ret:
+ return err;
+}
+
static void titsc_step_config(struct titsc *ts_dev)
{
unsigned int config;
@@ -65,18 +180,18 @@ static void titsc_step_config(struct titsc *ts_dev)
total_steps = 2 * ts_dev->steps_to_configure;
config = STEPCONFIG_MODE_HWSYNC |
- STEPCONFIG_AVG_16 | STEPCONFIG_XPP;
+ STEPCONFIG_AVG_16 | ts_dev->bit_xp;
switch (ts_dev->wires) {
case 4:
- config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN;
+ config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn;
break;
case 5:
- config |= STEPCONFIG_YNN |
- STEPCONFIG_INP_AN4 | STEPCONFIG_XNN |
- STEPCONFIG_YPP;
+ config |= ts_dev->bit_yn |
+ STEPCONFIG_INP_AN4 | ts_dev->bit_xn |
+ ts_dev->bit_yp;
break;
case 8:
- config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN;
+ config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn;
break;
}
@@ -87,18 +202,18 @@ static void titsc_step_config(struct titsc *ts_dev)
config = 0;
config = STEPCONFIG_MODE_HWSYNC |
- STEPCONFIG_AVG_16 | STEPCONFIG_YNN |
+ STEPCONFIG_AVG_16 | ts_dev->bit_yn |
STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1;
switch (ts_dev->wires) {
case 4:
- config |= STEPCONFIG_YPP;
+ config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
break;
case 5:
- config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 |
- STEPCONFIG_XNP | STEPCONFIG_YPN;
+ config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 |
+ ts_dev->bit_xn | ts_dev->bit_yp;
break;
case 8:
- config |= STEPCONFIG_YPP;
+ config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
break;
}
@@ -109,9 +224,9 @@ static void titsc_step_config(struct titsc *ts_dev)
config = 0;
/* Charge step configuration */
- config = STEPCONFIG_XPP | STEPCONFIG_YNN |
+ config = ts_dev->bit_xp | ts_dev->bit_yn |
STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR |
- STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1;
+ STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp);
titsc_writel(ts_dev, REG_CHARGECONFIG, config);
titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
@@ -119,13 +234,14 @@ static void titsc_step_config(struct titsc *ts_dev)
config = 0;
/* Configure to calculate pressure */
config = STEPCONFIG_MODE_HWSYNC |
- STEPCONFIG_AVG_16 | STEPCONFIG_YPP |
- STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM;
+ STEPCONFIG_AVG_16 | ts_dev->bit_yp |
+ ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
+ STEPCONFIG_INP(ts_dev->inp_xp);
titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config);
titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1),
STEPCONFIG_OPENDLY);
- config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1;
+ config |= STEPCONFIG_INP(ts_dev->inp_yn) | STEPCONFIG_FIFO1;
titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config);
titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
STEPCONFIG_OPENDLY);
@@ -295,6 +411,8 @@ static int titsc_probe(struct platform_device *pdev)
ts_dev->wires = pdata->tsc_init->wires;
ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance;
ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure;
+ memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config,
+ sizeof(pdata->tsc_init->wire_config));
err = request_irq(ts_dev->irq, titsc_irq,
0, pdev->dev.driver->name, ts_dev);
@@ -304,6 +422,11 @@ static int titsc_probe(struct platform_device *pdev)
}
titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
+ err = titsc_config_wires(ts_dev);
+ if (err) {
+ dev_err(&pdev->dev, "wrong i/p wire configuration\n");
+ goto err_free_irq;
+ }
titsc_step_config(ts_dev);
titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure);
@@ -373,6 +496,7 @@ static int titsc_resume(struct device *dev)
0x00);
titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
}
+ titsc_config_wires(ts_dev);
titsc_step_config(ts_dev);
titsc_writel(ts_dev, REG_FIFO0THR,
ts_dev->steps_to_configure);
diff --git a/include/linux/input/ti_am335x_tsc.h b/include/linux/input/ti_am335x_tsc.h
index 49269a2..6a66b4d 100644
--- a/include/linux/input/ti_am335x_tsc.h
+++ b/include/linux/input/ti_am335x_tsc.h
@@ -12,12 +12,24 @@
* A step configured to read a single
* co-ordinate value, can be applied
* more number of times for better results.
+ * @wire_config: Different EVM's could have a different order
+ * for connecting wires on touchscreen.
+ * We need to provide an 8 bit number where in
+ * the 1st four bits represent the analog lines
+ * and the next 4 bits represent positive/
+ * negative terminal on that input line.
+ * Notations to represent the input lines and
+ * terminals resoectively is as follows:
+ * AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7.
+ * XP = 0, XN = 1, YP = 2, YN = 3.
+ *
*/
struct tsc_data {
int wires;
int x_plate_resistance;
int steps_to_configure;
+ int wire_config[10];
};
#endif
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index 23e4f33..9624fea 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -72,8 +72,6 @@
#define STEPCONFIG_INM_ADCREFM STEPCONFIG_INM(8)
#define STEPCONFIG_INP_MASK (0xF << 19)
#define STEPCONFIG_INP(val) ((val) << 19)
-#define STEPCONFIG_INP_AN2 STEPCONFIG_INP(2)
-#define STEPCONFIG_INP_AN3 STEPCONFIG_INP(3)
#define STEPCONFIG_INP_AN4 STEPCONFIG_INP(4)
#define STEPCONFIG_INP_ADCREFM STEPCONFIG_INP(8)
#define STEPCONFIG_FIFO1 BIT(26)
@@ -95,7 +93,6 @@
#define STEPCHARGE_INM_AN1 STEPCHARGE_INM(1)
#define STEPCHARGE_INP_MASK (0xF << 19)
#define STEPCHARGE_INP(val) ((val) << 19)
-#define STEPCHARGE_INP_AN1 STEPCHARGE_INP(1)
#define STEPCHARGE_RFM_MASK (3 << 23)
#define STEPCHARGE_RFM(val) ((val) << 23)
#define STEPCHARGE_RFM_XNUR STEPCHARGE_RFM(1)
@@ -117,6 +114,13 @@
#define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3)
#define CNTRLREG_TSCENB BIT(7)
+#define XPP STEPCONFIG_XPP
+#define XNP STEPCONFIG_XNP
+#define XNN STEPCONFIG_XNN
+#define YPP STEPCONFIG_YPP
+#define YPN STEPCONFIG_YPN
+#define YNN STEPCONFIG_YNN
+
#define ADC_CLK 3000000
#define MAX_CLK_DIV 7
#define TOTAL_STEPS 16
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 3/8] input: touchscreen: ti_tsc: remove unwanted fifo flush
From: Patil, Rachna @ 2013-01-24 3:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358999112-31192-1-git-send-email-rachna@ti.com>
From: "Patil, Rachna" <rachna@ti.com>
When touchscreen and ADC are used together, this
unwanted fifo flush leads to loss of ADC data.
Signed-off-by: Patil, Rachna <rachna@ti.com>
---
drivers/input/touchscreen/ti_am335x_tsc.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index 0c460f9..064d2b2 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -308,8 +308,6 @@ static irqreturn_t titsc_irq(int irq, void *dev)
unsigned int x = 0, y = 0;
unsigned int z1, z2, z;
unsigned int fsm;
- unsigned int fifo1count, fifo0count;
- int i;
status = titsc_readl(ts_dev, REG_IRQSTATUS);
if (status & IRQENB_FIFO0THRES) {
@@ -318,14 +316,6 @@ static irqreturn_t titsc_irq(int irq, void *dev)
z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff;
z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff;
- fifo1count = titsc_readl(ts_dev, REG_FIFO1CNT);
- for (i = 0; i < fifo1count; i++)
- titsc_readl(ts_dev, REG_FIFO1);
-
- fifo0count = titsc_readl(ts_dev, REG_FIFO0CNT);
- for (i = 0; i < fifo0count; i++)
- titsc_readl(ts_dev, REG_FIFO0);
-
if (ts_dev->pen_down && z1 != 0 && z2 != 0) {
/*
* Calculate pressure using formula
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 4/8] MFD: ti_am335x_tscadc: add device tree binding information
From: Patil, Rachna @ 2013-01-24 3:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358999112-31192-1-git-send-email-rachna@ti.com>
From: "Patil, Rachna" <rachna@ti.com>
Signed-off-by: Patil, Rachna <rachna@ti.com>
---
Changes in v4:
Subnodes and their properties documentation added.
Non-standard properties prefixed with vendor name.
.../devicetree/bindings/mfd/ti_am335x_tscadc.txt | 52 ++++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/ti_am335x_tscadc.txt
diff --git a/Documentation/devicetree/bindings/mfd/ti_am335x_tscadc.txt b/Documentation/devicetree/bindings/mfd/ti_am335x_tscadc.txt
new file mode 100644
index 0000000..0100771
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/ti_am335x_tscadc.txt
@@ -0,0 +1,52 @@
+Texas Instruments - TSC / ADC multi-functional device
+
+ti_tscadc is a multi-function device with touchscreen and ADC on chip.
+This document describes the binding for mfd device.
+
+Required properties:
+- compatible: "ti,ti-tscadc"
+- reg: Specifies the address of MFD block
+- interrupts: IRQ line connected to the main SoC
+- interrupt-parent: The parent interrupt controller
+
+Optional properties:
+- ti,hwmods: Hardware information related to TSC/ADC MFD device
+
+Sub-nodes:
+Device Description
+------ -----------
+tsc Touchscreen
+adc Analog to digital converter
+
+Sub-node device required properties:
+tsc:
+- ti,wires: 4/5/8 wire touchscreen support on the platform.
+- ti,x-plate-resistance: X plate resistance.
+- ti,steps-to-configure: A step is configured to read a single co-ordinate value,
+ can be applied more number of times for better results.
+- ti,wire-config: Order for connecting wires on touchscreen.
+
+adc:
+- ti,adc-channels: Number of ADC channels used.
+
+Example:
+
+ tscadc: tscadc at 44e0d000 {
+ compatible = "ti,ti-tscadc";
+ reg = <0x44e0d000 0x1000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <16>;
+ ti,hwmods = "adc_tsc";
+
+ tsc {
+ ti,wires = <4>;
+ ti,x-plate-resistance = <200>;
+ ti,steps-to-configure = <5>;
+ ti,wire-config = <0x00 0x11 0x22 0x33>;
+ };
+
+ adc {
+ ti,adc-channels = <4>;
+ };
+ };
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 5/8] MFD: ti_am335x_tscadc: Add DT support
From: Patil, Rachna @ 2013-01-24 3:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358999112-31192-1-git-send-email-rachna@ti.com>
From: "Patil, Rachna" <rachna@ti.com>
Make changes to add DT support in the MFD core driver.
Signed-off-by: Patil, Rachna <rachna@ti.com>
---
Changes in v4:
Non-standard properties prefixed with vendor name.
drivers/mfd/ti_am335x_tscadc.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index e9f3fb5..87b446b 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -22,6 +22,8 @@
#include <linux/regmap.h>
#include <linux/mfd/core.h>
#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/mfd/ti_am335x_tscadc.h>
#include <linux/input/ti_am335x_tsc.h>
@@ -64,20 +66,31 @@ static int ti_tscadc_probe(struct platform_device *pdev)
struct resource *res;
struct clk *clk;
struct mfd_tscadc_board *pdata = pdev->dev.platform_data;
+ struct device_node *node = pdev->dev.of_node;
struct mfd_cell *cell;
int err, ctrl;
int clk_value, clock_rate;
- int tsc_wires, adc_channels = 0, total_channels;
+ int tsc_wires = 0, adc_channels = 0, total_channels;
- if (!pdata) {
+ if (!pdata && !pdev->dev.of_node) {
dev_err(&pdev->dev, "Could not find platform data\n");
return -EINVAL;
}
- if (pdata->adc_init)
- adc_channels = pdata->adc_init->adc_channels;
+ if (pdev->dev.platform_data) {
+ if (pdata->tsc_init)
+ tsc_wires = pdata->tsc_init->wires;
+
+ if (pdata->adc_init)
+ adc_channels = pdata->adc_init->adc_channels;
+ } else {
+ node = of_find_node_by_name(pdev->dev.of_node, "tsc");
+ of_property_read_u32(node, "ti,wires", &tsc_wires);
+
+ node = of_find_node_by_name(pdev->dev.of_node, "adc");
+ of_property_read_u32(node, "ti,adc-channels", &adc_channels);
+ }
- tsc_wires = pdata->tsc_init->wires;
total_channels = tsc_wires + adc_channels;
if (total_channels > 8) {
@@ -256,11 +269,16 @@ static const struct dev_pm_ops tscadc_pm_ops = {
#define TSCADC_PM_OPS NULL
#endif
+static const struct of_device_id ti_tscadc_dt_ids[] = {
+ { .compatible = "ti,ti-tscadc", },
+};
+
static struct platform_driver ti_tscadc_driver = {
.driver = {
.name = "ti_tscadc",
.owner = THIS_MODULE,
.pm = TSCADC_PM_OPS,
+ .of_match_table = of_match_ptr(ti_tscadc_dt_ids),
},
.probe = ti_tscadc_probe,
.remove = ti_tscadc_remove,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 6/8] input: ti_am335x_tsc: Add DT support
From: Patil, Rachna @ 2013-01-24 3:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358999112-31192-1-git-send-email-rachna@ti.com>
From: "Patil, Rachna" <rachna@ti.com>
Add DT support for client touchscreen driver
Signed-off-by: Patil, Rachna <rachna@ti.com>
---
Changes in v4:
Non-standard properties prefixed with vendor name.
drivers/input/touchscreen/ti_am335x_tsc.c | 94 +++++++++++++++++++++++++----
1 file changed, 81 insertions(+), 13 deletions(-)
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index 064d2b2..6ff5a76 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -26,6 +26,8 @@
#include <linux/io.h>
#include <linux/input/ti_am335x_tsc.h>
#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/mfd/ti_am335x_tscadc.h>
@@ -366,6 +368,74 @@ static irqreturn_t titsc_irq(int irq, void *dev)
return IRQ_HANDLED;
}
+static int titsc_parse_dt(struct ti_tscadc_dev *tscadc_dev,
+ struct titsc *ts_dev)
+{
+ struct device_node *node = tscadc_dev->dev->of_node;
+ int err, i;
+ u32 val32, wires_conf[4];
+
+ if (!node)
+ return -EINVAL;
+ else {
+ node = of_find_node_by_name(node, "tsc");
+ if (!node)
+ return -EINVAL;
+ else {
+ err = of_property_read_u32(node, "ti,wires", &val32);
+ if (err < 0)
+ goto error_ret;
+ else
+ ts_dev->wires = val32;
+
+ err = of_property_read_u32(node,
+ "ti,x-plate-resistance", &val32);
+ if (err < 0)
+ goto error_ret;
+ else
+ ts_dev->x_plate_resistance = val32;
+
+ err = of_property_read_u32(node,
+ "ti,steps-to-configure", &val32);
+ if (err < 0)
+ goto error_ret;
+ else
+ ts_dev->steps_to_configure = val32;
+
+ err = of_property_read_u32_array(node, "ti,wire-config",
+ wires_conf, ARRAY_SIZE(wires_conf));
+ if (err < 0)
+ goto error_ret;
+ else {
+ for (i = 0; i < ARRAY_SIZE(wires_conf); i++)
+ ts_dev->config_inp[i] = wires_conf[i];
+ }
+ }
+ }
+ return 0;
+
+error_ret:
+ return err;
+}
+
+static int titsc_parse_pdata(struct ti_tscadc_dev *tscadc_dev,
+ struct titsc *ts_dev)
+{
+ struct mfd_tscadc_board *pdata = tscadc_dev->dev->platform_data;
+
+ if (!pdata)
+ return -EINVAL;
+
+ ts_dev->wires = pdata->tsc_init->wires;
+ ts_dev->x_plate_resistance =
+ pdata->tsc_init->x_plate_resistance;
+ ts_dev->steps_to_configure =
+ pdata->tsc_init->steps_to_configure;
+ memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config,
+ sizeof(pdata->tsc_init->wire_config));
+ return 0;
+}
+
/*
* The functions for inserting/removing driver as a module.
*/
@@ -375,16 +445,8 @@ static int titsc_probe(struct platform_device *pdev)
struct titsc *ts_dev;
struct input_dev *input_dev;
struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
- struct mfd_tscadc_board *pdata;
int err;
- pdata = tscadc_dev->dev->platform_data;
-
- if (!pdata) {
- dev_err(&pdev->dev, "Could not find platform data\n");
- return -EINVAL;
- }
-
/* Allocate memory for device */
ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL);
input_dev = input_allocate_device();
@@ -398,11 +460,17 @@ static int titsc_probe(struct platform_device *pdev)
ts_dev->mfd_tscadc = tscadc_dev;
ts_dev->input = input_dev;
ts_dev->irq = tscadc_dev->irq;
- ts_dev->wires = pdata->tsc_init->wires;
- ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance;
- ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure;
- memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config,
- sizeof(pdata->tsc_init->wire_config));
+
+ if (tscadc_dev->dev->platform_data)
+ err = titsc_parse_pdata(tscadc_dev, ts_dev);
+ else
+ err = titsc_parse_dt(tscadc_dev, ts_dev);
+
+ if (err) {
+ dev_err(&pdev->dev, "Could not find platform data\n");
+ err = -EINVAL;
+ goto err_free_mem;
+ }
err = request_irq(ts_dev->irq, titsc_irq,
0, pdev->dev.driver->name, ts_dev);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 7/8] IIO: ti_am335x_adc: Add DT support
From: Patil, Rachna @ 2013-01-24 3:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358999112-31192-1-git-send-email-rachna@ti.com>
From: "Patil, Rachna" <rachna@ti.com>
Add DT support for client ADC driver.
Signed-off-by: Patil, Rachna <rachna@ti.com>
---
Changes in v4:
Non-standard properties prefixed with vendor name.
drivers/iio/adc/ti_am335x_adc.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index cd030e1..8e7b089 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -22,6 +22,8 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/iio/iio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/mfd/ti_am335x_tscadc.h>
#include <linux/platform_data/ti_am335x_adc.h>
@@ -141,11 +143,12 @@ static int tiadc_probe(struct platform_device *pdev)
struct iio_dev *indio_dev;
struct tiadc_device *adc_dev;
struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
- struct mfd_tscadc_board *pdata;
+ struct mfd_tscadc_board *pdata = tscadc_dev->dev->platform_data;
+ struct device_node *node = tscadc_dev->dev->of_node;
int err;
+ u32 val32;
- pdata = tscadc_dev->dev->platform_data;
- if (!pdata || !pdata->adc_init) {
+ if (!pdata && !node) {
dev_err(&pdev->dev, "Could not find platform data\n");
return -EINVAL;
}
@@ -159,7 +162,22 @@ static int tiadc_probe(struct platform_device *pdev)
adc_dev = iio_priv(indio_dev);
adc_dev->mfd_tscadc = tscadc_dev;
- adc_dev->channels = pdata->adc_init->adc_channels;
+
+ if (pdata)
+ adc_dev->channels = pdata->adc_init->adc_channels;
+ else {
+ node = of_find_node_by_name(node, "adc");
+ if (!node)
+ return -EINVAL;
+ else {
+ err = of_property_read_u32(node,
+ "ti,adc-channels", &val32);
+ if (err < 0)
+ goto err_free_device;
+ else
+ adc_dev->channels = val32;
+ }
+ }
indio_dev->dev.parent = &pdev->dev;
indio_dev->name = dev_name(&pdev->dev);
--
1.7.9.5
^ 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