* [PATCH v2 1/3] ARM: Kirkwood: Remove unused includes
From: Andrew Lunn @ 2012-10-20 11:23 UTC (permalink / raw)
To: linux-arm-kernel
With the gradual conversion of C code to DT, there are a number of
include files which are no longer needed. Remove them.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
arch/arm/mach-kirkwood/board-dockstar.c | 13 -------------
arch/arm/mach-kirkwood/board-dreamplug.c | 15 ---------------
arch/arm/mach-kirkwood/board-goflexnet.c | 13 -------------
arch/arm/mach-kirkwood/board-ib62x0.c | 6 ------
arch/arm/mach-kirkwood/board-iconnect.c | 8 --------
arch/arm/mach-kirkwood/board-iomega_ix2_200.c | 2 --
arch/arm/mach-kirkwood/board-lsxl.c | 8 --------
arch/arm/mach-kirkwood/board-ts219.c | 3 ---
8 files changed, 68 deletions(-)
diff --git a/arch/arm/mach-kirkwood/board-dockstar.c b/arch/arm/mach-kirkwood/board-dockstar.c
index f2fbb02..6912882 100644
--- a/arch/arm/mach-kirkwood/board-dockstar.c
+++ b/arch/arm/mach-kirkwood/board-dockstar.c
@@ -16,21 +16,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
#include <linux/gpio.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/kirkwood.h>
-#include <mach/bridge-regs.h>
-#include <linux/platform_data/mmc-mvsdio.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c
index 20af53a..8a8ebe0 100644
--- a/arch/arm/mach-kirkwood/board-dreamplug.c
+++ b/arch/arm/mach-kirkwood/board-dreamplug.c
@@ -13,23 +13,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
#include <linux/gpio.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/kirkwood.h>
-#include <mach/bridge-regs.h>
#include <linux/platform_data/mmc-mvsdio.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-goflexnet.c b/arch/arm/mach-kirkwood/board-goflexnet.c
index 001ca8c..5dcd0d6 100644
--- a/arch/arm/mach-kirkwood/board-goflexnet.c
+++ b/arch/arm/mach-kirkwood/board-goflexnet.c
@@ -18,21 +18,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
#include <linux/gpio.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/kirkwood.h>
-#include <mach/bridge-regs.h>
-#include <linux/platform_data/mmc-mvsdio.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-ib62x0.c b/arch/arm/mach-kirkwood/board-ib62x0.c
index cfc47f8..6d3a564 100644
--- a/arch/arm/mach-kirkwood/board-ib62x0.c
+++ b/arch/arm/mach-kirkwood/board-ib62x0.c
@@ -13,15 +13,9 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/partitions.h>
-#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/input.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c
index d084b1e..24f5aa7 100644
--- a/arch/arm/mach-kirkwood/board-iconnect.c
+++ b/arch/arm/mach-kirkwood/board-iconnect.c
@@ -10,16 +10,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/gpio.h>
-#include <asm/mach/arch.h>
-#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
index 158fb97..e4ed62c 100644
--- a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
+++ b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
@@ -10,10 +10,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
-#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-lsxl.c b/arch/arm/mach-kirkwood/board-lsxl.c
index 83d8975..64e5cc6 100644
--- a/arch/arm/mach-kirkwood/board-lsxl.c
+++ b/arch/arm/mach-kirkwood/board-lsxl.c
@@ -14,17 +14,9 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/partitions.h>
-#include <linux/ata_platform.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/gpio-fan.h>
-#include <linux/input.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-ts219.c b/arch/arm/mach-kirkwood/board-ts219.c
index 1750e68..f3bfeda 100644
--- a/arch/arm/mach-kirkwood/board-ts219.c
+++ b/arch/arm/mach-kirkwood/board-ts219.c
@@ -19,9 +19,6 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mv643xx_eth.h>
-#include <linux/ata_platform.h>
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
--
1.7.10.4
^ permalink raw reply related
* [PATCH] ARM: Kirkwood: new board USI Topkick
From: Jason Cooper @ 2012-10-20 11:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121020085834.GY21046@lunn.ch>
On Sat, Oct 20, 2012 at 10:58:34AM +0200, Andrew Lunn wrote:
> > +++ b/arch/arm/boot/dts/kirkwood-topkick.dts
> > @@ -0,0 +1,85 @@
> > +/dts-v1/;
> > +
> > +/include/ "kirkwood.dtsi"
> > +
> > +/ {
> > + model = "Univeral Scientific Industrial Co. Topkick-1281P2";
> > + compatible = "usi,topkick-1281P2", "usi,topkick", "marvell,kirkwood-88f6282", "marvell,kirkwood";
>
> Hi Jason
>
> Nice to see the correct Kirkwood variant in DT. This is going to be an
> issue for pinctrl sometime soon.
>
> > +
> > + sata at 80000 {
> > + status = "okay";
> > + nr-ports = <2>;
>
> Could nr-ports be 1? It saves a little bit of memory. There only seems
> to be one SATA interface available, no external SATA port. However, if
> the one used is the second SATA, then 2 is required.
Yes, I caught this right after <send>, and mentioned it on irc for v2.
It was part of my, "did they wire it up to sata1, instead?" effort.
Sebastian was a huge help getting sata and the leds working.
>
> > diff --git a/arch/arm/mach-kirkwood/board-usi_topkick.c b/arch/arm/mach-kirkwood/board-usi_topkick.c
> > new file mode 100644
> > index 0000000..02ba4aa
> > --- /dev/null
> > +++ b/arch/arm/mach-kirkwood/board-usi_topkick.c
> > @@ -0,0 +1,93 @@
> > +/*
> > + * 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/platform_device.h>
> > +#include <linux/ata_platform.h>
> > +#include <linux/mv643xx_eth.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_fdt.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/gpio.h>
> > +#include <linux/mtd/physmap.h>
> > +#include <linux/spi/flash.h>
> > +#include <linux/spi/spi.h>
> > +#include <asm/mach-types.h>
> > +#include <asm/mach/arch.h>
> > +#include <asm/mach/map.h>
> > +#include <mach/kirkwood.h>
> > +#include <mach/bridge-regs.h>
> > +#include <linux/platform_data/mmc-mvsdio.h>
> > +#include "common.h"
> > +#include "mpp.h"
>
> A lot of these header files are not needed. Please could you remove
> the unused ones.
Sure, and I'll go back and double check dreamplug. ;-)
>
> > +
> > +static struct mv643xx_eth_platform_data topkick_ge00_data = {
> > + .phy_addr = MV643XX_ETH_PHY_ADDR(0),
> > +};
> > +
> > +/*
> > + * GPIO LED layout
> > + *
> > + * /-SYS_LED(2)
> > + * |
> > + * | /-DISK_LED
> > + * | |
> > + * | | /-WLAN_LED(2)
> > + * | | |
> > + * [SW] [*] [*] [*]
> > + */
> > +
> > +/*
> > + * Switch positions
> > + *
> > + * /-SW_LEFT
> > + * |
> > + * | /-SW_IDLE
> > + * | |
> > + * | | /-SW_RIGHT
> > + * | | |
> > + * PS [L] [I] [R] LEDS
> > + */
> > +
> > +static unsigned int topkick_mpp_config[] __initdata = {
> > + MPP21_GPIO, /* DISK_LED (low active) - yellow */
> > + MPP36_GPIO, /* SATA0 power enable (high active) */
> > + MPP37_GPIO, /* SYS_LED2 (low active) - red */
> > + MPP38_GPIO, /* SYS_LED (low active) - blue */
> > + MPP39_GPIO, /* WLAN_LED (low active) - green */
> > + MPP43_GPIO, /* SW_LEFT (low active) */
> > + MPP44_GPIO, /* SW_RIGHT (low active) */
> > + MPP45_GPIO, /* SW_IDLE (low active) */
> > + MPP46_GPIO, /* SW_LEFT (low active) */
> > + MPP48_GPIO, /* WLAN_LED2 (low active) - yellow */
> > + 0
>
> This assumes the boot loader is configuring all the other pins as
> needed. It would be safer to explicitly configure the SATA pins,
> Ethernet pins etc. However, maybe that should wait until we have
> pinctrl, which makes it a lot easier.
I agree.
>
> > +};
> > +
> > +#define TOPKICK_SATA0_PWR_ENABLE 36
> > +
> > +void __init usi_topkick_init(void)
> > +{
> > + /*
> > + * Basic setup. Needs to be called early.
> > + */
> > + kirkwood_mpp_conf(topkick_mpp_config);
> > +
> > + /* SATA0 power enable */
> > + gpio_set_value(TOPKICK_SATA0_PWR_ENABLE, 1);
>
> It would be nice to be able to do that in DT. Does such a binding
> already exist? Its something we need quite often in kirkwood, and i
> guess other machines architectures as well.
I was thinking about that and how to handle it once we are down to
board-dt.c. At the very least, we can expose the pin in sysfs and have
an initrd enable it for booting from HDD.
The ideal solution would be something similar to gpio-leds, where you
can set default-state = "on". This may already exist for gpios, I
haven't looked yet.
>
> > +
> > + kirkwood_ehci_init();
> > + kirkwood_ge00_init(&topkick_ge00_data);
> > +}
>
> How is the wifi device instantiated? Is it a PCIe device so it
> auto-probed? Or is some explicit instantiation required, say if its an
> SPI device?
I dunno, I don't usually enable wifi on my dreamplug, so I admit I
forgot to look.
>
> It would be good to add this board to kirkwood_defconfig as well.
Yes, already planned for v2.
Thanks for the review.
Jason.
^ permalink raw reply
* [PATCH 3/3] ARM: Kirkwood: checkpatch cleanups
From: Andrew Lunn @ 2012-10-20 11:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350729736-14539-3-git-send-email-andrew@lunn.ch>
> --- a/arch/arm/mach-kirkwood/cpuidle.c
> +++ b/arch/arm/mach-kirkwood/cpuidle.c
> @@ -20,7 +20,6 @@
> #include <linux/io.h>
> #include <linux/export.h>
> #include <asm/proc-fns.h>
> -#include <asm/cpuidle.h>
> #include <mach/kirkwood.h>
Upps. This breaks the build. V2 soon to be posted.
Andrew
^ permalink raw reply
* [PATCH v2 2/2] ARM: Kirkwood: Convert all DT boards to EHCI via DT.
From: Andrew Lunn @ 2012-10-20 11:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350731401-21442-1-git-send-email-andrew@lunn.ch>
Now that the EHCI driver has DT support, drop old style configuration
of it and add DT in its place. Since all the boards enable the EHCI,
enable it by default in kirkwood.dtsi. Any new boards which don't have
USB can specifically disable it.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
arch/arm/boot/dts/kirkwood.dtsi | 7 +++++++
arch/arm/mach-kirkwood/board-dnskw.c | 1 -
arch/arm/mach-kirkwood/board-dockstar.c | 1 -
arch/arm/mach-kirkwood/board-dreamplug.c | 1 -
arch/arm/mach-kirkwood/board-dt.c | 1 +
arch/arm/mach-kirkwood/board-goflexnet.c | 1 -
arch/arm/mach-kirkwood/board-ib62x0.c | 1 -
arch/arm/mach-kirkwood/board-iconnect.c | 1 -
arch/arm/mach-kirkwood/board-iomega_ix2_200.c | 2 --
arch/arm/mach-kirkwood/board-km_kirkwood.c | 1 -
arch/arm/mach-kirkwood/board-lsxl.c | 1 -
arch/arm/mach-kirkwood/board-ts219.c | 1 -
12 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index 4e5b815..4fc7a8e 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -77,6 +77,13 @@
status = "okay";
};
+ ehci at 50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <19>;
+ status = "okay";
+ };
+
sata at 80000 {
compatible = "marvell,orion-sata";
reg = <0x80000 0x5000>;
diff --git a/arch/arm/mach-kirkwood/board-dnskw.c b/arch/arm/mach-kirkwood/board-dnskw.c
index 43d16d6..2ac6c60 100644
--- a/arch/arm/mach-kirkwood/board-dnskw.c
+++ b/arch/arm/mach-kirkwood/board-dnskw.c
@@ -78,7 +78,6 @@ void __init dnskw_init(void)
{
kirkwood_mpp_conf(dnskw_mpp_config);
- kirkwood_ehci_init();
kirkwood_ge00_init(&dnskw_ge00_data);
/* Register power-off GPIO. */
diff --git a/arch/arm/mach-kirkwood/board-dockstar.c b/arch/arm/mach-kirkwood/board-dockstar.c
index f2fbb02..e94782d 100644
--- a/arch/arm/mach-kirkwood/board-dockstar.c
+++ b/arch/arm/mach-kirkwood/board-dockstar.c
@@ -55,7 +55,6 @@ void __init dockstar_dt_init(void)
if (gpio_request(29, "USB Power Enable") != 0 ||
gpio_direction_output(29, 1) != 0)
pr_err("can't setup GPIO 29 (USB Power Enable)\n");
- kirkwood_ehci_init();
kirkwood_ge00_init(&dockstar_ge00_data);
}
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c
index 20af53a..acdc04a 100644
--- a/arch/arm/mach-kirkwood/board-dreamplug.c
+++ b/arch/arm/mach-kirkwood/board-dreamplug.c
@@ -64,7 +64,6 @@ void __init dreamplug_init(void)
*/
kirkwood_mpp_conf(dreamplug_mpp_config);
- kirkwood_ehci_init();
kirkwood_ge00_init(&dreamplug_ge00_data);
kirkwood_ge01_init(&dreamplug_ge01_data);
kirkwood_sdio_init(&dreamplug_mvsdio_data);
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 70c5a28..ccb91b8 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -34,6 +34,7 @@ struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL),
OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1030000, "mv_crypto", NULL),
+ OF_DEV_AUXDATA("marvell,orion-ehci", 0xf1050000, "orion-ehci.0", NULL),
{},
};
diff --git a/arch/arm/mach-kirkwood/board-goflexnet.c b/arch/arm/mach-kirkwood/board-goflexnet.c
index 001ca8c..d388bea 100644
--- a/arch/arm/mach-kirkwood/board-goflexnet.c
+++ b/arch/arm/mach-kirkwood/board-goflexnet.c
@@ -65,7 +65,6 @@ void __init goflexnet_init(void)
if (gpio_request(29, "USB Power Enable") != 0 ||
gpio_direction_output(29, 1) != 0)
pr_err("can't setup GPIO 29 (USB Power Enable)\n");
- kirkwood_ehci_init();
kirkwood_ge00_init(&goflexnet_ge00_data);
}
diff --git a/arch/arm/mach-kirkwood/board-ib62x0.c b/arch/arm/mach-kirkwood/board-ib62x0.c
index cfc47f8..db08e37 100644
--- a/arch/arm/mach-kirkwood/board-ib62x0.c
+++ b/arch/arm/mach-kirkwood/board-ib62x0.c
@@ -61,7 +61,6 @@ void __init ib62x0_init(void)
*/
kirkwood_mpp_conf(ib62x0_mpp_config);
- kirkwood_ehci_init();
kirkwood_ge00_init(&ib62x0_ge00_data);
if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 &&
gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0)
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c
index d084b1e..8275fb0 100644
--- a/arch/arm/mach-kirkwood/board-iconnect.c
+++ b/arch/arm/mach-kirkwood/board-iconnect.c
@@ -45,7 +45,6 @@ void __init iconnect_init(void)
{
kirkwood_mpp_conf(iconnect_mpp_config);
- kirkwood_ehci_init();
kirkwood_ge00_init(&iconnect_ge00_data);
}
diff --git a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
index 158fb97..a6f3d29 100644
--- a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
+++ b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
@@ -51,7 +51,5 @@ void __init iomega_ix2_200_init(void)
*/
kirkwood_mpp_conf(iomega_ix2_200_mpp_config);
- kirkwood_ehci_init();
-
kirkwood_ge01_init(&iomega_ix2_200_ge00_data);
}
diff --git a/arch/arm/mach-kirkwood/board-km_kirkwood.c b/arch/arm/mach-kirkwood/board-km_kirkwood.c
index f7d3283..1e9ac4b 100644
--- a/arch/arm/mach-kirkwood/board-km_kirkwood.c
+++ b/arch/arm/mach-kirkwood/board-km_kirkwood.c
@@ -52,6 +52,5 @@ void __init km_kirkwood_init(void)
if (!IS_ERR(sata_clk))
sata_clk->flags |= CLK_IGNORE_UNUSED;
- kirkwood_ehci_init();
kirkwood_ge00_init(&km_kirkwood_ge00_data);
}
diff --git a/arch/arm/mach-kirkwood/board-lsxl.c b/arch/arm/mach-kirkwood/board-lsxl.c
index 83d8975..68e64b2 100644
--- a/arch/arm/mach-kirkwood/board-lsxl.c
+++ b/arch/arm/mach-kirkwood/board-lsxl.c
@@ -125,7 +125,6 @@ void __init lsxl_init(void)
gpio_set_value(LSXL_GPIO_USB_POWER, 1);
gpio_set_value(LSXL_GPIO_HDD_POWER, 1);
- kirkwood_ehci_init();
kirkwood_ge00_init(&lsxl_ge00_data);
kirkwood_ge01_init(&lsxl_ge01_data);
platform_device_register(&lsxl_fan_device);
diff --git a/arch/arm/mach-kirkwood/board-ts219.c b/arch/arm/mach-kirkwood/board-ts219.c
index 1750e68..5a031b9 100644
--- a/arch/arm/mach-kirkwood/board-ts219.c
+++ b/arch/arm/mach-kirkwood/board-ts219.c
@@ -66,7 +66,6 @@ void __init qnap_dt_ts219_init(void)
qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
kirkwood_ge00_init(&qnap_ts219_ge00_data);
- kirkwood_ehci_init();
pm_power_off = qnap_tsx1x_power_off;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 1/2] ARM: Kirkwood: ehci-orion: Add device tree binding
From: Andrew Lunn @ 2012-10-20 11:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350731401-21442-1-git-send-email-andrew@lunn.ch>
Based on previous work by Michael Walle and Jason Cooper.
Made their work actually work, which required added interrupt from DT
and auxdata, along with setting the dma_mask, which DT does not
currently do.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
---
.../devicetree/bindings/usb/ehci-orion.txt | 15 ++++++++
drivers/usb/host/ehci-orion.c | 38 ++++++++++++++++++--
2 files changed, 50 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/ehci-orion.txt
diff --git a/Documentation/devicetree/bindings/usb/ehci-orion.txt b/Documentation/devicetree/bindings/usb/ehci-orion.txt
new file mode 100644
index 0000000..6bc09ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ehci-orion.txt
@@ -0,0 +1,15 @@
+* EHCI controller, Orion Marvell variants
+
+Required properties:
+- compatible: must be "marvell,orion-ehci"
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- interrupts: The EHCI interrupt
+
+Example:
+
+ ehci at 50000 {
+ compatible = "marvell,orion-ehci";
+ reg = <0x50000 0x1000>;
+ interrupts = <19>;
+ };
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 8e7eca6..dda0dbf 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -14,6 +14,9 @@
#include <linux/mbus.h>
#include <linux/clk.h>
#include <linux/platform_data/usb-ehci-orion.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
#define rdl(off) __raw_readl(hcd->regs + (off))
#define wrl(off, val) __raw_writel((val), hcd->regs + (off))
@@ -181,6 +184,8 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
}
}
+static u64 ehci_orion_dma_mask = DMA_BIT_MASK(32);
+
static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
{
struct orion_ehci_data *pd = pdev->dev.platform_data;
@@ -191,13 +196,17 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
struct clk *clk;
void __iomem *regs;
int irq, err;
+ enum orion_ehci_phy_ver phy_version;
if (usb_disabled())
return -ENODEV;
pr_debug("Initializing Orion-SoC USB Host Controller\n");
- irq = platform_get_irq(pdev, 0);
+ if (pdev->dev.of_node)
+ irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ else
+ irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(&pdev->dev,
"Found HC with no IRQ. Check %s setup!\n",
@@ -215,6 +224,14 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
goto err1;
}
+ /*
+ * Right now device-tree probed devices don't get dma_mask
+ * set. Since shared usb code relies on it, set it here for
+ * now. Once we have dma capability bindings this can go away.
+ */
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &ehci_orion_dma_mask;
+
if (!request_mem_region(res->start, resource_size(res),
ehci_orion_hc_driver.description)) {
dev_dbg(&pdev->dev, "controller already in use\n");
@@ -262,7 +279,12 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
/*
* setup Orion USB controller.
*/
- switch (pd->phy_version) {
+ if (pdev->dev.of_node)
+ phy_version = EHCI_PHY_NA;
+ else
+ phy_version = pd->phy_version;
+
+ switch (phy_version) {
case EHCI_PHY_NA: /* dont change USB phy settings */
break;
case EHCI_PHY_ORION:
@@ -317,9 +339,19 @@ static int __exit ehci_orion_drv_remove(struct platform_device *pdev)
MODULE_ALIAS("platform:orion-ehci");
+static const struct of_device_id ehci_orion_dt_ids[] __devinitdata = {
+ { .compatible = "marvell,orion-ehci", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ehci_orion_dt_ids);
+
static struct platform_driver ehci_orion_driver = {
.probe = ehci_orion_drv_probe,
.remove = __exit_p(ehci_orion_drv_remove),
.shutdown = usb_hcd_platform_shutdown,
- .driver.name = "orion-ehci",
+ .driver = {
+ .name = "orion-ehci",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ehci_orion_dt_ids),
+ },
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 0/2] DT EHCI support for Kirkwood.
From: Andrew Lunn @ 2012-10-20 11:09 UTC (permalink / raw)
To: linux-arm-kernel
These two patches add DT support to ehci-orion and convert all
existing Kirkwood DT boards to using DT to instantiate the USB host.
v1->v2: Remove the phy property from DT. The previous implementation
was not compatible with the new ideas of a USB phy node. Only orion5x
needs it anyway, and currently converting orion5x to DT is low
priority. Adding a phy node later will also not affect backwards
compatibility.
Andrew Lunn (2):
ARM: Kirkwood: ehci-orion: Add device tree binding
ARM: Kirkwood: Convert all DT boards to EHCI via DT.
.../devicetree/bindings/usb/ehci-orion.txt | 15 ++++++++
arch/arm/boot/dts/kirkwood.dtsi | 7 ++++
arch/arm/mach-kirkwood/board-dnskw.c | 1 -
arch/arm/mach-kirkwood/board-dockstar.c | 1 -
arch/arm/mach-kirkwood/board-dreamplug.c | 1 -
arch/arm/mach-kirkwood/board-dt.c | 1 +
arch/arm/mach-kirkwood/board-goflexnet.c | 1 -
arch/arm/mach-kirkwood/board-ib62x0.c | 1 -
arch/arm/mach-kirkwood/board-iconnect.c | 1 -
arch/arm/mach-kirkwood/board-iomega_ix2_200.c | 2 --
arch/arm/mach-kirkwood/board-km_kirkwood.c | 1 -
arch/arm/mach-kirkwood/board-lsxl.c | 1 -
arch/arm/mach-kirkwood/board-ts219.c | 1 -
drivers/usb/host/ehci-orion.c | 38 ++++++++++++++++++--
14 files changed, 58 insertions(+), 14 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/ehci-orion.txt
--
1.7.10.4
^ permalink raw reply
* [PATCH 3/3] ARM: Kirkwood: checkpatch cleanups
From: Andrew Lunn @ 2012-10-20 10:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350729736-14539-1-git-send-email-andrew@lunn.ch>
Mostly printk to pr_{err|info} changes and a few strings split over
multiple lines are combined.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
arch/arm/mach-kirkwood/board-dt.c | 2 +-
arch/arm/mach-kirkwood/common.c | 9 ++++-----
arch/arm/mach-kirkwood/common.h | 3 ++-
arch/arm/mach-kirkwood/cpuidle.c | 3 +--
arch/arm/mach-kirkwood/dockstar-setup.c | 2 +-
arch/arm/mach-kirkwood/mpp.c | 4 ++--
arch/arm/mach-kirkwood/netspace_v2-setup.c | 4 ++--
arch/arm/mach-kirkwood/openrd-setup.c | 14 +++++---------
arch/arm/mach-kirkwood/pcie.c | 13 +++++++------
arch/arm/mach-kirkwood/sheevaplug-setup.c | 2 +-
arch/arm/mach-kirkwood/ts41x-setup.c | 3 +--
11 files changed, 27 insertions(+), 32 deletions(-)
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 2d840da..d699bd0 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -100,7 +100,7 @@ static void __init kirkwood_dt_init(void)
kirkwood_auxdata_lookup, NULL);
}
-static const char *kirkwood_dt_board_compat[] = {
+static const char * const kirkwood_dt_board_compat[] = {
"globalscale,dreamplug",
"dlink,dns-320",
"dlink,dns-325",
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index f694ba8..a46f90f 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -18,10 +18,10 @@
#include <linux/clk-provider.h>
#include <linux/spinlock.h>
#include <linux/mv643xx_i2c.h>
+#include <linux/timex.h>
+#include <linux/kexec.h>
#include <net/dsa.h>
#include <asm/page.h>
-#include <asm/timex.h>
-#include <asm/kexec.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <mach/kirkwood.h>
@@ -644,8 +644,7 @@ void __init kirkwood_l2_init(void)
void __init kirkwood_init(void)
{
- printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
- kirkwood_id(), kirkwood_tclk);
+ pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk);
/*
* Disable propagation of mbus errors to the CPU local bus,
@@ -671,7 +670,7 @@ void __init kirkwood_init(void)
kirkwood_xor1_init();
kirkwood_crypto_init();
-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_KEXEC
kexec_reinit = kirkwood_enable_pcie;
#endif
}
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index bcffd7c..6088e92 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -47,7 +47,8 @@ void kirkwood_i2c_init(void);
void kirkwood_uart0_init(void);
void kirkwood_uart1_init(void);
void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay);
-void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *));
+void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
+ int (*dev_ready)(struct mtd_info *));
void kirkwood_audio_init(void);
void kirkwood_restart(char, const char *);
void kirkwood_clk_init(void);
diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c
index 0f17109..4174602 100644
--- a/arch/arm/mach-kirkwood/cpuidle.c
+++ b/arch/arm/mach-kirkwood/cpuidle.c
@@ -20,7 +20,6 @@
#include <linux/io.h>
#include <linux/export.h>
#include <asm/proc-fns.h>
-#include <asm/cpuidle.h>
#include <mach/kirkwood.h>
#define KIRKWOOD_MAX_STATES 2
@@ -64,7 +63,7 @@ static int kirkwood_init_cpuidle(void)
cpuidle_register_driver(&kirkwood_idle_driver);
if (cpuidle_register_device(device)) {
- printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n");
+ pr_err("kirkwood_init_cpuidle: Failed registering\n");
return -EIO;
}
return 0;
diff --git a/arch/arm/mach-kirkwood/dockstar-setup.c b/arch/arm/mach-kirkwood/dockstar-setup.c
index 23dcb19..791a98f 100644
--- a/arch/arm/mach-kirkwood/dockstar-setup.c
+++ b/arch/arm/mach-kirkwood/dockstar-setup.c
@@ -93,7 +93,7 @@ static void __init dockstar_init(void)
if (gpio_request(29, "USB Power Enable") != 0 ||
gpio_direction_output(29, 1) != 0)
- printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
+ pr_err("can't set up GPIO 29 (USB Power Enable)\n");
kirkwood_ehci_init();
kirkwood_ge00_init(&dockstar_ge00_data);
diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c
index 0c6ad63..827cde4 100644
--- a/arch/arm/mach-kirkwood/mpp.c
+++ b/arch/arm/mach-kirkwood/mpp.c
@@ -30,8 +30,8 @@ static unsigned int __init kirkwood_variant(void)
if (dev == MV88F6180_DEV_ID)
return MPP_F6180_MASK;
- printk(KERN_ERR "MPP setup: unknown kirkwood variant "
- "(dev %#x rev %#x)\n", dev, rev);
+ pr_err("MPP setup: unknown kirkwood variant (dev %#x rev %#x)\n",
+ dev, rev);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c
index 88b0788..728e86d 100644
--- a/arch/arm/mach-kirkwood/netspace_v2-setup.c
+++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c
@@ -79,7 +79,7 @@ static struct platform_device netspace_v2_gpio_buttons = {
.name = "gpio-keys",
.id = -1,
.dev = {
- .platform_data = &netspace_v2_button_data,
+ .platform_data = &netspace_v2_button_data,
},
};
@@ -211,7 +211,7 @@ static unsigned int netspace_v2_mpp_config[] __initdata = {
MPP29_GPIO, /* Blue led (slow register) */
MPP30_GPIO, /* Blue led (command register) */
MPP31_GPIO, /* Board power off */
- MPP32_GPIO, /* Power button (0 = Released, 1 = Pushed) */
+ MPP32_GPIO, /* Power button (0 = Released, 1 = Pushed) */
MPP33_GPO, /* Fan speed (bit 2) */
0
};
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index 134ef50..7e81e9b 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -121,14 +121,12 @@ static int __init uart1_mpp_config(void)
kirkwood_mpp_conf(openrd_uart1_mpp_config);
if (gpio_request(34, "SD_UART1_SEL")) {
- printk(KERN_ERR "GPIO request failed for SD/UART1 selection"
- ", gpio: 34\n");
+ pr_err("GPIO request 34 failed for SD/UART1 selection\n");
return -EIO;
}
if (gpio_request(28, "RS232_RS485_SEL")) {
- printk(KERN_ERR "GPIO request failed for RS232/RS485 selection"
- ", gpio# 28\n");
+ pr_err("GPIO request 28 failed for RS232/RS485 selection\n");
gpio_free(34);
return -EIO;
}
@@ -185,15 +183,13 @@ static void __init openrd_init(void)
if (uart1 <= 0) {
if (uart1 < 0)
- printk(KERN_ERR "Invalid kernel parameter to select "
- "UART1. Defaulting to SD. ERROR CODE: %d\n",
- uart1);
+ pr_err("Invalid kernel parameter to select UART1. Defaulting to SD. ERROR CODE: %d\n",
+ uart1);
/* Select SD
* Pin # 34: 0 => UART1, 1 => SD */
if (gpio_request(34, "SD_UART1_SEL")) {
- printk(KERN_ERR "GPIO request failed for SD/UART1 "
- "selection, gpio: 34\n");
+ pr_err("GPIO request 34 failed for SD/UART1 selection\n");
} else {
gpio_direction_output(34, 1);
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index ec54491..2585811 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -26,7 +26,7 @@ static void kirkwood_enable_pcie_clk(const char *port)
clk = clk_get_sys("pcie", port);
if (IS_ERR(clk)) {
- printk(KERN_ERR "PCIE clock %s missing\n", port);
+ pr_err("PCIE clock %s missing\n", port);
return;
}
clk_prepare_enable(clk);
@@ -168,7 +168,7 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
return 0;
index = pcie_port_map[nr];
- printk(KERN_INFO "PCI: bus%d uses PCIe port %d\n", sys->busnr, index);
+ pr_info("PCI: bus%d uses PCIe port %d\n", sys->busnr, index);
pp = kzalloc(sizeof(*pp), GFP_KERNEL);
if (!pp)
@@ -186,7 +186,8 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
case 1:
kirkwood_enable_pcie_clk("1");
pcie1_ioresources_init(pp);
- pci_ioremap_io(SZ_64K * sys->busnr, KIRKWOOD_PCIE1_IO_PHYS_BASE);
+ pci_ioremap_io(SZ_64K * sys->busnr,
+ KIRKWOOD_PCIE1_IO_PHYS_BASE);
break;
default:
panic("PCIe setup: invalid controller %d", index);
@@ -257,13 +258,13 @@ static struct hw_pci kirkwood_pci __initdata = {
static void __init add_pcie_port(int index, void __iomem *base)
{
- printk(KERN_INFO "Kirkwood PCIe port %d: ", index);
+ pr_info("Kirkwood PCIe port %d: ", index);
if (orion_pcie_link_up(base)) {
- printk(KERN_INFO "link up\n");
+ pr_info("link up\n");
pcie_port_map[num_pcie_ports++] = index;
} else
- printk(KERN_INFO "link down, ignoring\n");
+ pr_info("link down, ignoring\n");
}
void __init kirkwood_pcie_init(unsigned int portmask)
diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c
index 28d0aba..8a17594 100644
--- a/arch/arm/mach-kirkwood/sheevaplug-setup.c
+++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c
@@ -117,7 +117,7 @@ static void __init sheevaplug_init(void)
if (gpio_request(29, "USB Power Enable") != 0 ||
gpio_direction_output(29, 1) != 0)
- printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
+ pr_err("can't set up GPIO 29 (USB Power Enable)\n");
kirkwood_ehci_init();
kirkwood_ge00_init(&sheevaplug_ge00_data);
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
index 367a940..e4c6127 100644
--- a/arch/arm/mach-kirkwood/ts41x-setup.c
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -170,8 +170,7 @@ static int __init ts41x_pci_init(void)
else
kirkwood_pcie_init(KW_PCIE0);
}
-
- return 0;
+ return 0;
}
subsys_initcall(ts41x_pci_init);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/3] ARM: Kirkwood: Fix sparse warnings.
From: Andrew Lunn @ 2012-10-20 10:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350729736-14539-1-git-send-email-andrew@lunn.ch>
Mostly missing statics, but also missing include files
and void parameters.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
arch/arm/mach-kirkwood/board-dt.c | 2 +-
arch/arm/mach-kirkwood/common.c | 2 +-
arch/arm/mach-kirkwood/irq.c | 1 +
arch/arm/mach-kirkwood/lacie_v2-common.c | 1 +
arch/arm/mach-kirkwood/t5325-setup.c | 6 +++---
arch/arm/mach-kirkwood/tsx1x-common.c | 7 ++++---
6 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 70c5a28..2d840da 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -26,7 +26,7 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = {
{ }
};
-struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
+static struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
NULL),
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 3991077..f694ba8 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -425,7 +425,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
/*****************************************************************************
* SPI
****************************************************************************/
-void __init kirkwood_spi_init()
+void __init kirkwood_spi_init(void)
{
orion_spi_init(SPI_PHYS_BASE);
}
diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c
index 8847035..2a97a2e 100644
--- a/arch/arm/mach-kirkwood/irq.c
+++ b/arch/arm/mach-kirkwood/irq.c
@@ -14,6 +14,7 @@
#include <mach/bridge-regs.h>
#include <plat/orion-gpio.h>
#include <plat/irq.h>
+#include "common.h"
static int __initdata gpio0_irqs[4] = {
IRQ_KIRKWOOD_GPIO_LOW_0_7,
diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c
index 285edab..4894959 100644
--- a/arch/arm/mach-kirkwood/lacie_v2-common.c
+++ b/arch/arm/mach-kirkwood/lacie_v2-common.c
@@ -19,6 +19,7 @@
#include <mach/irqs.h>
#include <plat/time.h>
#include "common.h"
+#include "lacie_v2-common.h"
/*****************************************************************************
* 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c
index bad738e..f2daf71 100644
--- a/arch/arm/mach-kirkwood/t5325-setup.c
+++ b/arch/arm/mach-kirkwood/t5325-setup.c
@@ -29,7 +29,7 @@
#include "common.h"
#include "mpp.h"
-struct mtd_partition hp_t5325_partitions[] = {
+static struct mtd_partition hp_t5325_partitions[] = {
{
.name = "u-boot env",
.size = SZ_64K,
@@ -59,14 +59,14 @@ struct mtd_partition hp_t5325_partitions[] = {
},
};
-const struct flash_platform_data hp_t5325_flash = {
+static const struct flash_platform_data hp_t5325_flash = {
.type = "mx25l8005",
.name = "spi_flash",
.parts = hp_t5325_partitions,
.nr_parts = ARRAY_SIZE(hp_t5325_partitions),
};
-struct spi_board_info __initdata hp_t5325_spi_slave_info[] = {
+static struct spi_board_info __initdata hp_t5325_spi_slave_info[] = {
{
.modalias = "m25p80",
.platform_data = &hp_t5325_flash,
diff --git a/arch/arm/mach-kirkwood/tsx1x-common.c b/arch/arm/mach-kirkwood/tsx1x-common.c
index 8943ede..cec87ce 100644
--- a/arch/arm/mach-kirkwood/tsx1x-common.c
+++ b/arch/arm/mach-kirkwood/tsx1x-common.c
@@ -7,6 +7,7 @@
#include <linux/serial_reg.h>
#include <mach/kirkwood.h>
#include "common.h"
+#include "tsx1x-common.h"
/*
* QNAP TS-x1x Boards flash
@@ -29,7 +30,7 @@
*
***************************************************************************/
-struct mtd_partition qnap_tsx1x_partitions[] = {
+static struct mtd_partition qnap_tsx1x_partitions[] = {
{
.name = "U-Boot",
.size = 0x00080000,
@@ -58,14 +59,14 @@ struct mtd_partition qnap_tsx1x_partitions[] = {
},
};
-const struct flash_platform_data qnap_tsx1x_flash = {
+static const struct flash_platform_data qnap_tsx1x_flash = {
.type = "m25p128",
.name = "spi_flash",
.parts = qnap_tsx1x_partitions,
.nr_parts = ARRAY_SIZE(qnap_tsx1x_partitions),
};
-struct spi_board_info __initdata qnap_tsx1x_spi_slave_info[] = {
+static struct spi_board_info __initdata qnap_tsx1x_spi_slave_info[] = {
{
.modalias = "m25p80",
.platform_data = &qnap_tsx1x_flash,
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/3] ARM: Kirkwood: Remove unused includes
From: Andrew Lunn @ 2012-10-20 10:42 UTC (permalink / raw)
To: linux-arm-kernel
With the gradual conversion of C code to DT, there are a number of
include files which are no longer needed. Remove them.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
arch/arm/mach-kirkwood/board-dockstar.c | 13 -------------
arch/arm/mach-kirkwood/board-dreamplug.c | 15 ---------------
arch/arm/mach-kirkwood/board-goflexnet.c | 13 -------------
arch/arm/mach-kirkwood/board-ib62x0.c | 6 ------
arch/arm/mach-kirkwood/board-iconnect.c | 8 --------
arch/arm/mach-kirkwood/board-iomega_ix2_200.c | 2 --
arch/arm/mach-kirkwood/board-lsxl.c | 8 --------
arch/arm/mach-kirkwood/board-ts219.c | 3 ---
8 files changed, 68 deletions(-)
diff --git a/arch/arm/mach-kirkwood/board-dockstar.c b/arch/arm/mach-kirkwood/board-dockstar.c
index f2fbb02..6912882 100644
--- a/arch/arm/mach-kirkwood/board-dockstar.c
+++ b/arch/arm/mach-kirkwood/board-dockstar.c
@@ -16,21 +16,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
#include <linux/gpio.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/kirkwood.h>
-#include <mach/bridge-regs.h>
-#include <linux/platform_data/mmc-mvsdio.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c
index 20af53a..8a8ebe0 100644
--- a/arch/arm/mach-kirkwood/board-dreamplug.c
+++ b/arch/arm/mach-kirkwood/board-dreamplug.c
@@ -13,23 +13,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
#include <linux/gpio.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/kirkwood.h>
-#include <mach/bridge-regs.h>
#include <linux/platform_data/mmc-mvsdio.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-goflexnet.c b/arch/arm/mach-kirkwood/board-goflexnet.c
index 001ca8c..5dcd0d6 100644
--- a/arch/arm/mach-kirkwood/board-goflexnet.c
+++ b/arch/arm/mach-kirkwood/board-goflexnet.c
@@ -18,21 +18,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
#include <linux/gpio.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/kirkwood.h>
-#include <mach/bridge-regs.h>
-#include <linux/platform_data/mmc-mvsdio.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-ib62x0.c b/arch/arm/mach-kirkwood/board-ib62x0.c
index cfc47f8..6d3a564 100644
--- a/arch/arm/mach-kirkwood/board-ib62x0.c
+++ b/arch/arm/mach-kirkwood/board-ib62x0.c
@@ -13,15 +13,9 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/partitions.h>
-#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/input.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c
index d084b1e..24f5aa7 100644
--- a/arch/arm/mach-kirkwood/board-iconnect.c
+++ b/arch/arm/mach-kirkwood/board-iconnect.c
@@ -10,16 +10,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/gpio.h>
-#include <asm/mach/arch.h>
-#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
index 158fb97..e4ed62c 100644
--- a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
+++ b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
@@ -10,10 +10,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
-#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-lsxl.c b/arch/arm/mach-kirkwood/board-lsxl.c
index 83d8975..64e5cc6 100644
--- a/arch/arm/mach-kirkwood/board-lsxl.c
+++ b/arch/arm/mach-kirkwood/board-lsxl.c
@@ -14,17 +14,9 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/partitions.h>
-#include <linux/ata_platform.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/gpio-fan.h>
-#include <linux/input.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-kirkwood/board-ts219.c b/arch/arm/mach-kirkwood/board-ts219.c
index 1750e68..f3bfeda 100644
--- a/arch/arm/mach-kirkwood/board-ts219.c
+++ b/arch/arm/mach-kirkwood/board-ts219.c
@@ -19,9 +19,6 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mv643xx_eth.h>
-#include <linux/ata_platform.h>
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
--
1.7.10.4
^ permalink raw reply related
* [PATCH] [media] s5p-tv: remove unused including <linux/version.h>
From: Sylwester Nawrocki @ 2012-10-20 10:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPgLHd-0c4D0cSVQBZA=bbaDvcu4yHBj_2DPPGrQMKQZxxGqBg@mail.gmail.com>
Hi,
On 10/08/2012 02:32 PM, Wei Yongjun wrote:
> From: Wei Yongjun<yongjun_wei@trendmicro.com.cn>
>
> Remove including<linux/version.h> that don't need it.
>
> dpatch engine is used to auto generate this patch.
> (https://github.com/weiyj/dpatch)
Sorry, I have already applied similar patch:
http://patchwork.linuxtv.org/patch/15057
Thanks,
Sylwester
> Signed-off-by: Wei Yongjun<yongjun_wei@trendmicro.com.cn>
> ---
> drivers/media/platform/s5p-tv/mixer_video.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c
> index 0c1cd89..9b52f3a 100644
> --- a/drivers/media/platform/s5p-tv/mixer_video.c
> +++ b/drivers/media/platform/s5p-tv/mixer_video.c
> @@ -19,7 +19,6 @@
> #include<linux/videodev2.h>
> #include<linux/mm.h>
> #include<linux/module.h>
> -#include<linux/version.h>
> #include<linux/timer.h>
> #include<media/videobuf2-dma-contig.h>
^ permalink raw reply
* [PATCH 5/5 v6] gpio: Add block gpio to several gpio drivers
From: Roland Stigge @ 2012-10-20 10:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350728508-22508-1-git-send-email-stigge@antcom.de>
This patch adds block GPIO support to several gpio drivers.
Signed-off-by: Roland Stigge <stigge@antcom.de>
---
drivers/gpio/gpio-em.c | 23 ++++++++++++
drivers/gpio/gpio-generic.c | 56 ++++++++++++++++++++++++++++++
drivers/gpio/gpio-lpc32xx.c | 82 ++++++++++++++++++++++++++++++++++++++++++++
drivers/gpio/gpio-max730x.c | 61 ++++++++++++++++++++++++++++++++
drivers/gpio/gpio-max732x.c | 59 +++++++++++++++++++++++++++++++
drivers/gpio/gpio-pca953x.c | 64 ++++++++++++++++++++++++++++++++++
drivers/gpio/gpio-pcf857x.c | 24 ++++++++++++
drivers/gpio/gpio-pch.c | 27 ++++++++++++++
drivers/gpio/gpio-pl061.c | 17 +++++++++
drivers/gpio/gpio-twl6040.c | 32 +++++++++++++++++
drivers/gpio/gpio-ucb1400.c | 23 ++++++++++++
drivers/gpio/gpio-vt8500.c | 24 ++++++++++++
drivers/gpio/gpio-xilinx.c | 44 +++++++++++++++++++++++
13 files changed, 536 insertions(+)
--- linux-2.6.orig/drivers/gpio/gpio-em.c
+++ linux-2.6/drivers/gpio/gpio-em.c
@@ -203,6 +203,27 @@ static void em_gio_set(struct gpio_chip
__em_gio_set(chip, GIO_OH, offset - 16, value);
}
+static unsigned long em_gio_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+ return (int)(em_gio_read(gpio_to_priv(chip), GIO_I) & mask);
+}
+
+static void em_gio_set_block(struct gpio_chip *chip, unsigned long mask,
+ unsigned long values)
+{
+ unsigned long mask_ol = mask & 0xFFFF;
+ unsigned long mask_oh = mask >> 16;
+
+ unsigned long values_ol = values & mask_ol;
+ unsigned long values_oh = (values >> 16) & mask_oh;
+
+ em_gio_write(gpio_to_priv(chip), GIO_OL,
+ mask_ol << 16 | values_ol);
+ em_gio_write(gpio_to_priv(chip), GIO_OH,
+ mask_oh << 16 | values_oh);
+}
+
static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset,
int value)
{
@@ -317,8 +338,10 @@ static int __devinit em_gio_probe(struct
gpio_chip = &p->gpio_chip;
gpio_chip->direction_input = em_gio_direction_input;
gpio_chip->get = em_gio_get;
+ gpio_chip->get_block = em_gio_get_block;
gpio_chip->direction_output = em_gio_direction_output;
gpio_chip->set = em_gio_set;
+ gpio_chip->set_block = em_gio_set_block;
gpio_chip->to_irq = em_gio_to_irq;
gpio_chip->label = name;
gpio_chip->owner = THIS_MODULE;
--- linux-2.6.orig/drivers/gpio/gpio-generic.c
+++ linux-2.6/drivers/gpio/gpio-generic.c
@@ -122,6 +122,13 @@ static int bgpio_get(struct gpio_chip *g
return bgc->read_reg(bgc->reg_dat) & bgc->pin2mask(bgc, gpio);
}
+static unsigned long bgpio_get_block(struct gpio_chip *gc, unsigned long mask)
+{
+ struct bgpio_chip *bgc = to_bgpio_chip(gc);
+
+ return bgc->read_reg(bgc->reg_dat) & mask;
+}
+
static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
{
struct bgpio_chip *bgc = to_bgpio_chip(gc);
@@ -170,6 +177,51 @@ static void bgpio_set_set(struct gpio_ch
spin_unlock_irqrestore(&bgc->lock, flags);
}
+static void bgpio_set_block(struct gpio_chip *gc, unsigned long mask,
+ unsigned long values)
+{
+ struct bgpio_chip *bgc = to_bgpio_chip(gc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&bgc->lock, flags);
+
+ bgc->data &= ~mask;
+ bgc->data |= values & mask;
+
+ bgc->write_reg(bgc->reg_dat, bgc->data);
+
+ spin_unlock_irqrestore(&bgc->lock, flags);
+}
+
+static void bgpio_set_with_clear_block(struct gpio_chip *gc, unsigned long mask,
+ unsigned long values)
+{
+ struct bgpio_chip *bgc = to_bgpio_chip(gc);
+ unsigned long set_bits = values & mask;
+ unsigned long clr_bits = ~values & mask;
+
+ if (set_bits)
+ bgc->write_reg(bgc->reg_set, set_bits);
+ if (clr_bits)
+ bgc->write_reg(bgc->reg_set, clr_bits);
+}
+
+static void bgpio_set_set_block(struct gpio_chip *gc, unsigned long mask,
+ unsigned long values)
+{
+ struct bgpio_chip *bgc = to_bgpio_chip(gc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&bgc->lock, flags);
+
+ bgc->data &= ~mask;
+ bgc->data |= values & mask;
+
+ bgc->write_reg(bgc->reg_set, bgc->data);
+
+ spin_unlock_irqrestore(&bgc->lock, flags);
+}
+
static int bgpio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio)
{
return 0;
@@ -317,14 +369,18 @@ static int bgpio_setup_io(struct bgpio_c
bgc->reg_set = set;
bgc->reg_clr = clr;
bgc->gc.set = bgpio_set_with_clear;
+ bgc->gc.set_block = bgpio_set_with_clear_block;
} else if (set && !clr) {
bgc->reg_set = set;
bgc->gc.set = bgpio_set_set;
+ bgc->gc.set_block = bgpio_set_set_block;
} else {
bgc->gc.set = bgpio_set;
+ bgc->gc.set_block = bgpio_set_block;
}
bgc->gc.get = bgpio_get;
+ bgc->gc.get_block = bgpio_get_block;
return 0;
}
--- linux-2.6.orig/drivers/gpio/gpio-lpc32xx.c
+++ linux-2.6/drivers/gpio/gpio-lpc32xx.c
@@ -297,6 +297,22 @@ static int lpc32xx_gpio_get_value_p3(str
return __get_gpio_state_p3(group, pin);
}
+static unsigned long lpc32xx_gpio_get_block_p3(struct gpio_chip *chip,
+ unsigned long mask)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+ u32 bits = __raw_readl(group->gpio_grp->inp_state);
+
+ /* In P3_INP_STATE, the 6 GPIOs are scattered over the register,
+ * rearranging to bits 0-5
+ */
+ bits >>= 10;
+ bits &= 0x401F;
+ bits |= (bits & 0x4000) >> 9;
+
+ return bits & mask & 0x3F;
+}
+
static int lpc32xx_gpi_get_value(struct gpio_chip *chip, unsigned pin)
{
struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
@@ -304,6 +320,15 @@ static int lpc32xx_gpi_get_value(struct
return __get_gpi_state_p3(group, pin);
}
+static unsigned long lpc32xx_gpi_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+ u32 bits = __raw_readl(group->gpio_grp->inp_state);
+
+ return bits & mask;
+}
+
static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
int value)
{
@@ -351,6 +376,27 @@ static void lpc32xx_gpio_set_value_p3(st
__set_gpio_level_p3(group, pin, value);
}
+static void lpc32xx_gpio_set_block_p3(struct gpio_chip *chip,
+ unsigned long mask,
+ unsigned long values)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+ u32 set_bits = values & mask;
+ u32 clr_bits = ~values & mask;
+
+ /* States of GPIO 0-5 start at bit 25 */
+ set_bits <<= 25;
+ clr_bits <<= 25;
+
+ /* Note: On LPC32xx, GPOs can only be set at once or cleared at once,
+ * but not set and cleared@once
+ */
+ if (set_bits)
+ __raw_writel(set_bits, group->gpio_grp->outp_set);
+ if (clr_bits)
+ __raw_writel(clr_bits, group->gpio_grp->outp_clr);
+}
+
static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin,
int value)
{
@@ -366,6 +412,31 @@ static int lpc32xx_gpo_get_value(struct
return __get_gpo_state_p3(group, pin);
}
+static void lpc32xx_gpo_set_block(struct gpio_chip *chip, unsigned long mask,
+ unsigned long values)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+ u32 set_bits = values & mask;
+ u32 clr_bits = ~values & mask;
+
+ /* Note: On LPC32xx, GPOs can only be set at once or cleared at once,
+ * but not set and cleared at once
+ */
+ if (set_bits)
+ __raw_writel(set_bits, group->gpio_grp->outp_set);
+ if (clr_bits)
+ __raw_writel(clr_bits, group->gpio_grp->outp_clr);
+}
+
+static unsigned long lpc32xx_gpo_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+ u32 bits = __raw_readl(group->gpio_grp->outp_state);
+
+ return bits & mask;
+}
+
static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin)
{
if (pin < chip->ngpio)
@@ -440,8 +511,10 @@ static struct lpc32xx_gpio_chip lpc32xx_
.label = "gpio_p0",
.direction_input = lpc32xx_gpio_dir_input_p012,
.get = lpc32xx_gpio_get_value_p012,
+ .get_block = lpc32xx_gpi_get_block,
.direction_output = lpc32xx_gpio_dir_output_p012,
.set = lpc32xx_gpio_set_value_p012,
+ .set_block = lpc32xx_gpo_set_block,
.request = lpc32xx_gpio_request,
.to_irq = lpc32xx_gpio_to_irq_p01,
.base = LPC32XX_GPIO_P0_GRP,
@@ -456,8 +529,10 @@ static struct lpc32xx_gpio_chip lpc32xx_
.label = "gpio_p1",
.direction_input = lpc32xx_gpio_dir_input_p012,
.get = lpc32xx_gpio_get_value_p012,
+ .get_block = lpc32xx_gpi_get_block,
.direction_output = lpc32xx_gpio_dir_output_p012,
.set = lpc32xx_gpio_set_value_p012,
+ .set_block = lpc32xx_gpo_set_block,
.request = lpc32xx_gpio_request,
.to_irq = lpc32xx_gpio_to_irq_p01,
.base = LPC32XX_GPIO_P1_GRP,
@@ -472,8 +547,10 @@ static struct lpc32xx_gpio_chip lpc32xx_
.label = "gpio_p2",
.direction_input = lpc32xx_gpio_dir_input_p012,
.get = lpc32xx_gpio_get_value_p012,
+ .get_block = lpc32xx_gpi_get_block,
.direction_output = lpc32xx_gpio_dir_output_p012,
.set = lpc32xx_gpio_set_value_p012,
+ .set_block = lpc32xx_gpo_set_block,
.request = lpc32xx_gpio_request,
.base = LPC32XX_GPIO_P2_GRP,
.ngpio = LPC32XX_GPIO_P2_MAX,
@@ -487,8 +564,10 @@ static struct lpc32xx_gpio_chip lpc32xx_
.label = "gpio_p3",
.direction_input = lpc32xx_gpio_dir_input_p3,
.get = lpc32xx_gpio_get_value_p3,
+ .get_block = lpc32xx_gpio_get_block_p3,
.direction_output = lpc32xx_gpio_dir_output_p3,
.set = lpc32xx_gpio_set_value_p3,
+ .set_block = lpc32xx_gpio_set_block_p3,
.request = lpc32xx_gpio_request,
.to_irq = lpc32xx_gpio_to_irq_gpio_p3,
.base = LPC32XX_GPIO_P3_GRP,
@@ -503,6 +582,7 @@ static struct lpc32xx_gpio_chip lpc32xx_
.label = "gpi_p3",
.direction_input = lpc32xx_gpio_dir_in_always,
.get = lpc32xx_gpi_get_value,
+ .get_block = lpc32xx_gpi_get_block,
.request = lpc32xx_gpio_request,
.to_irq = lpc32xx_gpio_to_irq_gpi_p3,
.base = LPC32XX_GPI_P3_GRP,
@@ -517,7 +597,9 @@ static struct lpc32xx_gpio_chip lpc32xx_
.label = "gpo_p3",
.direction_output = lpc32xx_gpio_dir_out_always,
.set = lpc32xx_gpo_set_value,
+ .set_block = lpc32xx_gpo_set_block,
.get = lpc32xx_gpo_get_value,
+ .get_block = lpc32xx_gpo_get_block,
.request = lpc32xx_gpio_request,
.base = LPC32XX_GPO_P3_GRP,
.ngpio = LPC32XX_GPO_P3_MAX,
--- linux-2.6.orig/drivers/gpio/gpio-max730x.c
+++ linux-2.6/drivers/gpio/gpio-max730x.c
@@ -146,6 +146,44 @@ static int max7301_get(struct gpio_chip
return level;
}
+static unsigned long max7301_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+ int i, j;
+ unsigned long result = 0;
+
+ for (i = 0; i < 4; i++) {
+ if ((mask >> (i * 8)) & 0xFF) { /* i/o only if necessary */
+ u8 in_level = ts->read(ts->dev, 0x44 + i * 8);
+ u8 in_mask = 0;
+ u8 out_level = (ts->out_level >> (i * 8 + 4)) & 0xFF;
+ u8 out_mask = 0;
+
+ for (j = 0; j < 8; j++) {
+ int offset = 4 + i * 8 + j;
+ int config = (ts->port_config[offset >> 2] >>
+ ((offset & 3) << 1)) &
+ PIN_CONFIG_MASK;
+
+ switch (config) {
+ case PIN_CONFIG_OUT:
+ out_mask |= BIT(j);
+ break;
+ case PIN_CONFIG_IN_WO_PULLUP:
+ case PIN_CONFIG_IN_PULLUP:
+ in_mask |= BIT(j);
+ }
+ }
+
+ result |= ((unsigned long)(in_level & in_mask) |
+ (out_level & out_mask)) << (i * 8);
+ }
+ }
+
+ return result & mask;
+}
+
static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct max7301 *ts = container_of(chip, struct max7301, chip);
@@ -160,6 +198,27 @@ static void max7301_set(struct gpio_chip
mutex_unlock(&ts->lock);
}
+static void max7301_set_block(struct gpio_chip *chip, unsigned long mask,
+ unsigned long values)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+ unsigned long changes;
+ int i;
+
+ mutex_lock(&ts->lock);
+
+ changes = (ts->out_level ^ (values << 4)) & (mask << 4);
+ ts->out_level ^= changes;
+
+ for (i = 0; i < 4; i++) {
+ if ((changes >> (i * 8 + 4)) & 0xFF) /* i/o only on change */
+ ts->write(ts->dev, 0x44 + i * 8,
+ (ts->out_level >> (i * 8 + 4)) & 0xFF);
+ }
+
+ mutex_unlock(&ts->lock);
+}
+
int __devinit __max730x_probe(struct max7301 *ts)
{
struct device *dev = ts->dev;
@@ -183,8 +242,10 @@ int __devinit __max730x_probe(struct max
ts->chip.direction_input = max7301_direction_input;
ts->chip.get = max7301_get;
+ ts->chip.get_block = max7301_get_block;
ts->chip.direction_output = max7301_direction_output;
ts->chip.set = max7301_set;
+ ts->chip.set_block = max7301_set_block;
ts->chip.base = pdata->base;
ts->chip.ngpio = PIN_NUMBER;
--- linux-2.6.orig/drivers/gpio/gpio-max732x.c
+++ linux-2.6/drivers/gpio/gpio-max732x.c
@@ -219,6 +219,63 @@ out:
mutex_unlock(&chip->lock);
}
+static unsigned long max732x_gpio_get_block(struct gpio_chip *gc,
+ unsigned long mask)
+{
+ struct max732x_chip *chip;
+ uint8_t lo = 0;
+ uint8_t hi = 0;
+ int ret;
+
+ chip = container_of(gc, struct max732x_chip, gpio_chip);
+
+ if (mask & 0xFF) {
+ ret = max732x_readb(chip, is_group_a(chip, 0), &lo);
+ if (ret < 0)
+ return 0;
+ }
+ if (mask & 0xFF00) {
+ ret = max732x_readb(chip, is_group_a(chip, 8), &hi);
+ if (ret < 0)
+ return 0;
+ }
+
+ return (((unsigned long)hi << 8) | lo) & mask;
+}
+
+static void max732x_gpio_set_block(struct gpio_chip *gc, unsigned long mask,
+ unsigned long values)
+{
+ struct max732x_chip *chip;
+ uint8_t reg_out;
+ uint8_t lo_mask = mask & 0xFF;
+ uint8_t hi_mask = (mask >> 8) & 0xFF;
+ int ret;
+
+ chip = container_of(gc, struct max732x_chip, gpio_chip);
+
+ mutex_lock(&chip->lock);
+
+ if (lo_mask) {
+ reg_out = (chip->reg_out[0] & ~lo_mask) | (values & lo_mask);
+ ret = max732x_writeb(chip, is_group_a(chip, 0), reg_out);
+ if (ret < 0)
+ goto out;
+ chip->reg_out[0] = reg_out;
+ }
+ if (hi_mask) {
+ reg_out = (chip->reg_out[1] & ~hi_mask) |
+ ((values >> 8) & hi_mask);
+ ret = max732x_writeb(chip, is_group_a(chip, 8), reg_out);
+ if (ret < 0)
+ goto out;
+ chip->reg_out[1] = reg_out;
+ }
+
+out:
+ mutex_unlock(&chip->lock);
+}
+
static int max732x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
{
struct max732x_chip *chip;
@@ -562,8 +619,10 @@ static int __devinit max732x_setup_gpio(
if (chip->dir_output) {
gc->direction_output = max732x_gpio_direction_output;
gc->set = max732x_gpio_set_value;
+ gc->set_block = max732x_gpio_set_block;
}
gc->get = max732x_gpio_get_value;
+ gc->get_block = max732x_gpio_get_block;
gc->can_sleep = 1;
gc->base = gpio_start;
--- linux-2.6.orig/drivers/gpio/gpio-pca953x.c
+++ linux-2.6/drivers/gpio/gpio-pca953x.c
@@ -300,6 +300,68 @@ exit:
mutex_unlock(&chip->i2c_lock);
}
+static unsigned long pca953x_gpio_get_block(struct gpio_chip *gc,
+ unsigned long mask)
+{
+ struct pca953x_chip *chip;
+ u32 reg_val;
+ int ret, offset = 0;
+
+ chip = container_of(gc, struct pca953x_chip, gpio_chip);
+
+ mutex_lock(&chip->i2c_lock);
+ switch (chip->chip_type) {
+ case PCA953X_TYPE:
+ offset = PCA953X_INPUT;
+ break;
+ case PCA957X_TYPE:
+ offset = PCA957X_IN;
+ break;
+ }
+ ret = pca953x_read_reg(chip, offset, ®_val);
+ mutex_unlock(&chip->i2c_lock);
+ if (ret < 0) {
+ /* NOTE: diagnostic already emitted; that's all we should
+ * do unless gpio_*_value_cansleep() calls become different
+ * from their nonsleeping siblings (and report faults).
+ */
+ return 0;
+ }
+
+ return reg_val & mask;
+}
+
+static void pca953x_gpio_set_block(struct gpio_chip *gc, unsigned long mask,
+ unsigned long values)
+{
+ struct pca953x_chip *chip;
+ u32 reg_val;
+ int ret, offset = 0;
+
+ chip = container_of(gc, struct pca953x_chip, gpio_chip);
+
+ mutex_lock(&chip->i2c_lock);
+
+ reg_val = chip->reg_output & ~mask;
+ reg_val |= values & mask;
+
+ switch (chip->chip_type) {
+ case PCA953X_TYPE:
+ offset = PCA953X_OUTPUT;
+ break;
+ case PCA957X_TYPE:
+ offset = PCA957X_OUT;
+ break;
+ }
+ ret = pca953x_write_reg(chip, offset, reg_val);
+ if (ret)
+ goto exit;
+
+ chip->reg_output = reg_val;
+exit:
+ mutex_unlock(&chip->i2c_lock);
+}
+
static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
{
struct gpio_chip *gc;
@@ -310,6 +372,8 @@ static void pca953x_setup_gpio(struct pc
gc->direction_output = pca953x_gpio_direction_output;
gc->get = pca953x_gpio_get_value;
gc->set = pca953x_gpio_set_value;
+ gc->get_block = pca953x_gpio_get_block;
+ gc->set_block = pca953x_gpio_set_block;
gc->can_sleep = 1;
gc->base = chip->gpio_start;
--- linux-2.6.orig/drivers/gpio/gpio-pcf857x.c
+++ linux-2.6/drivers/gpio/gpio-pcf857x.c
@@ -158,6 +158,28 @@ static void pcf857x_set(struct gpio_chip
pcf857x_output(chip, offset, value);
}
+static unsigned long pcf857x_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+ struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
+ int value;
+
+ value = gpio->read(gpio->client);
+ return (value < 0) ? 0 : (value & mask);
+}
+
+static void pcf857x_set_block(struct gpio_chip *chip, unsigned long mask,
+ unsigned long values)
+{
+ struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
+
+ mutex_lock(&gpio->lock);
+ gpio->out &= ~mask;
+ gpio->out |= values & mask;
+ gpio->write(gpio->client, gpio->out);
+ mutex_unlock(&gpio->lock);
+}
+
/*-------------------------------------------------------------------------*/
static int pcf857x_to_irq(struct gpio_chip *chip, unsigned offset)
@@ -280,6 +302,8 @@ static int pcf857x_probe(struct i2c_clie
gpio->chip.owner = THIS_MODULE;
gpio->chip.get = pcf857x_get;
gpio->chip.set = pcf857x_set;
+ gpio->chip.get_block = pcf857x_get_block;
+ gpio->chip.set_block = pcf857x_set_block;
gpio->chip.direction_input = pcf857x_input;
gpio->chip.direction_output = pcf857x_output;
gpio->chip.ngpio = id->driver_data;
--- linux-2.6.orig/drivers/gpio/gpio-pch.c
+++ linux-2.6/drivers/gpio/gpio-pch.c
@@ -122,6 +122,23 @@ static void pch_gpio_set(struct gpio_chi
spin_unlock_irqrestore(&chip->spinlock, flags);
}
+static void pch_gpio_set_block(struct gpio_chip *gpio, unsigned long mask,
+ unsigned long values)
+{
+ u32 reg_val;
+ struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
+ unsigned long flags;
+
+ spin_lock_irqsave(&chip->spinlock, flags);
+ reg_val = ioread32(&chip->reg->po);
+
+ reg_val &= ~mask;
+ reg_val |= values & mask;
+
+ iowrite32(reg_val, &chip->reg->po);
+ spin_unlock_irqrestore(&chip->spinlock, flags);
+}
+
static int pch_gpio_get(struct gpio_chip *gpio, unsigned nr)
{
struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
@@ -129,6 +146,14 @@ static int pch_gpio_get(struct gpio_chip
return ioread32(&chip->reg->pi) & (1 << nr);
}
+static unsigned long pch_gpio_get_block(struct gpio_chip *gpio,
+ unsigned long mask)
+{
+ struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
+
+ return ioread32(&chip->reg->pi) & mask;
+}
+
static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
int val)
{
@@ -218,8 +243,10 @@ static void pch_gpio_setup(struct pch_gp
gpio->owner = THIS_MODULE;
gpio->direction_input = pch_gpio_direction_input;
gpio->get = pch_gpio_get;
+ gpio->get_block = pch_gpio_get_block;
gpio->direction_output = pch_gpio_direction_output;
gpio->set = pch_gpio_set;
+ gpio->set_block = pch_gpio_set_block;
gpio->dbg_show = NULL;
gpio->base = -1;
gpio->ngpio = gpio_pins[chip->ioh];
--- linux-2.6.orig/drivers/gpio/gpio-pl061.c
+++ linux-2.6/drivers/gpio/gpio-pl061.c
@@ -123,6 +123,21 @@ static void pl061_set_value(struct gpio_
writeb(!!value << offset, chip->base + (1 << (offset + 2)));
}
+static unsigned long pl061_get_block(struct gpio_chip *gc, unsigned long mask)
+{
+ struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
+
+ return !!readb(chip->base + (mask << 2));
+}
+
+static void pl061_set_block(struct gpio_chip *gc, unsigned long mask,
+ unsigned long values)
+{
+ struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
+
+ writeb(values & mask, chip->base + (mask << 2));
+}
+
static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
@@ -256,6 +271,8 @@ static int pl061_probe(struct amba_devic
chip->gc.direction_output = pl061_direction_output;
chip->gc.get = pl061_get_value;
chip->gc.set = pl061_set_value;
+ chip->gc.get_block = pl061_get_block;
+ chip->gc.set_block = pl061_set_block;
chip->gc.to_irq = pl061_to_irq;
chip->gc.ngpio = PL061_GPIO_NR;
chip->gc.label = dev_name(&dev->dev);
--- linux-2.6.orig/drivers/gpio/gpio-twl6040.c
+++ linux-2.6/drivers/gpio/gpio-twl6040.c
@@ -46,6 +46,19 @@ static int twl6040gpo_get(struct gpio_ch
return (ret >> offset) & 1;
}
+static unsigned long twl6040gpo_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+ struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent);
+ int ret = 0;
+
+ ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL);
+ if (ret < 0)
+ return 0;
+
+ return ret & mask;
+}
+
static int twl6040gpo_direction_out(struct gpio_chip *chip, unsigned offset,
int value)
{
@@ -71,12 +84,31 @@ static void twl6040gpo_set(struct gpio_c
twl6040_reg_write(twl6040, TWL6040_REG_GPOCTL, gpoctl);
}
+static void twl6040gpo_set_block(struct gpio_chip *chip, unsigned long mask,
+ unsigned long values)
+{
+ struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent);
+ int ret;
+ u8 gpoctl;
+
+ ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL);
+ if (ret < 0)
+ return;
+
+ gpoctl = ret & ~mask;
+ gpoctl |= values & mask;
+
+ twl6040_reg_write(twl6040, TWL6040_REG_GPOCTL, gpoctl);
+}
+
static struct gpio_chip twl6040gpo_chip = {
.label = "twl6040",
.owner = THIS_MODULE,
.get = twl6040gpo_get,
+ .get_block = twl6040gpo_get_block,
.direction_output = twl6040gpo_direction_out,
.set = twl6040gpo_set,
+ .set_block = twl6040gpo_set_block,
.can_sleep = 1,
};
--- linux-2.6.orig/drivers/gpio/gpio-ucb1400.c
+++ linux-2.6/drivers/gpio/gpio-ucb1400.c
@@ -45,6 +45,27 @@ static void ucb1400_gpio_set(struct gpio
ucb1400_gpio_set_value(gpio->ac97, off, val);
}
+static unsigned long ucb1400_gpio_get_block(struct gpio_chip *gc,
+ unsigned long mask)
+{
+ struct ucb1400_gpio *gpio;
+ gpio = container_of(gc, struct ucb1400_gpio, gc);
+ return ucb1400_reg_read(gpio->ac97, UCB_IO_DATA) & mask;
+}
+
+static void ucb1400_gpio_set_block(struct gpio_chip *gc, unsigned long mask,
+ unsigned long values)
+{
+ struct ucb1400_gpio *gpio;
+ u16 tmp;
+ gpio = container_of(gc, struct ucb1400_gpio, gc);
+
+ tmp = ucb1400_reg_read(gpio->ac97, UCB_IO_DATA) & ~mask;
+ tmp |= values & mask;
+
+ ucb1400_reg_write(gpio->ac97, UCB_IO_DATA, tmp);
+}
+
static int ucb1400_gpio_probe(struct platform_device *dev)
{
struct ucb1400_gpio *ucb = dev->dev.platform_data;
@@ -66,6 +87,8 @@ static int ucb1400_gpio_probe(struct pla
ucb->gc.direction_output = ucb1400_gpio_dir_out;
ucb->gc.get = ucb1400_gpio_get;
ucb->gc.set = ucb1400_gpio_set;
+ ucb->gc.get_block = ucb1400_gpio_get_block;
+ ucb->gc.set_block = ucb1400_gpio_set_block;
ucb->gc.can_sleep = 1;
err = gpiochip_add(&ucb->gc);
--- linux-2.6.orig/drivers/gpio/gpio-vt8500.c
+++ linux-2.6/drivers/gpio/gpio-vt8500.c
@@ -209,6 +209,28 @@ static void vt8500_gpio_set_value(struct
writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->data_out);
}
+static unsigned long vt8500_gpio_get_block(struct gpio_chip *chip,
+ unsigned long mask)
+{
+ struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+
+ return readl_relaxed(vt8500_chip->base + vt8500_chip->regs->data_in) &
+ mask;
+}
+
+static void vt8500_gpio_set_block(struct gpio_chip *chip, unsigned long mask,
+ unsigned long values)
+{
+ struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+
+ u32 val = readl_relaxed(vt8500_chip->base +
+ vt8500_chip->regs->data_out);
+ val &= ~mask;
+ val |= values & mask;
+
+ writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->data_out);
+}
+
static int vt8500_of_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags)
{
@@ -251,6 +273,8 @@ static int vt8500_add_chips(struct platf
chip->direction_output = vt8500_gpio_direction_output;
chip->get = vt8500_gpio_get_value;
chip->set = vt8500_gpio_set_value;
+ chip->get_block = vt8500_gpio_get_block;
+ chip->set_block = vt8500_gpio_set_block;
chip->can_sleep = 0;
chip->base = pin_cnt;
chip->ngpio = data->banks[i].ngpio;
--- linux-2.6.orig/drivers/gpio/gpio-xilinx.c
+++ linux-2.6/drivers/gpio/gpio-xilinx.c
@@ -49,6 +49,21 @@ static int xgpio_get(struct gpio_chip *g
}
/**
+ * xgpio_get_block - Read a block of specified signals of the GPIO device.
+ * @gc: Pointer to gpio_chip device structure.
+ * @mask: Bit mask (bit 0 == 0th GPIO) for GPIOs to get
+ *
+ * This function reads a block of specified signal of the GPIO device, returned
+ * as a bit mask, each bit representing a GPIO
+ */
+static unsigned long xgpio_get_block(struct gpio_chip *gc, unsigned long mask)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+
+ return in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) & mask;
+}
+
+/**
* xgpio_set - Write the specified signal of the GPIO device.
* @gc: Pointer to gpio_chip device structure.
* @gpio: GPIO signal number.
@@ -77,6 +92,33 @@ static void xgpio_set(struct gpio_chip *
}
/**
+ * xgpio_set_block - Write a block of specified signals of the GPIO device.
+ * @gc: Pointer to gpio_chip device structure.
+ * @mask: Bit mask (bit 0 == 0th GPIO) for GPIOs to set
+ * @values: Bit mapped values
+ *
+ * This function writes the specified values in to the specified signals of the
+ * GPIO device.
+ */
+static void xgpio_set_block(struct gpio_chip *gc, unsigned long mask,
+ unsigned long values)
+{
+ unsigned long flags;
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct xgpio_instance *chip =
+ container_of(mm_gc, struct xgpio_instance, mmchip);
+
+ spin_lock_irqsave(&chip->gpio_lock, flags);
+
+ chip->gpio_state &= ~mask;
+ chip->gpio_state |= mask & values;
+
+ out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
+
+ spin_unlock_irqrestore(&chip->gpio_lock, flags);
+}
+
+/**
* xgpio_dir_in - Set the direction of the specified GPIO signal as input.
* @gc: Pointer to gpio_chip device structure.
* @gpio: GPIO signal number.
@@ -195,6 +237,8 @@ static int __devinit xgpio_of_probe(stru
chip->mmchip.gc.direction_output = xgpio_dir_out;
chip->mmchip.gc.get = xgpio_get;
chip->mmchip.gc.set = xgpio_set;
+ chip->mmchip.gc.get_block = xgpio_get_block;
+ chip->mmchip.gc.set_block = xgpio_set_block;
chip->mmchip.save_regs = xgpio_save_regs;
^ permalink raw reply
* [PATCH 4/5 v6] gpio: Add device tree support to block GPIO API
From: Roland Stigge @ 2012-10-20 10:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350728508-22508-1-git-send-email-stigge@antcom.de>
This patch adds device tree support to the block GPIO API.
Signed-off-by: Roland Stigge <stigge@antcom.de>
---
Documentation/devicetree/bindings/gpio/gpio-block.txt | 36 +++++++
drivers/gpio/Makefile | 1
drivers/gpio/gpioblock-of.c | 84 ++++++++++++++++++
3 files changed, 121 insertions(+)
--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/gpio/gpio-block.txt
@@ -0,0 +1,36 @@
+Block GPIO definition
+=====================
+
+This binding specifies arbitrary blocks of gpios, combining gpios from one or
+more GPIO controllers together, to form a word for r/w access.
+
+Required property:
+- compatible: must be "linux,gpio-block"
+
+Required subnodes:
+- the name will be the registered name of the block
+- property "gpios" is a list of gpios for the respective block
+
+Example:
+
+ blockgpio {
+ compatible = "linux,gpio-block";
+
+ block0 {
+ gpios = <&gpio 3 0 0>,
+ <&gpio 3 1 0>;
+ };
+ block1 {
+ gpios = <&gpio 4 1 0>,
+ <&gpio 4 3 0>,
+ <&gpio 4 2 0>,
+ <&gpio 4 4 0>,
+ <&gpio 4 5 0>,
+ <&gpio 4 6 0>,
+ <&gpio 4 7 0>,
+ <&gpio 4 8 0>,
+ <&gpio 4 9 0>,
+ <&gpio 4 10 0>,
+ <&gpio 4 19 0>;
+ };
+ };
--- linux-2.6.orig/drivers/gpio/Makefile
+++ linux-2.6/drivers/gpio/Makefile
@@ -4,6 +4,7 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o
obj-$(CONFIG_OF_GPIO) += gpiolib-of.o
+obj-$(CONFIG_OF_GPIO) += gpioblock-of.o
# Device drivers. Generally keep list sorted alphabetically
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
--- /dev/null
+++ linux-2.6/drivers/gpio/gpioblock-of.c
@@ -0,0 +1,84 @@
+/*
+ * OF implementation for Block GPIO
+ *
+ * Copyright (C) 2012 Roland Stigge <stigge@antcom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+static int __devinit gpioblock_of_probe(struct platform_device *pdev)
+{
+ struct device_node *block;
+ unsigned *gpios;
+ int ngpio;
+ int ret;
+ struct gpio_block *gb;
+
+ for_each_available_child_of_node(pdev->dev.of_node, block) {
+ int i;
+
+ ngpio = of_gpio_count(block);
+ gpios = kzalloc(ngpio * sizeof(*gpios), GFP_KERNEL);
+ if (!gpios)
+ return -ENOMEM;
+ for (i = 0; i < ngpio; i++) {
+ ret = of_get_gpio(block, i);
+ if (ret < 0)
+ return ret; /* expect -EPROBE_DEFER */
+ gpios[i] = ret;
+ }
+ gb = gpio_block_create(gpios, ngpio, block->name);
+ if (IS_ERR(gb)) {
+ dev_err(&pdev->dev,
+ "Error creating GPIO block from device tree\n");
+ return PTR_ERR(gb);
+ }
+ ret = gpio_block_register(gb);
+ if (ret < 0) {
+ gpio_block_free(gb);
+ return ret;
+ }
+ kfree(gpios);
+ dev_info(&pdev->dev, "Registered gpio block %s: %d gpios\n",
+ block->name, ngpio);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id gpioblock_of_match[] __devinitdata = {
+ { .compatible = "linux,gpio-block", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, gpioblock_of_match);
+#endif
+
+static struct platform_driver gpioblock_of_driver = {
+ .driver = {
+ .name = "gpio-block",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpioblock_of_match),
+
+ },
+ .probe = gpioblock_of_probe,
+};
+
+module_platform_driver(gpioblock_of_driver);
+
+MODULE_DESCRIPTION("GPIO Block driver");
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpioblock-of");
^ permalink raw reply
* [PATCH 3/5 v6] gpiolib: Fix default attributes for class
From: Roland Stigge @ 2012-10-20 10:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350728508-22508-1-git-send-email-stigge@antcom.de>
There is a race condition between creating a gpio or gpiochip device and adding
default attributes. This patch fixes this by defining the default attributes as
dev_attrs of the class. For this, it was necessary to create a separate
gpiochip_class besides gpio_class.
Signed-off-by: Roland Stigge <stigge@antcom.de>
---
Documentation/ABI/testing/sysfs-gpio | 11 ++++
drivers/gpio/gpiolib.c | 79 +++++++++++++++--------------------
2 files changed, 45 insertions(+), 45 deletions(-)
--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -20,6 +20,17 @@ Description:
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
+
+What: /sys/class/gpiochip/
+Date: October 2012
+KernelVersion: 3.7
+Contact: Roland Stigge <stigge@antcom.de>
+Description:
+
+ Each gpiochip is represented by a separate device having the following
+ attributes:
+
+ /sys/class/gpiochip
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -321,9 +321,6 @@ static ssize_t gpio_value_store(struct d
return status;
}
-static const DEVICE_ATTR(value, 0644,
- gpio_value_show, gpio_value_store);
-
static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
{
struct sysfs_dirent *value_sd = priv;
@@ -544,19 +541,6 @@ static ssize_t gpio_active_low_store(str
return status ? : size;
}
-static const DEVICE_ATTR(active_low, 0644,
- gpio_active_low_show, gpio_active_low_store);
-
-static const struct attribute *gpio_attrs[] = {
- &dev_attr_value.attr,
- &dev_attr_active_low.attr,
- NULL,
-};
-
-static const struct attribute_group gpio_attr_group = {
- .attrs = (struct attribute **) gpio_attrs,
-};
-
/*
* /sys/class/gpio/gpiochipN/
* /base ... matching gpio_chip.base (N)
@@ -571,7 +555,6 @@ static ssize_t chip_base_show(struct dev
return sprintf(buf, "%d\n", chip->base);
}
-static DEVICE_ATTR(base, 0444, chip_base_show, NULL);
static ssize_t chip_label_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -580,7 +563,6 @@ static ssize_t chip_label_show(struct de
return sprintf(buf, "%s\n", chip->label ? : "");
}
-static DEVICE_ATTR(label, 0444, chip_label_show, NULL);
static ssize_t chip_ngpio_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -589,18 +571,6 @@ static ssize_t chip_ngpio_show(struct de
return sprintf(buf, "%u\n", chip->ngpio);
}
-static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
-
-static const struct attribute *gpiochip_attrs[] = {
- &dev_attr_base.attr,
- &dev_attr_label.attr,
- &dev_attr_ngpio.attr,
- NULL,
-};
-
-static const struct attribute_group gpiochip_attr_group = {
- .attrs = (struct attribute **) gpiochip_attrs,
-};
/*
* /sys/class/gpio/export ... write-only
@@ -677,11 +647,32 @@ static struct class_attribute gpio_class
__ATTR_NULL,
};
+static struct device_attribute gpio_attrs[] = {
+ __ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store),
+ __ATTR(value, 0644, gpio_value_show, gpio_value_store),
+ __ATTR_NULL,
+};
+
static struct class gpio_class = {
.name = "gpio",
.owner = THIS_MODULE,
- .class_attrs = gpio_class_attrs,
+ .class_attrs = gpio_class_attrs,
+ .dev_attrs = gpio_attrs,
+};
+
+static struct device_attribute gpiochip_attrs[] = {
+ __ATTR(label, 0444, chip_label_show, NULL),
+ __ATTR(base, 0444, chip_base_show, NULL),
+ __ATTR(ngpio, 0444, chip_ngpio_show, NULL),
+ __ATTR_NULL,
+};
+
+static struct class gpiochip_class = {
+ .name = "gpiochip",
+ .owner = THIS_MODULE,
+
+ .dev_attrs = gpiochip_attrs,
};
@@ -738,10 +729,7 @@ int gpio_export(unsigned gpio, bool dire
dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
desc, ioname ? ioname : "gpio%u", gpio);
if (!IS_ERR(dev)) {
- status = sysfs_create_group(&dev->kobj,
- &gpio_attr_group);
-
- if (!status && direction_may_change)
+ if (direction_may_change)
status = device_create_file(dev,
&dev_attr_direction);
@@ -911,25 +899,22 @@ EXPORT_SYMBOL_GPL(gpio_unexport);
static int gpiochip_export(struct gpio_chip *chip)
{
- int status;
+ int status = 0;
struct device *dev;
/* Many systems register gpio chips for SOC support very early,
* before driver model support is available. In those cases we
* export this later, in gpiolib_sysfs_init() ... here we just
- * verify that _some_ field of gpio_class got initialized.
+ * verify that _some_ field of gpiochip_class got initialized.
*/
- if (!gpio_class.p)
+ if (!gpiochip_class.p)
return 0;
/* use chip->base for the ID; it's already known to be unique */
mutex_lock(&sysfs_lock);
- dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip,
- "gpiochip%d", chip->base);
- if (!IS_ERR(dev)) {
- status = sysfs_create_group(&dev->kobj,
- &gpiochip_attr_group);
- } else
+ dev = device_create(&gpiochip_class, chip->dev, MKDEV(0, 0), chip,
+ "gpiochip%d", chip->base);
+ if (IS_ERR(dev))
status = PTR_ERR(dev);
chip->exported = (status == 0);
mutex_unlock(&sysfs_lock);
@@ -957,7 +942,7 @@ static void gpiochip_unexport(struct gpi
struct device *dev;
mutex_lock(&sysfs_lock);
- dev = class_find_device(&gpio_class, NULL, chip, match_export);
+ dev = class_find_device(&gpiochip_class, NULL, chip, match_export);
if (dev) {
put_device(dev);
device_unregister(dev);
@@ -1190,6 +1175,10 @@ static int __init gpiolib_sysfs_init(voi
if (status < 0)
return status;
+ status = class_register(&gpiochip_class);
+ if (status < 0)
+ return status;
+
status = class_register(&gpio_block_class);
if (status < 0)
return status;
^ permalink raw reply
* [PATCH 2/5 v6] gpio: Add sysfs support to block GPIO API
From: Roland Stigge @ 2012-10-20 10:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350728508-22508-1-git-send-email-stigge@antcom.de>
This patch adds sysfs support to the block GPIO API.
Signed-off-by: Roland Stigge <stigge@antcom.de>
---
Documentation/ABI/testing/sysfs-gpio | 18 ++
drivers/gpio/gpiolib.c | 214 +++++++++++++++++++++++++++++++++++
include/asm-generic/gpio.h | 11 +
include/linux/gpio.h | 13 ++
4 files changed, 256 insertions(+)
--- linux-2.6.orig/Documentation/ABI/testing/sysfs-gpio
+++ linux-2.6/Documentation/ABI/testing/sysfs-gpio
@@ -25,3 +25,21 @@ Description:
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
+What: /sys/class/gpioblock/
+Date: October 2012
+KernelVersion: 3.7
+Contact: Roland Stigge <stigge@antcom.de>
+Description:
+
+ Block GPIO devices are visible in sysfs as soon as they are registered
+ (e.g. via devicetree definition). For actual I/O use, their "exported"
+ boolean attribute must be set to "1". Then, the attribute "values" is
+ created and at the same time, the GPIOs in the block are requested for
+ exclusive use by sysfs.
+
+ /sys/class/gpioblock
+ /BLOCKNAME ... for each GPIO block name
+ /ngpio ... (r/o) number of GPIOs in this group
+ /exported ... sysfs export state of this group (0, 1)
+ /value ... current value as 32 or 64 bit integer in hex
+ (only available if /exported is 1)
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -972,6 +972,214 @@ static void gpiochip_unexport(struct gpi
chip->label, status);
}
+static ssize_t gpio_block_ngpio_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ const struct gpio_block *block = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", block->ngpio);
+}
+
+static ssize_t gpio_block_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ const struct gpio_block *block = dev_get_drvdata(dev);
+
+ return sprintf(buf, sizeof(unsigned long) == 4 ? "0x%08lx\n" :
+ "0x%016lx\n", gpio_block_get(block));
+}
+
+static bool gpio_block_is_output(struct gpio_block *block)
+{
+ int i;
+
+ for (i = 0; i < block->ngpio; i++)
+ if (!test_bit(FLAG_IS_OUT, &gpio_desc[block->gpio[i]].flags))
+ return false;
+ return true;
+}
+
+static ssize_t gpio_block_value_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ ssize_t status;
+ struct gpio_block *block = dev_get_drvdata(dev);
+ unsigned long value;
+
+ status = kstrtoul(buf, 0, &value);
+ if (status == 0) {
+ mutex_lock(&sysfs_lock);
+ if (gpio_block_is_output(block)) {
+ gpio_block_set(block, value);
+ status = size;
+ } else {
+ status = -EPERM;
+ }
+ mutex_unlock(&sysfs_lock);
+ }
+ return status;
+}
+
+static struct device_attribute
+dev_attr_block_value = __ATTR(value, S_IWUSR | S_IRUGO, gpio_block_value_show,
+ gpio_block_value_store);
+
+static struct class gpio_block_class;
+
+static int gpio_block_value_is_exported(struct gpio_block *block)
+{
+ struct device *dev;
+ struct sysfs_dirent *sd = NULL;
+
+ mutex_lock(&sysfs_lock);
+ dev = class_find_device(&gpio_block_class, NULL, block, match_export);
+ if (!dev)
+ goto out;
+
+ sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value");
+
+out:
+ mutex_unlock(&sysfs_lock);
+ return !!sd;
+}
+
+static ssize_t gpio_block_exported_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct gpio_block *block = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", gpio_block_value_is_exported(block));
+}
+
+static int gpio_block_value_export(struct gpio_block *block)
+{
+ struct device *dev;
+ int status;
+ int i;
+
+ mutex_lock(&sysfs_lock);
+
+ for (i = 0; i < block->ngpio; i++) {
+ status = gpio_request(block->gpio[i], "sysfs");
+ if (status)
+ goto out;
+ }
+
+ dev = class_find_device(&gpio_block_class, NULL, block, match_export);
+ if (!dev) {
+ status = -ENODEV;
+ goto out;
+ }
+
+ status = device_create_file(dev, &dev_attr_block_value);
+ if (status)
+ goto out;
+
+ mutex_unlock(&sysfs_lock);
+ return 0;
+
+out:
+ while (--i >= 0)
+ gpio_free(block->gpio[i]);
+
+ mutex_unlock(&sysfs_lock);
+ return status;
+}
+
+static int gpio_block_value_unexport(struct gpio_block *block)
+{
+ struct device *dev;
+ int i;
+
+ dev = class_find_device(&gpio_block_class, NULL, block, match_export);
+ if (!dev)
+ return -ENODEV;
+
+ for (i = 0; i < block->ngpio; i++)
+ gpio_free(block->gpio[i]);
+
+ device_remove_file(dev, &dev_attr_block_value);
+
+ return 0;
+}
+
+static ssize_t gpio_block_exported_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ long value;
+ int status;
+ struct gpio_block *block = dev_get_drvdata(dev);
+ int exported = gpio_block_value_is_exported(block);
+
+ status = kstrtoul(buf, 0, &value);
+ if (status < 0)
+ goto err;
+
+ if (value != exported) {
+ if (value)
+ status = gpio_block_value_export(block);
+ else
+ status = gpio_block_value_unexport(block);
+ if (!status)
+ status = size;
+ } else {
+ status = size;
+ }
+err:
+ return status;
+}
+
+static struct device_attribute gpio_block_attrs[] = {
+ __ATTR(exported, S_IWUSR | S_IRUGO, gpio_block_exported_show,
+ gpio_block_exported_store),
+ __ATTR(ngpio, S_IRUGO, gpio_block_ngpio_show, NULL),
+ __ATTR_NULL,
+};
+
+static struct class gpio_block_class = {
+ .name = "gpioblock",
+ .owner = THIS_MODULE,
+
+ .dev_attrs = gpio_block_attrs,
+};
+
+int gpio_block_export(struct gpio_block *block)
+{
+ int status = 0;
+ struct device *dev;
+
+ /* can't export until sysfs is available ... */
+ if (!gpio_block_class.p) {
+ pr_debug("%s: called too early!\n", __func__);
+ return -ENOENT;
+ }
+
+ mutex_lock(&sysfs_lock);
+ dev = device_create(&gpio_block_class, NULL, MKDEV(0, 0), block,
+ block->name);
+ if (IS_ERR(dev))
+ status = PTR_ERR(dev);
+ mutex_unlock(&sysfs_lock);
+
+ return status;
+}
+EXPORT_SYMBOL_GPL(gpio_block_export);
+
+void gpio_block_unexport(struct gpio_block *block)
+{
+ struct device *dev;
+
+ mutex_lock(&sysfs_lock);
+ dev = class_find_device(&gpio_block_class, NULL, block, match_export);
+ if (dev)
+ device_unregister(dev);
+ mutex_unlock(&sysfs_lock);
+}
+EXPORT_SYMBOL_GPL(gpio_block_unexport);
+
static int __init gpiolib_sysfs_init(void)
{
int status;
@@ -982,6 +1190,10 @@ static int __init gpiolib_sysfs_init(voi
if (status < 0)
return status;
+ status = class_register(&gpio_block_class);
+ if (status < 0)
+ return status;
+
/* Scan and register the gpio_chips which registered very
* early (e.g. before the class_register above was called).
*
@@ -1876,6 +2088,7 @@ int gpio_block_register(struct gpio_bloc
return -EBUSY;
list_add(&block->list, &gpio_block_list);
+ gpio_block_export(block);
return 0;
}
@@ -1888,6 +2101,7 @@ void gpio_block_unregister(struct gpio_b
list_for_each_entry(i, &gpio_block_list, list)
if (i == block) {
list_del(&i->list);
+ gpio_block_unexport(block);
break;
}
}
--- linux-2.6.orig/include/asm-generic/gpio.h
+++ linux-2.6/include/asm-generic/gpio.h
@@ -211,6 +211,8 @@ extern int gpio_export_link(struct devic
unsigned gpio);
extern int gpio_sysfs_set_active_low(unsigned gpio, int value);
extern void gpio_unexport(unsigned gpio);
+extern int gpio_block_export(struct gpio_block *block);
+extern void gpio_block_unexport(struct gpio_block *block);
#endif /* CONFIG_GPIO_SYSFS */
@@ -270,6 +272,15 @@ static inline int gpio_sysfs_set_active_
static inline void gpio_unexport(unsigned gpio)
{
}
+
+static inline int gpio_block_export(struct gpio_block *block)
+{
+ return -ENOSYS;
+}
+
+static inline void gpio_block_unexport(struct gpio_block *block)
+{
+}
#endif /* CONFIG_GPIO_SYSFS */
#endif /* _ASM_GENERIC_GPIO_H */
--- linux-2.6.orig/include/linux/gpio.h
+++ linux-2.6/include/linux/gpio.h
@@ -291,6 +291,19 @@ static inline void gpio_unexport(unsigne
WARN_ON(1);
}
+static inline int gpio_block_export(struct gpio_block *block)
+{
+ /* GPIO block can never have been requested or set as {in,out}put */
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+static inline void gpio_block_unexport(struct gpio_block *block)
+{
+ /* GPIO block can never have been exported */
+ WARN_ON(1);
+}
+
static inline int gpio_to_irq(unsigned gpio)
{
/* GPIO can never have been requested or set as input */
^ permalink raw reply
* [PATCH 1/5 v6] gpio: Add a block GPIO API to gpiolib
From: Roland Stigge @ 2012-10-20 10:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350728508-22508-1-git-send-email-stigge@antcom.de>
The recurring task of providing simultaneous access to GPIO lines (especially
for bit banging protocols) needs an appropriate API.
This patch adds a kernel internal "Block GPIO" API that enables simultaneous
access to several GPIOs. This is done by abstracting GPIOs to an n-bit word:
Once requested, it provides access to a group of GPIOs which can range over
multiple GPIO chips.
Signed-off-by: Roland Stigge <stigge@antcom.de>
---
Documentation/gpio.txt | 47 +++++++++
drivers/gpio/gpiolib.c | 217 +++++++++++++++++++++++++++++++++++++++++++++
include/asm-generic/gpio.h | 15 +++
include/linux/gpio.h | 74 +++++++++++++++
4 files changed, 353 insertions(+)
--- linux-2.6.orig/Documentation/gpio.txt
+++ linux-2.6/Documentation/gpio.txt
@@ -439,6 +439,53 @@ slower clock delays the rising edge of S
signaling rate accordingly.
+Block GPIO
+----------
+
+The above described interface concentrates on handling single GPIOs. However,
+in applications where it is critical to set several GPIOs at once, this
+interface doesn't work well, e.g. bit-banging protocols via grouped GPIO lines.
+Consider a GPIO controller that is connected via a slow I2C line. When
+switching two or more GPIOs one after another, there can be considerable time
+between those events. This is solved by an interface called Block GPIO:
+
+struct gpio_block *gpio_block_create(unsigned int *gpios, size_t size);
+
+This creates a new block of GPIOs as a list of GPIO numbers with the specified
+size which are accessible via the returned struct gpio_block and the accessor
+functions described below. Please note that you need to request the GPIOs
+separately via gpio_request(). An arbitrary list of globally valid GPIOs can be
+specified, even ranging over several gpio_chips. Actual handling of I/O
+operations will be done on a best effort base, i.e. simultaneous I/O only where
+possible by hardware and implemented in the respective GPIO driver. The number
+of GPIOs in one block is limited to the number of bits in an unsigned long, or
+BITS_PER_LONG, of the respective platform, i.e. typically at least 32 on a 32
+bit system, and at least 64 on a 64 bit system. However, several blocks can be
+defined at once.
+
+unsigned gpio_block_get(struct gpio_block *block);
+void gpio_block_set(struct gpio_block *block, unsigned value);
+
+With those accessor functions, setting and getting the GPIO values is possible,
+analogous to gpio_get_value() and gpio_set_value(). Each bit in the return
+value of gpio_block_get() and in the value argument of gpio_block_set()
+corresponds to a bit specified on gpio_block_create(). Block operations in
+hardware are only possible where the respective GPIO driver implements it,
+falling back to using single GPIO operations where the driver only implements
+single GPIO access.
+
+void gpio_block_free(struct gpio_block *block);
+
+After the GPIO block isn't used anymore, it should be free'd via
+gpio_block_free().
+
+int gpio_block_register(struct gpio_block *block);
+void gpio_block_unregister(struct gpio_block *block);
+
+These functions can be used to register a GPIO block. Blocks registered this
+way will be available via sysfs.
+
+
What do these conventions omit?
===============================
One of the biggest things these conventions omit is pin multiplexing, since
--- linux-2.6.orig/drivers/gpio/gpiolib.c
+++ linux-2.6/drivers/gpio/gpiolib.c
@@ -83,6 +83,8 @@ static inline void desc_set_label(struct
#endif
}
+static LIST_HEAD(gpio_block_list);
+
/* Warn when drivers omit gpio_request() calls -- legal but ill-advised
* when setting direction, and otherwise illegal. Until board setup code
* and drivers use explicit requests everywhere (which won't happen when
@@ -1676,6 +1678,221 @@ void __gpio_set_value(unsigned gpio, int
}
EXPORT_SYMBOL_GPL(__gpio_set_value);
+static int gpio_block_chip_index(struct gpio_block *block, struct gpio_chip *gc)
+{
+ int i;
+
+ for (i = 0; i < block->nchip; i++) {
+ if (block->gbc[i].gc == gc)
+ return i;
+ }
+ return -1;
+}
+
+struct gpio_block *gpio_block_create(unsigned *gpios, size_t size,
+ const char *name)
+{
+ struct gpio_block *block;
+ struct gpio_block_chip *gbc;
+ struct gpio_remap *remap;
+ void *tmp;
+ int i;
+
+ if (size < 1 || size > sizeof(unsigned long) * 8)
+ return ERR_PTR(-EINVAL);
+
+ for (i = 0; i < size; i++)
+ if (!gpio_is_valid(gpios[i]))
+ return ERR_PTR(-EINVAL);
+
+ block = kzalloc(sizeof(struct gpio_block), GFP_KERNEL);
+ if (!block)
+ return ERR_PTR(-ENOMEM);
+
+ block->name = name;
+ block->ngpio = size;
+ block->gpio = kzalloc(sizeof(*block->gpio) * size, GFP_KERNEL);
+ if (!block->gpio)
+ goto err1;
+
+ memcpy(block->gpio, gpios, sizeof(*block->gpio) * size);
+
+ for (i = 0; i < size; i++) {
+ struct gpio_chip *gc = gpio_to_chip(gpios[i]);
+ int bit = gpios[i] - gc->base;
+ int index = gpio_block_chip_index(block, gc);
+
+ if (index < 0) {
+ block->nchip++;
+ tmp = krealloc(block->gbc,
+ sizeof(struct gpio_block_chip) *
+ block->nchip, GFP_KERNEL);
+ if (!tmp) {
+ kfree(block->gbc);
+ goto err2;
+ }
+ block->gbc = tmp;
+ gbc = &block->gbc[block->nchip - 1];
+ gbc->gc = gc;
+ gbc->remap = NULL;
+ gbc->nremap = 0;
+ gbc->mask = 0;
+ } else {
+ gbc = &block->gbc[index];
+ }
+ /* represents the mask necessary on calls to the driver's
+ * .get_block() and .set_block()
+ */
+ gbc->mask |= BIT(bit);
+
+ /* collect gpios that are specified together, represented by
+ * neighboring bits
+ *
+ * Note that even though in setting remap is given a negative
+ * index, the next lines guard that the potential out-of-bounds
+ * pointer is not dereferenced when out of bounds.
+ */
+ remap = &gbc->remap[gbc->nremap - 1];
+ if (!gbc->nremap || (bit - i != remap->offset)) {
+ gbc->nremap++;
+ tmp = krealloc(gbc->remap,
+ sizeof(struct gpio_remap) *
+ gbc->nremap, GFP_KERNEL);
+ if (!tmp) {
+ kfree(gbc->remap);
+ goto err3;
+ }
+ gbc->remap = tmp;
+ remap = &gbc->remap[gbc->nremap - 1];
+ remap->offset = bit - i;
+ remap->mask = 0;
+ }
+
+ /* represents the mask necessary for bit reordering between
+ * gpio_block (i.e. as specified on gpio_block_get() and
+ * gpio_block_set()) and gpio_chip domain (i.e. as specified on
+ * the driver's .set_block() and .get_block())
+ */
+ remap->mask |= BIT(i);
+ }
+
+ return block;
+err3:
+ for (i = 0; i < block->nchip - 1; i++)
+ kfree(block->gbc[i].remap);
+ kfree(block->gbc);
+err2:
+ kfree(block->gpio);
+err1:
+ kfree(block);
+ return ERR_PTR(-ENOMEM);
+}
+EXPORT_SYMBOL_GPL(gpio_block_create);
+
+void gpio_block_free(struct gpio_block *block)
+{
+ int i;
+
+ for (i = 0; i < block->nchip; i++)
+ kfree(block->gbc[i].remap);
+ kfree(block->gpio);
+ kfree(block->gbc);
+ kfree(block);
+}
+EXPORT_SYMBOL_GPL(gpio_block_free);
+
+unsigned long gpio_block_get(const struct gpio_block *block)
+{
+ struct gpio_block_chip *gbc;
+ int i, j;
+ unsigned long values = 0;
+
+ for (i = 0; i < block->nchip; i++) {
+ unsigned long remapped = 0;
+
+ gbc = &block->gbc[i];
+
+ if (gbc->gc->get_block) {
+ remapped = gbc->gc->get_block(gbc->gc, gbc->mask);
+ } else {
+ /* emulate */
+ for_each_set_bit(j, &gbc->mask, BITS_PER_LONG)
+ remapped |= gbc->gc->get(gbc->gc,
+ gbc->gc->base + j) << j;
+ }
+
+ for (j = 0; j < gbc->nremap; j++) {
+ struct gpio_remap *gr = &gbc->remap[j];
+
+ values |= (remapped >> gr->offset) & gr->mask;
+ }
+ }
+
+ return values;
+}
+EXPORT_SYMBOL_GPL(gpio_block_get);
+
+void gpio_block_set(struct gpio_block *block, unsigned long values)
+{
+ struct gpio_block_chip *gbc;
+ int i, j;
+
+ for (i = 0; i < block->nchip; i++) {
+ unsigned long remapped = 0;
+
+ gbc = &block->gbc[i];
+
+ for (j = 0; j < gbc->nremap; j++) {
+ struct gpio_remap *gr = &gbc->remap[j];
+
+ remapped |= (values & gr->mask) << gr->offset;
+ }
+ if (gbc->gc->set_block) {
+ gbc->gc->set_block(gbc->gc, gbc->mask, remapped);
+ } else {
+ /* emulate */
+ for_each_set_bit(j, &gbc->mask, BITS_PER_LONG)
+ gbc->gc->set(gbc->gc, gbc->gc->base + j,
+ (remapped >> j) & 1);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(gpio_block_set);
+
+struct gpio_block *gpio_block_find_by_name(const char *name)
+{
+ struct gpio_block *i;
+
+ list_for_each_entry(i, &gpio_block_list, list)
+ if (!strcmp(i->name, name))
+ return i;
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(gpio_block_find_by_name);
+
+int gpio_block_register(struct gpio_block *block)
+{
+ if (gpio_block_find_by_name(block->name))
+ return -EBUSY;
+
+ list_add(&block->list, &gpio_block_list);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_block_register);
+
+void gpio_block_unregister(struct gpio_block *block)
+{
+ struct gpio_block *i;
+
+ list_for_each_entry(i, &gpio_block_list, list)
+ if (i == block) {
+ list_del(&i->list);
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(gpio_block_unregister);
+
/**
* __gpio_cansleep() - report whether gpio value access will sleep
* @gpio: gpio in question
--- linux-2.6.orig/include/asm-generic/gpio.h
+++ linux-2.6/include/asm-generic/gpio.h
@@ -43,6 +43,7 @@ static inline bool gpio_is_valid(int num
struct device;
struct gpio;
+struct gpio_block;
struct seq_file;
struct module;
struct device_node;
@@ -105,6 +106,8 @@ struct gpio_chip {
unsigned offset);
int (*get)(struct gpio_chip *chip,
unsigned offset);
+ unsigned long (*get_block)(struct gpio_chip *chip,
+ unsigned long mask);
int (*direction_output)(struct gpio_chip *chip,
unsigned offset, int value);
int (*set_debounce)(struct gpio_chip *chip,
@@ -112,6 +115,9 @@ struct gpio_chip {
void (*set)(struct gpio_chip *chip,
unsigned offset, int value);
+ void (*set_block)(struct gpio_chip *chip,
+ unsigned long mask,
+ unsigned long values);
int (*to_irq)(struct gpio_chip *chip,
unsigned offset);
@@ -171,6 +177,15 @@ extern void gpio_set_value_cansleep(unsi
extern int __gpio_get_value(unsigned gpio);
extern void __gpio_set_value(unsigned gpio, int value);
+extern struct gpio_block *gpio_block_create(unsigned *gpio, size_t size,
+ const char *name);
+extern void gpio_block_free(struct gpio_block *block);
+extern unsigned long gpio_block_get(const struct gpio_block *block);
+extern void gpio_block_set(struct gpio_block *block, unsigned long values);
+extern struct gpio_block *gpio_block_find_by_name(const char *name);
+extern int gpio_block_register(struct gpio_block *block);
+extern void gpio_block_unregister(struct gpio_block *block);
+
extern int __gpio_cansleep(unsigned gpio);
extern int __gpio_to_irq(unsigned gpio);
--- linux-2.6.orig/include/linux/gpio.h
+++ linux-2.6/include/linux/gpio.h
@@ -2,6 +2,8 @@
#define __LINUX_GPIO_H
#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/list.h>
/* see Documentation/gpio.txt */
@@ -39,6 +41,43 @@ struct gpio {
const char *label;
};
+/*
+ * struct gpio_remap - a structure for describing a bit mapping
+ * @mask: a bit mask
+ * @offset: how many bits to shift to the left (negative: to the right)
+ *
+ * When we are mapping bit values from one word to another (here: from GPIO
+ * block domain to GPIO driver domain) we first mask them out with mask and
+ * shift them as specified with offset. More complicated mappings are done by
+ * grouping several of those structs and adding the results together.
+ */
+struct gpio_remap {
+ unsigned long mask;
+ int offset;
+};
+
+struct gpio_block_chip {
+ struct gpio_chip *gc;
+ struct gpio_remap *remap;
+ int nremap;
+ unsigned long mask;
+};
+
+/**
+ * struct gpio_block - a structure describing a list of GPIOs for simultaneous
+ * operations
+ */
+struct gpio_block {
+ struct gpio_block_chip *gbc;
+ size_t nchip;
+ const char *name;
+
+ int ngpio;
+ unsigned *gpio;
+
+ struct list_head list;
+};
+
#ifdef CONFIG_GENERIC_GPIO
#ifdef CONFIG_ARCH_HAVE_CUSTOM_GPIO_H
@@ -169,6 +208,41 @@ static inline void gpio_set_value(unsign
WARN_ON(1);
}
+static inline
+struct gpio_block *gpio_block_create(unsigned *gpios, size_t size,
+ const char *name)
+{
+ WARN_ON(1);
+ return NULL;
+}
+
+static inline void gpio_block_free(struct gpio_block *block)
+{
+ WARN_ON(1);
+}
+
+static inline unsigned long gpio_block_get(const struct gpio_block *block)
+{
+ WARN_ON(1);
+ return 0;
+}
+
+static inline void gpio_block_set(struct gpio_block *block, unsigned long value)
+{
+ WARN_ON(1);
+}
+
+static inline int gpio_block_register(struct gpio_block *block)
+{
+ WARN_ON(1);
+ return 0;
+}
+
+static inline void gpio_block_unregister(struct gpio_block *block)
+{
+ WARN_ON(1);
+}
+
static inline int gpio_cansleep(unsigned gpio)
{
/* GPIO can never have been requested or set as {in,out}put */
^ permalink raw reply
* [PATCH 0/5 v6] gpio: Add block GPIO
From: Roland Stigge @ 2012-10-20 10:21 UTC (permalink / raw)
To: linux-arm-kernel
This set of patches adds:
* Block GPIO API to gpiolib
* Sysfs support for GPIO API, to provide userland access
* Devicetree support to instantiate GPIO blocks via DT
* Example implementations in several gpio drivers since they need
special accessor functions for block wise GPIO access
* Fix for race condition in gpiolib on device creation
Signed-off-by: Roland Stigge <stigge@antcom.de>
--
Changes since v5:
* Documented sysfs: elaborated on "exported" and "values" attributes
* Documented sysfs: gpiochip is a separate class now
* Aggregated driver support patches for block gpio into one single patch
* Added gpio block driver support for twl6040 and pch
Changes since v4:
* Documented word width
* Bugfix: export/unexport on register/unregister
* Using default dev_attrs for gpio_block_class
* Fix gpiolib: race condition on device creation
* Added driver support for ucb14500, vt8500, xilinx
Changes since v3:
* Added driver support for pca953x, em, pl061, max732x, pcf857x
* Coding style improvements
* Fixed krealloc memory leak in error case
* sysfs: values in hex
* Register blocks in a list
* Narrowing lock scope
* Use S_IWUSR and S_IRUGO instead of direct octal values
* Use for_each_set_bit()
* Change from unsigned to unsigned long for masks and values
Changes since v2:
* Added sysfs support
* Added devicetree support
* Added support for lpc32xx, generic
* Added functions for GPIO block registration
* Added more error checking
* Bit remapping bugfix
Changes since v1:
* API change to 32/64 bit word, bit masks
Thanks to Ryan Mallon, Linus Walleij, Stijn Devriendt, Jean-Christophe
Plagniol-Villard, Mark Brown and Greg Kroah-Hartman for reviewing!
Roland Stigge (5):
gpio: Add a block GPIO API to gpiolib
gpio: Add sysfs support to block GPIO API
gpiolib: Fix default attributes for class
gpio: Add device tree support to block GPIO API
gpio: Add block gpio to several gpio drivers
Documentation/ABI/testing/sysfs-gpio | 29 +
Documentation/devicetree/bindings/gpio/gpio-block.txt | 36 +
Documentation/gpio.txt | 47 +
drivers/gpio/Makefile | 1
drivers/gpio/gpio-em.c | 23
drivers/gpio/gpio-generic.c | 56 +
drivers/gpio/gpio-lpc32xx.c | 82 ++
drivers/gpio/gpio-max730x.c | 61 ++
drivers/gpio/gpio-max732x.c | 59 ++
drivers/gpio/gpio-pca953x.c | 64 ++
drivers/gpio/gpio-pcf857x.c | 24
drivers/gpio/gpio-pch.c | 27
drivers/gpio/gpio-pl061.c | 17
drivers/gpio/gpio-twl6040.c | 32 +
drivers/gpio/gpio-ucb1400.c | 23
drivers/gpio/gpio-vt8500.c | 24
drivers/gpio/gpio-xilinx.c | 44 +
drivers/gpio/gpioblock-of.c | 84 ++
drivers/gpio/gpiolib.c | 510 ++++++++++++++++--
include/asm-generic/gpio.h | 26
include/linux/gpio.h | 87 +++
21 files changed, 1311 insertions(+), 45 deletions(-)
^ permalink raw reply
* [PATCH] [media] s5p-tv: don't include linux/version.h in mixer_video.c
From: Sylwester Nawrocki @ 2012-10-20 9:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LNX.2.00.1210182125380.17217@swampdragon.chaosbits.net>
On 10/18/2012 09:28 PM, Jesper Juhl wrote:
> The header is not needed, so remove it.
I have applied it to my tree, thanks!
^ permalink raw reply
* [PATCH] ARM: Kirkwood: new board USI Topkick
From: Andrew Lunn @ 2012-10-20 8:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350679752-11931-1-git-send-email-jason@lakedaemon.net>
> +++ b/arch/arm/boot/dts/kirkwood-topkick.dts
> @@ -0,0 +1,85 @@
> +/dts-v1/;
> +
> +/include/ "kirkwood.dtsi"
> +
> +/ {
> + model = "Univeral Scientific Industrial Co. Topkick-1281P2";
> + compatible = "usi,topkick-1281P2", "usi,topkick", "marvell,kirkwood-88f6282", "marvell,kirkwood";
Hi Jason
Nice to see the correct Kirkwood variant in DT. This is going to be an
issue for pinctrl sometime soon.
> +
> + sata at 80000 {
> + status = "okay";
> + nr-ports = <2>;
Could nr-ports be 1? It saves a little bit of memory. There only seems
to be one SATA interface available, no external SATA port. However, if
the one used is the second SATA, then 2 is required.
> diff --git a/arch/arm/mach-kirkwood/board-usi_topkick.c b/arch/arm/mach-kirkwood/board-usi_topkick.c
> new file mode 100644
> index 0000000..02ba4aa
> --- /dev/null
> +++ b/arch/arm/mach-kirkwood/board-usi_topkick.c
> @@ -0,0 +1,93 @@
> +/*
> + * 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/platform_device.h>
> +#include <linux/ata_platform.h>
> +#include <linux/mv643xx_eth.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/gpio.h>
> +#include <linux/mtd/physmap.h>
> +#include <linux/spi/flash.h>
> +#include <linux/spi/spi.h>
> +#include <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/map.h>
> +#include <mach/kirkwood.h>
> +#include <mach/bridge-regs.h>
> +#include <linux/platform_data/mmc-mvsdio.h>
> +#include "common.h"
> +#include "mpp.h"
A lot of these header files are not needed. Please could you remove
the unused ones.
> +
> +static struct mv643xx_eth_platform_data topkick_ge00_data = {
> + .phy_addr = MV643XX_ETH_PHY_ADDR(0),
> +};
> +
> +/*
> + * GPIO LED layout
> + *
> + * /-SYS_LED(2)
> + * |
> + * | /-DISK_LED
> + * | |
> + * | | /-WLAN_LED(2)
> + * | | |
> + * [SW] [*] [*] [*]
> + */
> +
> +/*
> + * Switch positions
> + *
> + * /-SW_LEFT
> + * |
> + * | /-SW_IDLE
> + * | |
> + * | | /-SW_RIGHT
> + * | | |
> + * PS [L] [I] [R] LEDS
> + */
> +
> +static unsigned int topkick_mpp_config[] __initdata = {
> + MPP21_GPIO, /* DISK_LED (low active) - yellow */
> + MPP36_GPIO, /* SATA0 power enable (high active) */
> + MPP37_GPIO, /* SYS_LED2 (low active) - red */
> + MPP38_GPIO, /* SYS_LED (low active) - blue */
> + MPP39_GPIO, /* WLAN_LED (low active) - green */
> + MPP43_GPIO, /* SW_LEFT (low active) */
> + MPP44_GPIO, /* SW_RIGHT (low active) */
> + MPP45_GPIO, /* SW_IDLE (low active) */
> + MPP46_GPIO, /* SW_LEFT (low active) */
> + MPP48_GPIO, /* WLAN_LED2 (low active) - yellow */
> + 0
This assumes the boot loader is configuring all the other pins as
needed. It would be safer to explicitly configure the SATA pins,
Ethernet pins etc. However, maybe that should wait until we have
pinctrl, which makes it a lot easier.
> +};
> +
> +#define TOPKICK_SATA0_PWR_ENABLE 36
> +
> +void __init usi_topkick_init(void)
> +{
> + /*
> + * Basic setup. Needs to be called early.
> + */
> + kirkwood_mpp_conf(topkick_mpp_config);
> +
> + /* SATA0 power enable */
> + gpio_set_value(TOPKICK_SATA0_PWR_ENABLE, 1);
It would be nice to be able to do that in DT. Does such a binding
already exist? Its something we need quite often in kirkwood, and i
guess other machines architectures as well.
> +
> + kirkwood_ehci_init();
> + kirkwood_ge00_init(&topkick_ge00_data);
> +}
How is the wifi device instantiated? Is it a PCIe device so it
auto-probed? Or is some explicit instantiation required, say if its an
SPI device?
It would be good to add this board to kirkwood_defconfig as well.
Andrew
^ permalink raw reply
* OMP35xx booting issue
From: Paul Walmsley @ 2012-10-20 7:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPjKCR9ymWpkUPvXePu5NkGTxVaE2HFv5wp24aGBocdZ6nJFzg@mail.gmail.com>
On Sat, 20 Oct 2012, Anil Kumar wrote:
> devkit8000 is booting with kernel 3.5 and no much diff
> in kernel 3.6/3.5 board files
>
> i am suspecting here
>
> omap_hsmmc omap_hsmmc.0: unable to obtain RX DMA engine channel 62
Have you tried using omap2plus_defconfig?
- Paul
^ permalink raw reply
* [PATCH 1/2] cpufreq: return early from __cpufreq_driver_getavg()
From: Viresh Kumar @ 2012-10-20 7:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKohponGwhC_zmk1Whq56vmZMvjcxXKiSpdvMk4ZU8z0Wa2TBw@mail.gmail.com>
Re-sending, as it bounced from the lists :(
When i reply to mail from my Samsung S2, it replies in HTML format.
Don't know how to fix it :)
On 20 October 2012 10:12, Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> On Oct 20, 2012 3:37 AM, "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
>>
>> On Saturday 20 of October 2012 01:42:05 Viresh Kumar wrote:
>> > There is no need to do cpufreq_get_cpu() and cpufreq_put_cpu() for
>> > drivers that
>> > don't support getavg() routine.
>> >
>> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>>
>> The patch doesn't seem to follow the changelog or the other way around.
>
> Sorry if my log isn't clear enough.
> But i could still see it matching the code :)
>
> I have moved the check for drivers capabilities at the top
> of routine, so that there is no need to call mentioned routines.
>
>>
>> Thanks,
>> Rafael
>>
>>
>> > ---
>> > drivers/cpufreq/cpufreq.c | 6 ++++--
>> > 1 file changed, 4 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
>> > index 85df538..f552d5f 100644
>> > --- a/drivers/cpufreq/cpufreq.c
>> > +++ b/drivers/cpufreq/cpufreq.c
>> > @@ -1511,12 +1511,14 @@ int __cpufreq_driver_getavg(struct
>> > cpufreq_policy *policy, unsigned int cpu)
>> > {
>> > int ret = 0;
>> >
>> > + if (!(cpu_online(cpu) && cpufreq_driver->getavg))
>> > + return 0;
>> > +
>> > policy = cpufreq_cpu_get(policy->cpu);
>> > if (!policy)
>> > return -EINVAL;
>> >
>> > - if (cpu_online(cpu) && cpufreq_driver->getavg)
>> > - ret = cpufreq_driver->getavg(policy, cpu);
>> > + ret = cpufreq_driver->getavg(policy, cpu);
>> >
>> > cpufreq_cpu_put(policy);
>> > return ret;
>> >
>> --
>> I speak only for myself.
>> Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply
* OMAP baseline test results for v3.7-rc1
From: Paul Walmsley @ 2012-10-20 6:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1210191645390.10773@utopia.booyaka.com>
Hi Kevin
On Fri, 19 Oct 2012, Paul Walmsley wrote:
> On Thu, 18 Oct 2012, Paul Walmsley wrote:
>
> > Here are some basic OMAP test results for Linux v3.7-rc1.
> > Logs and other details at http://www.pwsan.com/omap/testlogs/test_v3.7-rc1/
...
> > Failing tests: needing investigation
> > ------------------------------------
> >
...
> > PM tests:
>
> * 3730 Beagle XM: OPPs do not initialize
> - Several "find_device_opp: Invalid parameters" messages appear on boot;
> related warnings follow
> - Cause unknown
This one seems to be caused by this commit:
commit 24d7b40a60cf19008334bcbcbd98da374d4d9c64
Author: Kevin Hilman <khilman@ti.com>
Date: Thu Sep 6 14:03:08 2012 -0700
ARM: OMAP2+: PM: MPU DVFS: use generic CPU device for MPU-SS
Care to take a look at it and fix it?
- Paul
^ permalink raw reply
* OMAP baseline test results for v3.7-rc1
From: Paul Walmsley @ 2012-10-20 6:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1210191645390.10773@utopia.booyaka.com>
Hi Jean
On Fri, 19 Oct 2012, Paul Walmsley wrote:
> On Thu, 18 Oct 2012, Paul Walmsley wrote:
>
> > Here are some basic OMAP test results for Linux v3.7-rc1.
> > Logs and other details at http://www.pwsan.com/omap/testlogs/test_v3.7-rc1/
...
> > Failing tests: needing investigation
> > ------------------------------------
> >
> > Boot tests:
>
> * 3530ES3 Beagle: I2C timeouts during userspace init
> - May be related to the threaded IRQ conversion of the I2C driver
> - Unknown cause
This one turned out to be caused by:
commit 3db11feffc1ad2ab9dea27789e6b5b3032827adc
Author: Jean Pihet <jean.pihet@newoldbits.com>
Date: Thu Sep 20 18:08:03 2012 +0200
ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints
Reverting this commit causes the problem to go away, but since the OMAP PM
constraint code was removed as well, it's unlikely that a simple revert is
the right thing to do.
Jean could you please investigate and fix this?
- Paul
^ permalink raw reply
* [PATCH 1/2] cpufreq: return early from __cpufreq_driver_getavg()
From: Viresh Kumar @ 2012-10-20 4:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2737823.2JYE7UmLRN@vostro.rjw.lan>
On Oct 20, 2012 3:37 AM, "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
>
> On Saturday 20 of October 2012 01:42:05 Viresh Kumar wrote:
> > There is no need to do cpufreq_get_cpu() and cpufreq_put_cpu() for
drivers that
> > don't support getavg() routine.
> >
> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>
> The patch doesn't seem to follow the changelog or the other way around.
Sorry if my log isn't clear enough.
But i could still see it matching the code :)
I have moved the check for drivers capabilities at the top
of routine, so that there is no need to call mentioned routines.
>
> Thanks,
> Rafael
>
>
> > ---
> > drivers/cpufreq/cpufreq.c | 6 ++++--
> > 1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > index 85df538..f552d5f 100644
> > --- a/drivers/cpufreq/cpufreq.c
> > +++ b/drivers/cpufreq/cpufreq.c
> > @@ -1511,12 +1511,14 @@ int __cpufreq_driver_getavg(struct
cpufreq_policy *policy, unsigned int cpu)
> > {
> > int ret = 0;
> >
> > + if (!(cpu_online(cpu) && cpufreq_driver->getavg))
> > + return 0;
> > +
> > policy = cpufreq_cpu_get(policy->cpu);
> > if (!policy)
> > return -EINVAL;
> >
> > - if (cpu_online(cpu) && cpufreq_driver->getavg)
> > - ret = cpufreq_driver->getavg(policy, cpu);
> > + ret = cpufreq_driver->getavg(policy, cpu);
> >
> > cpufreq_cpu_put(policy);
> > return ret;
> >
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121020/6db37aed/attachment-0001.html>
^ permalink raw reply
* [PATCH 2/2] USB: doc: Binding document for ehci-platform driver
From: Tony Prisk @ 2012-10-20 3:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350703053-4661-1-git-send-email-linux@prisktech.co.nz>
Add a binding document for ehci-platform driver.
Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
.../devicetree/bindings/usb/ehci-platform.txt | 22 ++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 Documentation/devicetree/bindings/usb/ehci-platform.txt
diff --git a/Documentation/devicetree/bindings/usb/ehci-platform.txt b/Documentation/devicetree/bindings/usb/ehci-platform.txt
new file mode 100644
index 0000000..faeffe4
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ehci-platform.txt
@@ -0,0 +1,22 @@
+Generic Platform EHCI Controller
+-----------------------------------------------------
+
+Required properties:
+- compatible : "ehci-platform"
+- reg : Should contain 1 register ranges(address and length)
+- interrupts : EHCI controller interrupt
+
+Optional properties:
+- caps-offset : offset to the capabilities register (default = 0)
+- has-tt : controller has transaction translator(s).
+- big-endian-desc : descriptors are in big-endian format
+- big-endian-mmio : mmio is in big-endian format
+- has-synopsys-hc-bug : controller has the synopsys hc bug
+
+Example:
+ ehci at d8007c00 {
+ compatible = "ehci-platform";
+ reg = <0xd8007c00 0x200>;
+ interrupts = <43>;
+ has-tt;
+ };
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/2] USB: Update EHCI-platform driver to devicetree.
From: Tony Prisk @ 2012-10-20 3:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350703053-4661-1-git-send-email-linux@prisktech.co.nz>
This patch adds devicetree support to the EHCI-platform driver,
and removes the now unneeded ehci-vt8500.c
Existing platform properties are maintained, with the exception
the power_(on/off) and suspend function pointers.
Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
drivers/usb/host/ehci-hcd.c | 5 --
drivers/usb/host/ehci-platform.c | 46 ++++++++++
drivers/usb/host/ehci-vt8500.c | 171 --------------------------------------
3 files changed, 46 insertions(+), 176 deletions(-)
delete mode 100644 drivers/usb/host/ehci-vt8500.c
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 6bf6c42..42c8e84 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1274,11 +1274,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER cns3xxx_ehci_driver
#endif
-#ifdef CONFIG_ARCH_VT8500
-#include "ehci-vt8500.c"
-#define PLATFORM_DRIVER vt8500_ehci_driver
-#endif
-
#ifdef CONFIG_PLAT_SPEAR
#include "ehci-spear.c"
#define PLATFORM_DRIVER spear_ehci_hcd_driver
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 764e010..7f962dc 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -19,6 +19,7 @@
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include <linux/platform_device.h>
+#include <linux/of.h>
#include <linux/usb/ehci_pdriver.h>
static int ehci_platform_reset(struct usb_hcd *hcd)
@@ -78,14 +79,48 @@ static const struct hc_driver ehci_platform_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
+static u64 ehci_dma_mask = DMA_BIT_MASK(32);
+
static int __devinit ehci_platform_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct resource *res_mem;
struct usb_ehci_pdata *pdata = dev->dev.platform_data;
+ struct device_node *np = dev->dev.of_node;
int irq;
int err = -ENOMEM;
+ /* Are we being initialized from a DT-probed device? */
+ if (np) {
+ /*
+ * No platform data is being passed, so initalize pdata.
+ * Limitation: we can't support power_on, power_off or
+ * power_suspend function pointers from DT.
+ * TODO: The missing functions could be replaced with
+ * power sequence handlers.
+ */
+ pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
+ dev->dev.platform_data = pdata;
+
+ /* Read the optional properties from DT node */
+ of_property_read_u32(np, "caps-offset", &pdata->caps_offset);
+ if (of_property_read_bool(np, "has-tt"))
+ pdata->has_tt = 1;
+ if (of_property_read_bool(np, "has-synopsys-hc-bug"))
+ pdata->has_synopsys_hc_bug = 1;
+ if (of_property_read_bool(np, "big-endian-desc"))
+ pdata->big_endian_desc = 1;
+ if (of_property_read_bool(np, "big-endian-mmio"))
+ pdata->big_endian_mmio = 1;
+
+ /* Right now device-tree probed devices don't get dma_mask set.
+ * Since shared usb code relies on it, set it here for now.
+ * Once we have dma capability bindings this can go away.
+ */
+ if (!dev->dev.dma_mask)
+ dev->dev.dma_mask = &ehci_dma_mask;
+ }
+
if (!pdata) {
WARN_ON(1);
return -ENODEV;
@@ -215,6 +250,16 @@ static const struct platform_device_id ehci_platform_table[] = {
{ "ehci-platform", 0 },
{ }
};
+
+#ifdef CONFIG_OF
+static const struct of_device_id ehci_platform_ids[] = {
+ { .compatible = "ehci-platform", },
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, ehci_platform_ids);
+#endif
+
MODULE_DEVICE_TABLE(platform, ehci_platform_table);
static const struct dev_pm_ops ehci_platform_pm_ops = {
@@ -231,5 +276,6 @@ static struct platform_driver ehci_platform_driver = {
.owner = THIS_MODULE,
.name = "ehci-platform",
.pm = &ehci_platform_pm_ops,
+ .of_match_table = of_match_ptr(ehci_platform_ids),
}
};
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
deleted file mode 100644
index d3c9a3e..0000000
--- a/drivers/usb/host/ehci-vt8500.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * drivers/usb/host/ehci-vt8500.c
- *
- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * Based on ehci-au1xxx.c
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/of.h>
-#include <linux/platform_device.h>
-
-static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int rc = 0;
-
- if (!udev->parent) /* udev is root hub itself, impossible */
- rc = -1;
- /* we only support lpm device connected to root hub yet */
- if (ehci->has_lpm && !udev->parent->parent) {
- rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
- if (!rc)
- rc = ehci_lpm_check(ehci, udev->portnum);
- }
- return rc;
-}
-
-static const struct hc_driver vt8500_ehci_hc_driver = {
- .description = hcd_name,
- .product_desc = "VT8500 EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- */
- .reset = ehci_setup,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
-
- /*
- * scheduling support
- */
- .get_frame_number = ehci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- /*
- * call back when device connected and addressed
- */
- .update_device = ehci_update_device,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32);
-
-static int vt8500_ehci_drv_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct ehci_hcd *ehci;
- struct resource *res;
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- /*
- * Right now device-tree probed devices don't get dma_mask set.
- * Since shared usb code relies on it, set it here for now.
- * Once we have dma capability bindings this can go away.
- */
- if (!pdev->dev.dma_mask)
- pdev->dev.dma_mask = &vt8500_ehci_dma_mask;
-
- if (pdev->resource[1].flags != IORESOURCE_IRQ) {
- pr_debug("resource[1] is not IORESOURCE_IRQ");
- return -ENOMEM;
- }
- hcd = usb_create_hcd(&vt8500_ehci_hc_driver, &pdev->dev, "VT8500");
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (!hcd->regs) {
- pr_debug("ioremap failed");
- ret = -ENOMEM;
- goto err1;
- }
-
- ehci = hcd_to_ehci(hcd);
- ehci->caps = hcd->regs;
-
- ret = usb_add_hcd(hcd, pdev->resource[1].start,
- IRQF_SHARED);
- if (ret == 0) {
- platform_set_drvdata(pdev, hcd);
- return ret;
- }
-
-err1:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int vt8500_ehci_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static const struct of_device_id vt8500_ehci_ids[] = {
- { .compatible = "via,vt8500-ehci", },
- { .compatible = "wm,prizm-ehci", },
- {}
-};
-
-static struct platform_driver vt8500_ehci_driver = {
- .probe = vt8500_ehci_drv_probe,
- .remove = vt8500_ehci_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "vt8500-ehci",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(vt8500_ehci_ids),
- }
-};
-
-MODULE_ALIAS("platform:vt8500-ehci");
-MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
--
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