* [PATCH 4/4] irqchip: gic: Perform the gic_secondary_init() call via CPU notifier
From: Catalin Marinas @ 2013-01-25 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130125043039.GN13691@verge.net.au>
On Fri, Jan 25, 2013 at 04:30:39AM +0000, Simon Horman wrote:
> On Wed, Jan 23, 2013 at 05:59:34PM +0000, Catalin Marinas wrote:
> > All the calls to gic_secondary_init() pass 0 as the first argument.
> > Since this function is called on each CPU when starting, it can be done
> > in a platform-independent way via a CPU notifier registered by the GIC
> > code.
> >
> > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Russell King <linux@arm.linux.org.uk>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Kukjin Kim <kgene.kim@samsung.com>
> > Cc: Rob Herring <rob.herring@calxeda.com>
> > Cc: Sascha Hauer <kernel@pengutronix.de>
> > Cc: David Brown <davidb@codeaurora.org>
> > Cc: Daniel Walker <dwalker@fifo99.com>
> > Cc: Bryan Huntsman <bryanh@codeaurora.org>
> > Cc: Tony Lindgren <tony@atomide.com>
> > Cc: Simon Horman <horms@verge.net.au>
> > Cc: Magnus Damm <magnus.damm@gmail.com>
> > Cc: Dinh Nguyen <dinguyen@altera.com>
> > Cc: Viresh Kumar <viresh.linux@gmail.com>
> > Cc: Shiraz Hashim <shiraz.hashim@st.com>
> > Cc: Stephen Warren <swarren@wwwdotorg.org>
> > Cc: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
> > Cc: Linus Walleij <linus.walleij@linaro.org>
>
> mach-shmobile portion:
>
> Acked-by: Simon Horman <horms+renesas@verge.net.au>
>
> For the record, I tested this on the kzm9g, kzm9d and marzen boards
> which use the r8a7779, EMEV2 and r8a7779 SoCs respectively.
Thanks. Can I add a Tested-by as well?
--
Catalin
^ permalink raw reply
* [PATCH] ARM: OMAP2xxx: clock data: clean up unused null clocks
From: Paul Walmsley @ 2013-01-25 9:32 UTC (permalink / raw)
To: linux-arm-kernel
Remove some clocks that don't appear to be used by anything
and which are not associated with any hardware registers.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/cclock2420_data.c | 16 +---------------
arch/arm/mach-omap2/cclock2430_data.c | 16 +---------------
2 files changed, 2 insertions(+), 30 deletions(-)
diff --git a/arch/arm/mach-omap2/cclock2420_data.c b/arch/arm/mach-omap2/cclock2420_data.c
index 7e5febe..c3acd2d 100644
--- a/arch/arm/mach-omap2/cclock2420_data.c
+++ b/arch/arm/mach-omap2/cclock2420_data.c
@@ -622,15 +622,10 @@ static struct clk_hw_omap gpios_fck_hw = {
DEFINE_STRUCT_CLK(gpios_fck, gpios_fck_parent_names, aes_ick_ops);
-static struct clk wu_l4_ick;
-
-DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm");
-DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops);
-
static struct clk gpios_ick;
static const char *gpios_ick_parent_names[] = {
- "wu_l4_ick",
+ "sys_ck",
};
static struct clk_hw_omap gpios_ick_hw = {
@@ -1682,13 +1677,6 @@ static struct clk_hw_omap wdt1_ick_hw = {
DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops);
-static struct clk wdt1_osc_ck;
-
-static const struct clk_ops wdt1_osc_ck_ops = {};
-
-DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL);
-DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops);
-
static struct clk wdt3_fck;
static struct clk_hw_omap wdt3_fck_hw = {
@@ -1767,7 +1755,6 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "func_96m_ck", &func_96m_ck, CK_242X),
CLK(NULL, "func_48m_ck", &func_48m_ck, CK_242X),
CLK(NULL, "func_12m_ck", &func_12m_ck, CK_242X),
- CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_242X),
CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_242X),
CLK(NULL, "sys_clkout", &sys_clkout, CK_242X),
CLK(NULL, "sys_clkout2_src", &sys_clkout2_src, CK_242X),
@@ -1797,7 +1784,6 @@ static struct omap_clk omap2420_clks[] = {
/* L4 domain clocks */
CLK(NULL, "l4_ck", &l4_ck, CK_242X),
CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_242X),
- CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_242X),
/* virtual meta-group clock */
CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_242X),
/* general l4 interface ck, multi-parent functional clk */
diff --git a/arch/arm/mach-omap2/cclock2430_data.c b/arch/arm/mach-omap2/cclock2430_data.c
index eda079b..7560ec9 100644
--- a/arch/arm/mach-omap2/cclock2430_data.c
+++ b/arch/arm/mach-omap2/cclock2430_data.c
@@ -601,15 +601,10 @@ static struct clk_hw_omap gpios_fck_hw = {
DEFINE_STRUCT_CLK(gpios_fck, gpio5_fck_parent_names, aes_ick_ops);
-static struct clk wu_l4_ick;
-
-DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm");
-DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops);
-
static struct clk gpios_ick;
static const char *gpios_ick_parent_names[] = {
- "wu_l4_ick",
+ "sys_ck",
};
static struct clk_hw_omap gpios_ick_hw = {
@@ -1811,13 +1806,6 @@ static struct clk_hw_omap wdt1_ick_hw = {
DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops);
-static struct clk wdt1_osc_ck;
-
-static const struct clk_ops wdt1_osc_ck_ops = {};
-
-DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL);
-DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops);
-
static struct clk wdt4_fck;
static struct clk_hw_omap wdt4_fck_hw = {
@@ -1869,7 +1857,6 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X),
CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X),
CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X),
- CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_243X),
CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_243X),
CLK(NULL, "sys_clkout", &sys_clkout, CK_243X),
CLK(NULL, "emul_ck", &emul_ck, CK_243X),
@@ -1898,7 +1885,6 @@ static struct omap_clk omap2430_clks[] = {
/* L4 domain clocks */
CLK(NULL, "l4_ck", &l4_ck, CK_243X),
CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X),
- CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_243X),
/* virtual meta-group clock */
CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X),
/* general l4 interface ck, multi-parent functional clk */
--
1.7.10.4
^ permalink raw reply related
* [RESEND PATCH v5 3/7] usb: chipidea: add otg id switch and vbus connect/disconnect detect
From: Alexander Shishkin @ 2013-01-25 9:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130125062827.GD29795@nchen-desktop>
Peter Chen <peter.chen@freescale.com> writes:
> On Thu, Jan 24, 2013 at 05:25:17PM +0200, Alexander Shishkin wrote:
>> Peter Chen <peter.chen@freescale.com> writes:
>>
>> > The main design flow is the same with msm otg driver, that is the id and
>> > vbus interrupt are handled at core driver, others are handled by
>> > individual drivers.
>> >
>> > - At former design, when switch usb role from device->host, it will call
>> > udc_stop, it will remove the gadget driver, so when switch role
>> > from host->device, it can't add gadget driver any more.
>> > At new design, when role switch occurs, the gadget just calls
>> > usb_gadget_vbus_disconnect/usb_gadget_vbus_connect as well as
>> > reset controller, it will not free any device/gadget structure
>> >
>> > - Add vbus connect and disconnect to core interrupt handler, it can
>> > notify udc driver by calling usb_gadget_vbus_disconnect
>> > /usb_gadget_vbus_connect.
>> >
>> > Signed-off-by: Peter Chen <peter.chen@freescale.com>
>>
>> [snip]
>>
>> > @@ -483,6 +614,17 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>> > goto rm_wq;
>> > }
>> >
>> > + otgsc = hw_read(ci, OP_OTGSC, ~0);
>> > + /*
>> > + * if it is device mode:
>> > + * - Enable vbus detect
>> > + * - If it has already connected to host, notify udc
>> > + */
>> > + if (ci->role == CI_ROLE_GADGET) {
>> > + ci_enable_otg_interrupt(ci, OTGSC_BSVIE);
>> > + ci_handle_vbus_change(ci);
>> > + }
>> > +
>>
>> Actually, this doesn't work, neither here, nor in udc_start(), where the
>> next patch moves it. If you start in host role with A plug, unplug it,
>> plug B and load a gadget module,
>
> When we unplug A, device's role start will be called, that is
> udc_id_switch_for_device in my patch, it will enable vbus interrupt.
> Then, when we plug B, there will be an vbus interrupt, then the
> ci->vbus_active will be set, then when we load a gadget module,
> the enumeration will begin like I said at last email.
What doesn't happen is the reset into device mode (unless you have
_REGS_SHARED set, which by the way seems a bit misleading) and we're
still doing nothing till the vbus interrupt comes. So the REGS_SHARED is
the real problem in this case.
Now, looking at ci13xxx_{start,stop}(), I'm seeing some more code
duplication. What do think about something like this (untested):
---cut---
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index dcac77c..38446de 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1351,6 +1351,28 @@ static const struct usb_ep_ops usb_ep_ops = {
.fifo_flush = ep_fifo_flush,
};
+static int hw_device_connect(struct ci13xxx *ci, int connect)
+{
+ int ret;
+
+ if (connect) {
+ pm_runtime_get_sync(&ci->gadget.dev);
+ ret = hw_device_reset(ci, USBMODE_CM_DC);
+ hw_device_state(ci, ci->ep0out->qh.dma);
+ dev_dbg(ci->dev, "Connected to host\n");
+ } else {
+ hw_device_state(ci, 0);
+ if (ci->platdata->notify_event)
+ ci->platdata->notify_event(ci,
+ CI13XXX_CONTROLLER_STOPPED_EVENT);
+ ret = _gadget_stop_activity(&ci->gadget);
+ pm_runtime_put_sync(&ci->gadget.dev);
+ dev_dbg(ci->dev, "Disconnected from host\n");
+ }
+
+ return ret;
+}
+
/******************************************************************************
* GADGET block
*****************************************************************************/
@@ -1358,7 +1380,7 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
{
struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget);
unsigned long flags;
- int gadget_ready = 0;
+ int gadget_ready = 0, ret = 0;
spin_lock_irqsave(&ci->lock, flags);
ci->vbus_active = is_active;
@@ -1366,24 +1388,10 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
gadget_ready = 1;
spin_unlock_irqrestore(&ci->lock, flags);
- if (gadget_ready) {
- if (is_active) {
- pm_runtime_get_sync(&_gadget->dev);
- hw_device_reset(ci, USBMODE_CM_DC);
- hw_device_state(ci, ci->ep0out->qh.dma);
- dev_dbg(ci->dev, "Connected to host\n");
- } else {
- hw_device_state(ci, 0);
- if (ci->platdata->notify_event)
- ci->platdata->notify_event(ci,
- CI13XXX_CONTROLLER_STOPPED_EVENT);
- _gadget_stop_activity(&ci->gadget);
- pm_runtime_put_sync(&_gadget->dev);
- dev_dbg(ci->dev, "Disconnected from host\n");
- }
- }
+ if (gadget_ready)
+ ret = hw_device_connect(ci, is_active);
- return 0;
+ return ret;
}
static int ci13xxx_wakeup(struct usb_gadget *_gadget)
@@ -1546,20 +1554,9 @@ static int ci13xxx_start(struct usb_gadget *gadget,
spin_lock_irqsave(&ci->lock, flags);
ci->driver = driver;
- pm_runtime_get_sync(&ci->gadget.dev);
- if (ci->vbus_active) {
- if (ci->platdata->flags & CI13XXX_REGS_SHARED)
- hw_device_reset(ci, USBMODE_CM_DC);
- } else {
- pm_runtime_put_sync(&ci->gadget.dev);
- goto done;
- }
+ if (ci->vbus_active)
+ retval = hw_device_connect(ci, 1);
- retval = hw_device_state(ci, ci->ep0out->qh.dma);
- if (retval)
- pm_runtime_put_sync(&ci->gadget.dev);
-
- done:
spin_unlock_irqrestore(&ci->lock, flags);
return retval;
}
@@ -1572,24 +1569,18 @@ static int ci13xxx_stop(struct usb_gadget *gadget,
{
struct ci13xxx *ci = container_of(gadget, struct ci13xxx, gadget);
unsigned long flags;
+ int ret = 0;
spin_lock_irqsave(&ci->lock, flags);
if (ci->vbus_active) {
- hw_device_state(ci, 0);
- if (ci->platdata->notify_event)
- ci->platdata->notify_event(ci,
- CI13XXX_CONTROLLER_STOPPED_EVENT);
ci->driver = NULL;
spin_unlock_irqrestore(&ci->lock, flags);
- _gadget_stop_activity(&ci->gadget);
- spin_lock_irqsave(&ci->lock, flags);
- pm_runtime_put(&ci->gadget.dev);
- }
-
- spin_unlock_irqrestore(&ci->lock, flags);
+ ret = hw_device_connect(ci, 0);
+ } else
+ spin_unlock_irqrestore(&ci->lock, flags);
- return 0;
+ return ret;
}
/******************************************************************************
---cut---
That's on top of your patchset. Then, I notice there's a mess with
locking around _gadget_stop_activity(), but that's out of scope of this
patchset, of course.
> Ok, I say "fully tested" means I tested cases for my development, which
> includes: host/device is plugged during boots up, device/host switch,
> host only controller, load gadget before/next cable plugs in. If you
> think it is not enough, I will skip "fully" when sends next version patch.
Sounds good, but it makes sense to mention that it's fully tested on
imx.
Regards,
--
Alex
^ permalink raw reply related
* [PATCH V3] ARM: DTS: exynos5250-arndale: Add initial board support file
From: Tushar Behera @ 2013-01-25 9:44 UTC (permalink / raw)
To: linux-arm-kernel
From: Girish K S <ks.giri@samsung.com>
Arndale is a low cost board based on the Samsung Exynos5250 SoC. This
patch adds initial device tree support for this board.
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
Signed-off-by: Girish K S <ks.giri@samsung.com>
Signed-off-by: Tushar Behera <tushar.behera@linaro.org>
---
Changes for V3:
* Removed unused GPIO lines for dwmmc2.
Changes for V2:
* Addressed review comments from Sachin.
* Fixed GPIO numbers for dwmmc0 and dwmmc2.
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/exynos5250-arndale.dts | 122 ++++++++++++++++++++++++++++++
2 files changed, 123 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/boot/dts/exynos5250-arndale.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 5ebb44f..e21f27c 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
exynos4210-smdkv310.dtb \
exynos4210-trats.dtb \
exynos4412-smdk4412.dtb \
+ exynos5250-arndale.dtb \
exynos5250-smdk5250.dtb \
exynos5250-snow.dtb \
exynos5440-ssdk5440.dtb
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
new file mode 100644
index 0000000..63572f9
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -0,0 +1,122 @@
+/*
+ * Samsung's Exynos5250 based Arndale board device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+/include/ "exynos5250.dtsi"
+
+/ {
+ model = "Insignal Arndale evaluation board based on EXYNOS5250";
+ compatible = "insignal,arndale", "samsung,exynos5250";
+
+ memory {
+ reg = <0x40000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttySAC2,115200";
+ };
+
+ i2c at 12C60000 {
+ status = "disabled";
+ };
+
+ i2c at 12C70000 {
+ status = "disabled";
+ };
+
+ i2c at 12C80000 {
+ status = "disabled";
+ };
+
+ i2c at 12C90000 {
+ status = "disabled";
+ };
+
+ i2c at 12CA0000 {
+ status = "disabled";
+ };
+
+ i2c at 12CB0000 {
+ status = "disabled";
+ };
+
+ i2c at 12CC0000 {
+ status = "disabled";
+ };
+
+ i2c at 12CD0000 {
+ status = "disabled";
+ };
+
+ i2c at 121D0000 {
+ status = "disabled";
+ };
+
+ dwmmc_0: dwmmc0 at 12200000 {
+ num-slots = <1>;
+ supports-highspeed;
+ broken-cd;
+ fifo-depth = <0x80>;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+
+ slot at 0 {
+ reg = <0>;
+ bus-width = <8>;
+ gpios = <&gpc0 0 2 0 3>, <&gpc0 1 2 0 3>,
+ <&gpc0 3 2 3 3>, <&gpc0 4 2 3 3>,
+ <&gpc0 5 2 3 3>, <&gpc0 6 2 3 3>,
+ <&gpc1 0 2 3 3>, <&gpc1 1 2 3 3>,
+ <&gpc1 2 2 3 3>, <&gpc1 3 2 3 3>;
+ };
+ };
+
+ dwmmc_1: dwmmc1 at 12210000 {
+ status = "disabled";
+ };
+
+ dwmmc_2: dwmmc2 at 12220000 {
+ num-slots = <1>;
+ supports-highspeed;
+ fifo-depth = <0x80>;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+
+ slot at 0 {
+ reg = <0>;
+ bus-width = <4>;
+ samsung,cd-pinmux-gpio = <&gpc3 2 2 3 3>;
+ gpios = <&gpc3 0 2 0 3>, <&gpc3 1 2 0 3>,
+ <&gpc3 3 2 3 3>, <&gpc3 4 2 3 3>,
+ <&gpc3 5 2 3 3>, <&gpc3 6 2 3 3>;
+ };
+ };
+
+ dwmmc_3: dwmmc3 at 12230000 {
+ status = "disabled";
+ };
+
+ spi_0: spi at 12d20000 {
+ status = "disabled";
+ };
+
+ spi_1: spi at 12d30000 {
+ status = "disabled";
+ };
+
+ spi_2: spi at 12d40000 {
+ status = "disabled";
+ };
+};
--
1.7.4.1
^ permalink raw reply related
* [PATCH 00/10] rework gpio pxa driver for pinctrl
From: Linus Walleij @ 2013-01-25 9:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130123131503.GJ2239@intel.com>
On Wed, Jan 23, 2013 at 2:15 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Wed, Jan 23, 2013 at 01:27:23PM +0100, Linus Walleij wrote:
>> On Wed, Jan 23, 2013 at 9:25 AM, Haojian Zhuang
>> <haojian.zhuang@linaro.org> wrote:
>>
>> > Remove all cpu depend macro. Bind gpio pxa driver with pinctrl driver.
>>
>> Please route this patch series by Mika so he can test it on his
>> funny hardware too.
>
> The hardware we have is Intel Lynxpoint (a PCH chipset for Haswell which
> has x86 core). The only PXA based IP block it has is the SPI controller as
> far as I know. For GPIOs we have Intel own GPIO block, which is different
> than the PXA one (at least I think so, adding Mathias just in case).
>
> Not sure how it helps if I test this series on Lynxpoint :-)
Heheh sorry Mika there is too much PXA stuff happening right
now :-)
I admit I confused the GPIO for the SPI. I'll just go and apply
Haoijan's patches.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 01/10] gpio: pxa: set initcall level to module init
From: Linus Walleij @ 2013-01-25 9:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-2-git-send-email-haojian.zhuang@linaro.org>
On Wed, Jan 23, 2013 at 9:25 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> gpio & pinctrl driver are used together. The pinctrl driver is already
> launched before gpio driver in Makefile. So set gpio driver to module
> init level. Otherwise, the sequence will be inverted.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Applied to my devel branch.
Thanks!
Linus Walleij
^ permalink raw reply
* [V5 PATCH 24/26] usb: gadget: mv_udc: add device tree support
From: Mark Rutland @ 2013-01-25 9:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAK9wHMTVBRGf-mhnmzSKKGyuHKeXU7N8k2vTh9omkD4A0yhPsQ@mail.gmail.com>
On Fri, Jan 25, 2013 at 02:13:54AM +0000, chao xie wrote:
> 2013/1/24 Mark Rutland <mark.rutland@arm.com>:
> > Hello,
> >
> > On Thu, Jan 24, 2013 at 06:38:48AM +0000, Chao Xie wrote:
> >> In original driver, we have callbacks in platform data, and some
> >> dynamically allocations variables in platform data.
> >> Now, these blocks are removed, the device tree support is easier
> >> now.
> >
> > Please could you also add a binding document? See
> > Documentation/devicetree/bindings/usb for examples of existing bindings.
> >
> > Also, please Cc devicetree-discuss when introducing a new binding as you are
> > doing here.
> >
> >>
> >> Signed-off-by: Chao Xie <chao.xie@marvell.com>
> >> ---
> >> drivers/usb/gadget/mv_udc.h | 5 +-
> >> drivers/usb/gadget/mv_udc_core.c | 106 ++++++++++++++++++++++++++++++--------
> >> 2 files changed, 86 insertions(+), 25 deletions(-)
> >>
> >> diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/mv_udc.h
> >> index 50ae7c7..de84722 100644
> >> --- a/drivers/usb/gadget/mv_udc.h
> >> +++ b/drivers/usb/gadget/mv_udc.h
> >> @@ -179,6 +179,7 @@ struct mv_udc {
> >> int irq;
> >>
> >> unsigned int extern_attr;
> >> + unsigned int mode;
> >> struct notifier_block notifier;
> >>
> >> struct mv_cap_regs __iomem *cap_regs;
> >> @@ -222,11 +223,9 @@ struct mv_udc {
> >> struct mv_usb2_phy *phy;
> >> struct usb_phy *transceiver;
> >>
> >> - struct mv_usb_platform_data *pdata;
> >> -
> >> /* some SOC has mutiple clock sources for USB*/
> >> unsigned int clknum;
> >> - struct clk *clk[0];
> >> + struct clk **clk;
> >> };
> >>
> >> /* endpoint data structure */
> >> diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c
> >> index 2e5907f..a4ee9a1 100644
> >> --- a/drivers/usb/gadget/mv_udc_core.c
> >> +++ b/drivers/usb/gadget/mv_udc_core.c
> >> @@ -34,6 +34,7 @@
> >> #include <linux/irq.h>
> >> #include <linux/platform_device.h>
> >> #include <linux/clk.h>
> >> +#include <linux/of.h>
> >> #include <linux/platform_data/mv_usb.h>
> >> #include <linux/usb/mv_usb2.h>
> >> #include <asm/unaligned.h>
> >> @@ -2153,21 +2154,57 @@ static int mv_udc_remove(struct platform_device *pdev)
> >> return 0;
> >> }
> >>
> >> +static int mv_udc_parse_dt(struct platform_device *pdev,
> >> + struct mv_udc *udc)
> >> +{
> >> + struct device_node *np = pdev->dev.of_node;
> >> + unsigned int clks_num;
> >> + int i, ret;
> >> + const char *clk_name;
> >> +
> >> + if (!np)
> >> + return 1;
> >> +
> >> + clks_num = of_property_count_strings(np, "clocks");
> >> + if (clks_num < 0)
> >> + return clks_num;
> >> +
> >> + udc->clk = devm_kzalloc(&pdev->dev,
> >> + sizeof(struct clk *) * clks_num, GFP_KERNEL);
> >> + if (udc->clk == NULL)
> >> + return -ENOMEM;
> >> +
> >> + for (i = 0; i < clks_num; i++) {
> >> + ret = of_property_read_string_index(np, "clocks", i,
> >> + &clk_name);
> >> + if (ret)
> >> + return ret;
> >> + udc->clk[i] = devm_clk_get(&pdev->dev, clk_name);
> >> + if (IS_ERR(udc->clk[i]))
> >> + return PTR_ERR(udc->clk[i]);
> >
> > I was going to ask if you couldn't use of_clk_get, but I see you want to use
> > the devm_* functions to handle cleanup. It seems a shame there's not a standard
> > devm_of_clk_get.
> >
> It is nice to have someone to review the device tree part patches.
> In fact main target of the modification is to remove the
> pointers/callbacks in the platform_data, so
> i can easly to add device tree support.
>
> of_clk_get is is based on CONFIG_COMMON_CLK. of_clk_get is not simple.
> The orginal way we use to
> get a clock used two arguments: dev_id and con_id. The dev_id is the
> name of the device.
> of_clk_get need clock framework changes. It means that clock driver
> need add device tree support. Now
> we are doing the clock tree support for Marvell MMP SOCes, but it will
> not be done in a short time.
> As i think, of_clk_get still have some problems. It parses the
> property's name as "clocks", but it does not support
> mutipile clocks. If the device driver original has two clocks, the old
> way can do it as
> clk_get(dev, "clock 1");
> clk_get(dev, "clock 2");
> of_clk_get can not do it. I have not asked this question in the
> mailist, and i will do it soon.
I may have misunderstood here, but as far as I can see, of_clk_get supports
multiple clocks -- it even takes an index parameter:
struct clk *of_clk_get(struct device_node *np, int index)
I can see several dts files which have a clocks property with multiple clocks.
In arch/arm/boot/dts/vexpress-v2m.dtsi there's a "arm,sp810" node with
multiple clocks, which I believe is dealt with by vexpress_clk_of_init in
drivers/clk/versatile/clk-vexpress.c (though this uses of_clk_get_by_name).
This also raises the issue that you expect the clocks property to be a list of
strings, while other bindings expect the clocks property to be list of
phandle/clock-specifier pairs.
It's worth taking a look at:
Documentation/devicetree/bindings/clock/clock-bindings.txt
Going against the common convention here is a very bad idea.
>
> >> + }
> >> +
> >> + udc->clknum = clks_num;
> >> +
> >> + ret = of_property_read_u32(np, "extern_attr", &udc->extern_attr);
> >> + if (ret)
> >> + return ret;
> >
> > This looks like a *very* bad idea. The udc::extern_attr field seems to be a set
> > of flags, which this could reads in directly (without any sanity checking),
> > effectively making it an undocumented ABI. This might be better as a set of
> > valueless properties.
> >
> > Will unsigned int be the same as u32 on all platforms this could be used on?
> > If not, you're passing the wrong type into of_property_read_u32.
> >
> > Additionally, in devicetree, '-' is used in preference of '_' in compatible
> > and property names.
> >
> I see. So what you mean is if the extern_attr has two flags, FLAG_A and FLAG_B,
> i need add two boolean properties Property_FLAG_A and Property_FLAG_B?
Something like that. The properties might not map directly to flags - it's
better to describe the hardware reason these flags are required rather than
what these falgs do to linux.
>
> >> +
> >> + ret = of_property_read_u32(np, "mode", &udc->mode);
> >> + if (ret)
> >> + return ret;
> >
> > If I've understood correctly, this property will either be MV_USB_MODE_OTG (0)
> > or MV_USB_MODE_OTG (1). Again, I don't think this is good to be exported as an
> > ABI, especially as nothing in the enum definition points out that this affects
> > anything outside the kernel.
> >
> > If this isn't something that wants to be changed at runtime, this should
> > probably be a string property, with "host" and "otg" as valid values. Looking
> > in Documentation/devicetree, the nvidia,tegra20-ehci binding uses similar
> > strings in its dr_mode property. There may be other (undocumented) precedents.
> >
> Thanks. I will check the examples, and change it.
:)
>
> >> +
> >> + return 0;
> >> +}
> >> +
> >> static int mv_udc_probe(struct platform_device *pdev)
> >> {
> >> - struct mv_usb_platform_data *pdata = pdev->dev.platform_data;
> >> struct mv_udc *udc;
> >> int retval = 0;
> >> - int clk_i = 0;
> >> struct resource *r;
> >> size_t size;
> >>
> >> - if (pdata == NULL) {
> >> - dev_err(&pdev->dev, "missing platform_data\n");
> >> - return -ENODEV;
> >> - }
> >> -
> >> - size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum;
> >> + size = sizeof(*udc);
> >> udc = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
> >> if (udc == NULL) {
> >> dev_err(&pdev->dev, "failed to allocate memory for udc\n");
> >> @@ -2175,14 +2212,43 @@ static int mv_udc_probe(struct platform_device *pdev)
> >> }
> >>
> >> udc->done = &release_done;
> >> - udc->extern_attr = pdata->extern_attr;
> >> - udc->pdata = pdev->dev.platform_data;
> >> spin_lock_init(&udc->lock);
> >>
> >> udc->dev = pdev;
> >>
> >> + retval = mv_udc_parse_dt(pdev, udc);
> >> + if (retval > 0) {
> >> + /* no CONFIG_OF */
> >> + struct mv_usb_platform_data *pdata = pdev->dev.platform_data;
> >> + int clk_i = 0;
> >> +
> >> + if (pdata == NULL) {
> >> + dev_err(&pdev->dev, "missing platform_data\n");
> >> + return -ENODEV;
> >> + }
> >> + udc->extern_attr = pdata->extern_attr;
> >> + udc->mode = pdata->mode;
> >> + udc->clknum = pdata->clknum;
> >> +
> >> + size = sizeof(struct clk *) * udc->clknum;
> >> + udc->clk = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
> >> + if (udc->clk == NULL)
> >> + return -ENOMEM;
> >> + for (clk_i = 0; clk_i < udc->clknum; clk_i++) {
> >> + udc->clk[clk_i] = devm_clk_get(&pdev->dev,
> >> + pdata->clkname[clk_i]);
> >> + if (IS_ERR(udc->clk[clk_i])) {
> >> + retval = PTR_ERR(udc->clk[clk_i]);
> >> + return retval;
> >
> > Why not just return PTR_ERR(udc->clk[clk_i]); ?
> >
> sure. i will change it.
>
> >> + }
> >> + }
> >> + } else if (retval < 0) {
> >> + dev_err(&pdev->dev, "error parse dt\n");
> >> + return retval;
> >> + }
> >> +
> >> #ifdef CONFIG_USB_OTG_UTILS
> >> - if (pdata->mode == MV_USB_MODE_OTG) {
> >> + if (udc->mode == MV_USB_MODE_OTG) {
> >> udc->transceiver = devm_usb_get_phy(&pdev->dev,
> >> USB_PHY_TYPE_USB2);
> >> if (IS_ERR_OR_NULL(udc->transceiver)) {
> >> @@ -2191,17 +2257,6 @@ static int mv_udc_probe(struct platform_device *pdev)
> >> }
> >> }
> >> #endif
> >> -
> >> - udc->clknum = pdata->clknum;
> >> - for (clk_i = 0; clk_i < udc->clknum; clk_i++) {
> >> - udc->clk[clk_i] = devm_clk_get(&pdev->dev,
> >> - pdata->clkname[clk_i]);
> >> - if (IS_ERR(udc->clk[clk_i])) {
> >> - retval = PTR_ERR(udc->clk[clk_i]);
> >> - return retval;
> >> - }
> >> - }
> >> -
> >> r = platform_get_resource(udc->dev, IORESOURCE_MEM, 0);
> >> if (r == NULL) {
> >> dev_err(&pdev->dev, "no I/O memory resource defined\n");
> >> @@ -2466,6 +2521,12 @@ static void mv_udc_shutdown(struct platform_device *pdev)
> >> mv_udc_disable(udc);
> >> }
> >>
> >> +static struct of_device_id mv_udc_dt_ids[] = {
> >> + { .compatible = "mrvl,mv-udc" },
> >
> > This compatible string should be listed in the binding document you generate to
> > accompany this.
> >
> I see. i will add the documents at the device tree directory.
> I will seperate the device tree part patches from the other patches. Thanks.
Great!
Thanks,
Mark.
^ permalink raw reply
* [PATCH 02/10] gpio: pxa: identify ed mask reg with platform data
From: Linus Walleij @ 2013-01-25 9:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-3-git-send-email-haojian.zhuang@linaro.org>
On Wed, Jan 23, 2013 at 9:25 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> Avoid to judge whether edge mask register exists by CPU. Use platform
> data to identify it instead. The gpio edge mask register exists in MMP
> series SoC.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
ARM SoC folks: do you approve (ACK) this patch so I
can apply it to my GPIO tree?
It looks allright to me, I just want to know so that there are no
huge changes around this code in the ARM SoC tree that will
cause trouble.
Yours,
Linus Walleij
^ permalink raw reply
* [V5 PATCH 26/26] usb: ehci: ehci-mv: add device tree support
From: Mark Rutland @ 2013-01-25 9:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAK9wHMQF6UYpc-TVxh1ot9hgmErFfvhFGuPLNQn1CfaMcsnD-A@mail.gmail.com>
[...]
> >> @@ -170,19 +202,36 @@ static int mv_ehci_probe(struct platform_device *pdev)
> >> }
> >>
> >> platform_set_drvdata(pdev, ehci_mv);
> >> - ehci_mv->pdata = pdata;
> >> ehci_mv->hcd = hcd;
> >>
> >> - ehci_mv->clknum = pdata->clknum;
> >> - for (clk_i = 0; clk_i < ehci_mv->clknum; clk_i++) {
> >> - ehci_mv->clk[clk_i] =
> >> - devm_clk_get(&pdev->dev, pdata->clkname[clk_i]);
> >> - if (IS_ERR(ehci_mv->clk[clk_i])) {
> >> - dev_err(&pdev->dev, "error get clck \"%s\"\n",
> >> - pdata->clkname[clk_i]);
> >> - retval = PTR_ERR(ehci_mv->clk[clk_i]);
> >> - goto err_clear_drvdata;
> >> + retval = mv_ehci_parse_dt(pdev, ehci_mv);
> >> + if (retval > 0) {
> >
> > Is this why you returned 1 from mv_ehci_parse_dt? So you only do this if you
> > don't have a dt node?
> >
> > If so, why not rip the check (and positive error code) out of mv_ehci_parse_dt,
> > and then here:
> >
> > if (pdev->dev.of_node) {
> > retval = mv_ehci_parse_dt(pdev, ehci_mv);
> > } else
> > fall back to mv_usb_platform_data ...
> > }
> >
> > That makes it obvious that one side depends on dt and the other's a fallback,
> > and doesn't rely on nonstandard return code behaviour.
> >
>
> I will change it.
>
> > Also, why not return immediately if mv_ehci_parse_dt fails?
> >
> I do not understand. if mv_ehci_parse_dt returns negative value, the
> probe will be finished immediately.
Yes, you're right. I got myself confused about the logic.
Thanks,
Mark.
^ permalink raw reply
* [PATCH 02/10] gpio: pxa: identify ed mask reg with platform data
From: Linus Walleij @ 2013-01-25 9:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACRpkdYnMhWYy_FGrJs+=DN7od08nk5eeansPNaq9nxhm61-=A@mail.gmail.com>
On Fri, Jan 25, 2013 at 10:54 AM, Linus Walleij
<linus.walleij@linaro.org> wrote:
> On Wed, Jan 23, 2013 at 9:25 AM, Haojian Zhuang
> <haojian.zhuang@linaro.org> wrote:
>
>> Avoid to judge whether edge mask register exists by CPU. Use platform
>> data to identify it instead. The gpio edge mask register exists in MMP
>> series SoC.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>
> ARM SoC folks: do you approve (ACK) this patch so I
> can apply it to my GPIO tree?
>
> It looks allright to me, I just want to know so that there are no
> huge changes around this code in the ARM SoC tree that will
> cause trouble.
Actually this goes for the whole series.
It touches a lot of code in arch/arm/*
Haoijan, do you prefer if ACK it so you can take it up through
ARM SoC?
I'm OK to take it all through my GPIO tree as well if the
ARM people ACK them.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 0/3] ARM: shmobile: sh-eth pins in DT for armadillo800eva
From: Laurent Pinchart @ 2013-01-25 9:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130125090544.GD30990@verge.net.au>
Hi Simon,
On Friday 25 January 2013 18:05:44 Simon Horman wrote:
> On Fri, Jan 25, 2013 at 09:09:54AM +0100, Guennadi Liakhovetski wrote:
> > On Fri, 25 Jan 2013, Simon Horman wrote:
> > > On Thu, Jan 24, 2013 at 05:07:30PM +0100, Guennadi Liakhovetski wrote:
> > > > This patch series gets rid of gpio_request()-style ethernet pin
> > > > configuration on armadillo800eva in reference implementation.
> > >
> > > Hi Guennadi,
> > >
> > > these changes seem to be reasonable to me.
> > >
> > > Are there any dependencies for the sh_eth patch?
> > > I assume this will be handled by David Miller through the net-next tree.
> > > Are there any dependencies? The last time I checked the DT bindings
> > > for sh_eth had not been merged.
> >
> > Obviously, it can only be applied, if the
> > Documentation/devicetree/bindings/net/sh_ether.txt file and the
> > sh_eth_parse_dt() function exist. Also, if there are no objections against
> > the new phy-reset-gpios DT property. Otherwise there are no dependencies -
> > as long as the phy-reset-gpios property isn't found in DT, the patch
> > doesn't affect the driver.
>
> Thanks, I'm slightly concerned that the other patch(es) relating
> to Documentation/devicetree/bindings/net/sh_ether.txt have gone missing in
> action.
>
> Do you have an interest in chasing them down or would you like me to?
>
> > > For the remaining two patches, which I assume will go through my renesas
> > > tree:
> > > * Are there any dependencies that aren't satisfied by the of-intc
> > > branch?
> >
> > AFAICS, that your branch doesn't contain Laurent's pinctrl patches, which
> > are needed for patch 1 to apply and for patch 3 to make sense. My earlier
> > MMC DT / pinctrl patches aren't required for these patches to function,
> > but these patches won't apply cleanly without them, since they touch the
> > same code fragments. So, it would be easier to merge them in the order of
> > submission.
> >
> > > * Could you get some Acks. At least from Laurent?
> >
> > Sure, let's give reviewers some more time :)
>
> Indeed.
>
> Laurent, if there are patches ready for me to take into the renesas tree
> please let me know. I'm reluctant to add any more pinmux changes for 3.9.
> But if a topic branch would help let me know.
I'd like the gpio_request_one() patches to go to v3.9 if possible. The other
pinctrl patches will need to wait until v3.10 I'm afraid.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH 04/10] gpio: pxa: use platform data for gpio inverted
From: Linus Walleij @ 2013-01-25 9:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-5-git-send-email-haojian.zhuang@linaro.org>
On Wed, Jan 23, 2013 at 9:25 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> Avoid to judge whether gpio is inverted by identifying cpu in gpio
> driver. Move this into platform data of gpio driver.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
(...)
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -71,6 +71,7 @@ struct pxa_gpio_chip {
> struct gpio_chip chip;
> void __iomem *regbase;
> unsigned int irq_base;
> + unsigned int inverted;
> char label[10];
I would use bool for this.
(No big deal, but if you want to nitpick..)
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 02/10] gpio: pxa: identify ed mask reg with platform data
From: Haojian Zhuang @ 2013-01-25 10:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACRpkdb8iQiSJZKe5ViGc08LJP686KmP2J8Z=GsbhjYkyvXF_g@mail.gmail.com>
On Fri, Jan 25, 2013 at 5:57 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Fri, Jan 25, 2013 at 10:54 AM, Linus Walleij
> <linus.walleij@linaro.org> wrote:
>> On Wed, Jan 23, 2013 at 9:25 AM, Haojian Zhuang
>> <haojian.zhuang@linaro.org> wrote:
>>
>>> Avoid to judge whether edge mask register exists by CPU. Use platform
>>> data to identify it instead. The gpio edge mask register exists in MMP
>>> series SoC.
>>>
>>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>>
>> ARM SoC folks: do you approve (ACK) this patch so I
>> can apply it to my GPIO tree?
>>
>> It looks allright to me, I just want to know so that there are no
>> huge changes around this code in the ARM SoC tree that will
>> cause trouble.
>
> Actually this goes for the whole series.
>
> It touches a lot of code in arch/arm/*
>
> Haoijan, do you prefer if ACK it so you can take it up through
> ARM SoC?
>
> I'm OK to take it all through my GPIO tree as well if the
> ARM people ACK them.
>
I'm fine to merge into gpio git tree.
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
^ permalink raw reply
* [PATCH 05/10] gpio: pxa: remove gpio_type
From: Linus Walleij @ 2013-01-25 10:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358929554-32265-6-git-send-email-haojian.zhuang@linaro.org>
On Wed, Jan 23, 2013 at 9:25 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> Since gpio_type is used to check whether gafr register is valid. So
> move it into platform data.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
(...)
> +++ b/drivers/gpio/gpio-pxa.c
> @@ -72,6 +72,7 @@ struct pxa_gpio_chip {
> void __iomem *regbase;
> unsigned int irq_base;
> unsigned int inverted;
> + unsigned int gafr;
> char label[10];
Also looks like some kind of a bool.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 0/3] leds-pwm: Defer PWM calls if PWM can sleep
From: Florian Vaussard @ 2013-01-25 10:01 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
When using the leds-pwm module with external PWM chips connected through
I2C, the kernel will panic when settings a trigger. In this case, PWM
calls can sleep, and should be deferred.
Patch 1 and 2 add the necessary API to the PWM subsystem, and update
matching drivers.
Patch 3 updates leds-pwm to use a worker if the PWM chip can sleep, or performs
direct calls otherwise.
This patchset is based on the for-next branch of the led subsystem [1],
as patch 3 depends on the recent work of Peter for DT bindings in leds-pwm.
The pwm patches should probably follow the same path.
Tested on Overo (OMAP3 + TWL4030) with device tree.
Best regards,
Florian
[1] git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git
Florian Vaussard (3):
pwm: Add pwm_cansleep() as exported API to users
pwm: Add can_sleep property to drivers
leds: leds-pwm: Defer led_pwm_set() if PWM can sleep
drivers/leds/leds-pwm.c | 45 +++++++++++++++++++++++++++++++++++++++------
drivers/pwm/core.c | 12 ++++++++++++
drivers/pwm/pwm-twl-led.c | 1 +
drivers/pwm/pwm-twl.c | 1 +
include/linux/pwm.h | 10 ++++++++++
5 files changed, 63 insertions(+), 6 deletions(-)
--
1.7.5.4
^ permalink raw reply
* [PATCH 1/3] pwm: Add pwm_cansleep() as exported API to users
From: Florian Vaussard @ 2013-01-25 10:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359108114-16998-1-git-send-email-florian.vaussard@epfl.ch>
Calls to some external PWM chips can sleep. To help users,
add pwm_cansleep() API.
Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
drivers/pwm/core.c | 12 ++++++++++++
include/linux/pwm.h | 10 ++++++++++
2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 4a13da4..f49bfa6 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -763,6 +763,18 @@ void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
}
EXPORT_SYMBOL_GPL(devm_pwm_put);
+/**
+ * pwm_can_sleep() - report whether pwm access will sleep
+ * @pwm: PWM device
+ *
+ * It returns nonzero if accessing the PWM can sleep.
+ */
+int pwm_can_sleep(struct pwm_device *pwm)
+{
+ return pwm->chip->can_sleep;
+}
+EXPORT_SYMBOL_GPL(pwm_can_sleep);
+
#ifdef CONFIG_DEBUG_FS
static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
{
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 70655a2..2aee75d 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -146,6 +146,8 @@ struct pwm_ops {
* @base: number of first PWM controlled by this chip
* @npwm: number of PWMs controlled by this chip
* @pwms: array of PWM devices allocated by the framework
+ * @can_sleep: flag must be set iff config()/enable()/disable() methods sleep,
+ * as they must while accessing PWM chips over I2C or SPI
*/
struct pwm_chip {
struct device *dev;
@@ -159,6 +161,7 @@ struct pwm_chip {
struct pwm_device * (*of_xlate)(struct pwm_chip *pc,
const struct of_phandle_args *args);
unsigned int of_pwm_n_cells;
+ unsigned int can_sleep:1;
};
#if IS_ENABLED(CONFIG_PWM)
@@ -182,6 +185,8 @@ struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id);
struct pwm_device *devm_of_pwm_get(struct device *dev, struct device_node *np,
const char *con_id);
void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
+
+int pwm_can_sleep(struct pwm_device *pwm);
#else
static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
{
@@ -242,6 +247,11 @@ static inline struct pwm_device *devm_of_pwm_get(struct device *dev,
static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
{
}
+
+static inline int pwm_can_sleep(struct pwm_device *pwm)
+{
+ return -EINVAL;
+}
#endif
struct pwm_lookup {
--
1.7.5.4
^ permalink raw reply related
* [PATCH 2/3] pwm: Add can_sleep property to drivers
From: Florian Vaussard @ 2013-01-25 10:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359108114-16998-1-git-send-email-florian.vaussard@epfl.ch>
Calls to PWM drivers connected through I2C can sleep.
Use the new can_sleep property.
Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
drivers/pwm/pwm-twl-led.c | 1 +
drivers/pwm/pwm-twl.c | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/pwm/pwm-twl-led.c b/drivers/pwm/pwm-twl-led.c
index 9dfa0f3..6261193 100644
--- a/drivers/pwm/pwm-twl-led.c
+++ b/drivers/pwm/pwm-twl-led.c
@@ -300,6 +300,7 @@ static int twl_pwmled_probe(struct platform_device *pdev)
twl->chip.dev = &pdev->dev;
twl->chip.base = -1;
+ twl->chip.can_sleep = 1;
mutex_init(&twl->mutex);
diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c
index e65db95..4e56cd8 100644
--- a/drivers/pwm/pwm-twl.c
+++ b/drivers/pwm/pwm-twl.c
@@ -315,6 +315,7 @@ static int twl_pwm_probe(struct platform_device *pdev)
twl->chip.dev = &pdev->dev;
twl->chip.base = -1;
twl->chip.npwm = 2;
+ twl->chip.can_sleep = 1;
mutex_init(&twl->mutex);
--
1.7.5.4
^ permalink raw reply related
* [PATCH 3/3] leds: leds-pwm: Defer led_pwm_set() if PWM can sleep
From: Florian Vaussard @ 2013-01-25 10:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359108114-16998-1-git-send-email-florian.vaussard@epfl.ch>
Call to led_pwm_set() can happen inside atomic context, like triggers.
If the PWM call can sleep, defer using a worker.
Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
drivers/leds/leds-pwm.c | 45 +++++++++++++++++++++++++++++++++++++++------
1 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index a1ea5f6..1ffb6ba 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -23,12 +23,15 @@
#include <linux/pwm.h>
#include <linux/leds_pwm.h>
#include <linux/slab.h>
+#include <linux/workqueue.h>
struct led_pwm_data {
struct led_classdev cdev;
struct pwm_device *pwm;
+ struct work_struct work;
unsigned int active_low;
unsigned int period;
+ int duty;
};
struct led_pwm_priv {
@@ -36,6 +39,20 @@ struct led_pwm_priv {
struct led_pwm_data leds[0];
};
+static void led_pwm_work(struct work_struct *work)
+{
+ struct led_pwm_data *led_dat =
+ container_of(work, struct led_pwm_data, work);
+ int new_duty = led_dat->duty;
+
+ pwm_config(led_dat->pwm, new_duty, led_dat->period);
+
+ if (new_duty == 0)
+ pwm_disable(led_dat->pwm);
+ else
+ pwm_enable(led_dat->pwm);
+}
+
static void led_pwm_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
@@ -43,13 +60,23 @@ static void led_pwm_set(struct led_classdev *led_cdev,
container_of(led_cdev, struct led_pwm_data, cdev);
unsigned int max = led_dat->cdev.max_brightness;
unsigned int period = led_dat->period;
+ int duty;
- if (brightness == 0) {
- pwm_config(led_dat->pwm, 0, period);
- pwm_disable(led_dat->pwm);
+ if (brightness == 0)
+ duty = 0;
+ else
+ duty = brightness * period / max;
+
+ if (pwm_can_sleep(led_dat->pwm)) {
+ led_dat->duty = duty;
+ schedule_work(&led_dat->work);
} else {
- pwm_config(led_dat->pwm, brightness * period / max, period);
- pwm_enable(led_dat->pwm);
+ pwm_config(led_dat->pwm, duty, period);
+
+ if (duty == 0)
+ pwm_disable(led_dat->pwm);
+ else
+ pwm_enable(led_dat->pwm);
}
}
@@ -100,6 +127,8 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
led_dat->cdev.brightness = LED_OFF;
led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+ INIT_WORK(&led_dat->work, led_pwm_work);
+
ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
if (ret < 0) {
dev_err(&pdev->dev, "failed to register for %s\n",
@@ -153,6 +182,8 @@ static int led_pwm_probe(struct platform_device *pdev)
led_dat->cdev.max_brightness = cur_led->max_brightness;
led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+ INIT_WORK(&led_dat->work, led_pwm_work);
+
ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
if (ret < 0)
goto err;
@@ -180,8 +211,10 @@ static int led_pwm_remove(struct platform_device *pdev)
struct led_pwm_priv *priv = platform_get_drvdata(pdev);
int i;
- for (i = 0; i < priv->num_leds; i++)
+ for (i = 0; i < priv->num_leds; i++) {
led_classdev_unregister(&priv->leds[i].cdev);
+ cancel_work_sync(&priv->leds[i].work);
+ }
return 0;
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 5/5] wlcore: move wl12xx_platform_data up and make it truly optional
From: Luciano Coelho @ 2013-01-25 10:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358952038-5982-6-git-send-email-coelho@ti.com>
The platform data is used not only by wlcore-based drivers, but also
by wl1251. Move it up in the directory hierarchy to reflect this.
Additionally, make it truly optional. At the moment, disabling
platform data while wl1251_sdio or wlcore_sdio are enabled doesn't
work, but it will be necessary when device tree support is
implemented.
Signed-off-by: Luciano Coelho <coelho@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
In v2:
* Fix ti/Makefile
* Modify board_omap3evm.c which was still using the old Kconfig define
Tony, is it okay if I add this change in the omap3evm board in this
patch and queue it via wireless so that the whole thing is in sync?
arch/arm/mach-omap2/board-omap3evm.c | 10 +++++-----
drivers/net/wireless/ti/Kconfig | 9 +++++++++
drivers/net/wireless/ti/Makefile | 4 +++-
.../wl12xx_platform_data.c => wilink_platform_data.c} | 0
drivers/net/wireless/ti/wlcore/Kconfig | 5 -----
drivers/net/wireless/ti/wlcore/Makefile | 3 ---
include/linux/wl12xx.h | 14 +++++++++++---
7 files changed, 28 insertions(+), 17 deletions(-)
rename drivers/net/wireless/ti/{wlcore/wl12xx_platform_data.c => wilink_platform_data.c} (100%)
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 3985f35..a4ca63b 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -309,7 +309,7 @@ static struct omap2_hsmmc_info mmc[] = {
.gpio_wp = 63,
.deferred = true,
},
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_WILINK_PLATFORM_DATA
{
.name = "wl1271",
.mmc = 2,
@@ -450,7 +450,7 @@ static struct regulator_init_data omap3evm_vio = {
.consumer_supplies = omap3evm_vio_supply,
};
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_WILINK_PLATFORM_DATA
#define OMAP3EVM_WLAN_PMENA_GPIO (150)
#define OMAP3EVM_WLAN_IRQ_GPIO (149)
@@ -563,7 +563,7 @@ static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP_PIN_OFF_NONE),
OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
OMAP_PIN_OFF_NONE),
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_WILINK_PLATFORM_DATA
/* WLAN IRQ - GPIO 149 */
OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
@@ -601,7 +601,7 @@ static struct omap_board_mux omap36x_board_mux[] __initdata = {
OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_WILINK_PLATFORM_DATA
/* WLAN IRQ - GPIO 149 */
OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
@@ -637,7 +637,7 @@ static struct gpio omap3_evm_ehci_gpios[] __initdata = {
static void __init omap3_evm_wl12xx_init(void)
{
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_WILINK_PLATFORM_DATA
int ret;
/* WL12xx WLAN Init */
diff --git a/drivers/net/wireless/ti/Kconfig b/drivers/net/wireless/ti/Kconfig
index be80011..cbe1e7f 100644
--- a/drivers/net/wireless/ti/Kconfig
+++ b/drivers/net/wireless/ti/Kconfig
@@ -12,4 +12,13 @@ source "drivers/net/wireless/ti/wl18xx/Kconfig"
# keep last for automatic dependencies
source "drivers/net/wireless/ti/wlcore/Kconfig"
+
+config WILINK_PLATFORM_DATA
+ bool "TI WiLink platform data"
+ depends on WLCORE_SDIO || WL1251_SDIO
+ default y
+ ---help---
+ Small platform data bit needed to pass data to the sdio modules.
+
+
endif # WL_TI
diff --git a/drivers/net/wireless/ti/Makefile b/drivers/net/wireless/ti/Makefile
index 4d68239..af14231 100644
--- a/drivers/net/wireless/ti/Makefile
+++ b/drivers/net/wireless/ti/Makefile
@@ -1,5 +1,7 @@
obj-$(CONFIG_WLCORE) += wlcore/
obj-$(CONFIG_WL12XX) += wl12xx/
-obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wlcore/
obj-$(CONFIG_WL1251) += wl1251/
obj-$(CONFIG_WL18XX) += wl18xx/
+
+# small builtin driver bit
+obj-$(CONFIG_WILINK_PLATFORM_DATA) += wilink_platform_data.o
diff --git a/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
similarity index 100%
rename from drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c
rename to drivers/net/wireless/ti/wilink_platform_data.c
diff --git a/drivers/net/wireless/ti/wlcore/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig
index d7b907e..2b83282 100644
--- a/drivers/net/wireless/ti/wlcore/Kconfig
+++ b/drivers/net/wireless/ti/wlcore/Kconfig
@@ -33,8 +33,3 @@ config WLCORE_SDIO
If you choose to build a module, it'll be called wlcore_sdio.
Say N if unsure.
-
-config WL12XX_PLATFORM_DATA
- bool
- depends on WLCORE_SDIO != n || WL1251_SDIO != n
- default y
diff --git a/drivers/net/wireless/ti/wlcore/Makefile b/drivers/net/wireless/ti/wlcore/Makefile
index d9fba9e..b21398f 100644
--- a/drivers/net/wireless/ti/wlcore/Makefile
+++ b/drivers/net/wireless/ti/wlcore/Makefile
@@ -9,7 +9,4 @@ obj-$(CONFIG_WLCORE) += wlcore.o
obj-$(CONFIG_WLCORE_SPI) += wlcore_spi.o
obj-$(CONFIG_WLCORE_SDIO) += wlcore_sdio.o
-# small builtin driver bit
-obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
-
ccflags-y += -D__CHECK_ENDIAN__
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 360c9bc..a54fe82 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -24,6 +24,8 @@
#ifndef _LINUX_WL12XX_H
#define _LINUX_WL12XX_H
+#include <linux/err.h>
+
/* Reference clock values */
enum {
WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
@@ -60,10 +62,12 @@ struct wl12xx_platform_data {
/* Platform does not support level trigger interrupts */
#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0)
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_WILINK_PLATFORM_DATA
int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
+struct wl12xx_platform_data *wl12xx_get_platform_data(void);
+
#else
static inline
@@ -72,8 +76,12 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
return -ENOSYS;
}
-#endif
+static inline
+struct wl12xx_platform_data *wl12xx_get_platform_data(void)
+{
+ return ERR_PTR(-ENODATA);
+}
-struct wl12xx_platform_data *wl12xx_get_platform_data(void);
+#endif
#endif
--
1.7.10.4
^ permalink raw reply related
* [RFC PATCH 0/4] net: mvmdio: close the gaps between mv643xx_eth and mvmdio
From: Florian Fainelli @ 2013-01-25 10:06 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
This patch series attempts to close the gaps between the SMI/MDIO driver
implemented and use by the Marvell MV643XX ethernet driver and Thomas' MVMDIO
driver. I did not convert yet mv643xx_eth to use it as it would require proper
Device Tree bindings (which is being worked on) to easily hook into it.
Note that I could not test this properly yet, thus the RFC, and I would like to
find a better way of setting/getting the PHY address than using two exports,
although I have tried to make them easy enough to use so the following logic in
Ethernet drivers can be used:
- lookup device tree handle from MDIO device tree node
- lookup corresponding struct platform_device from the device tree handle
- call the helpers
Comment welcome!
Florian Fainelli (4):
net: mvmdio: rename base register cookie from smireg to regs
net: mvmdio: do not assume SMI reg is at offset 0 of the resource
net: mvmdio: enhance driver to support SMI error/done interrupts
net: mvmdio: add getter and setter for PHY addresses
.../devicetree/bindings/net/marvell-orion-mdio.txt | 5 +-
arch/arm/boot/dts/armada-370-xp.dtsi | 2 +-
drivers/net/ethernet/marvell/mvmdio.c | 125 +++++++++++++++++---
include/linux/marvell_mvmdio.h | 10 ++
4 files changed, 122 insertions(+), 20 deletions(-)
create mode 100644 include/linux/marvell_mvmdio.h
--
1.7.10.4
^ permalink raw reply
* [RFC PATCH 1/4] net: mvmdio: rename base register cookie from smireg to regs
From: Florian Fainelli @ 2013-01-25 10:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359108409-4378-1-git-send-email-florian@openwrt.org>
This patch renames the base register cookie in the mvmdio drive from
"smireg" to "regs" since a subsequent patch is going to use an ioremap()
cookie whose size is larger than a single register of 4 bytes. No
functionnal code change introduced.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
drivers/net/ethernet/marvell/mvmdio.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index 74f1c15..e4a89b2 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -39,7 +39,7 @@
struct orion_mdio_dev {
struct mutex lock;
- void __iomem *smireg;
+ void __iomem *regs;
};
/* Wait for the SMI unit to be ready for another operation
@@ -52,7 +52,7 @@ static int orion_mdio_wait_ready(struct mii_bus *bus)
count = 0;
while (1) {
- val = readl(dev->smireg);
+ val = readl(dev->regs);
if (!(val & MVMDIO_SMI_BUSY))
break;
@@ -87,12 +87,12 @@ static int orion_mdio_read(struct mii_bus *bus, int mii_id,
writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) |
(regnum << MVMDIO_SMI_PHY_REG_SHIFT) |
MVMDIO_SMI_READ_OPERATION),
- dev->smireg);
+ dev->regs);
/* Wait for the value to become available */
count = 0;
while (1) {
- val = readl(dev->smireg);
+ val = readl(dev->regs);
if (val & MVMDIO_SMI_READ_VALID)
break;
@@ -129,7 +129,7 @@ static int orion_mdio_write(struct mii_bus *bus, int mii_id,
(regnum << MVMDIO_SMI_PHY_REG_SHIFT) |
MVMDIO_SMI_WRITE_OPERATION |
(value << MVMDIO_SMI_DATA_SHIFT)),
- dev->smireg);
+ dev->regs);
mutex_unlock(&dev->lock);
@@ -173,8 +173,8 @@ static int orion_mdio_probe(struct platform_device *pdev)
bus->irq[i] = PHY_POLL;
dev = bus->priv;
- dev->smireg = of_iomap(pdev->dev.of_node, 0);
- if (!dev->smireg) {
+ dev->regs = of_iomap(pdev->dev.of_node, 0);
+ if (!dev->regs) {
dev_err(&pdev->dev, "No SMI register address given in DT\n");
kfree(bus->irq);
mdiobus_free(bus);
@@ -186,7 +186,7 @@ static int orion_mdio_probe(struct platform_device *pdev)
ret = of_mdiobus_register(bus, np);
if (ret < 0) {
dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
- iounmap(dev->smireg);
+ iounmap(dev->regs);
kfree(bus->irq);
mdiobus_free(bus);
return ret;
--
1.7.10.4
^ permalink raw reply related
* [RFC PATCH 2/4] net: mvmdio: do not assume SMI reg is at offset 0 of the resource
From: Florian Fainelli @ 2013-01-25 10:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359108409-4378-1-git-send-email-florian@openwrt.org>
This patch changes the mvmdio driver not to assume that the
MVMDIO_SMI_REG is at offset 0 of the resource we are being passed via
Device Tree. This is actually required to reduce the differences between
the mv643xx_eth SMI driver and mvmdio. The only user of the "orion-mdio"
binding is updated accordingly.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
Documentation/devicetree/bindings/net/marvell-orion-mdio.txt | 2 +-
arch/arm/boot/dts/armada-370-xp.dtsi | 2 +-
drivers/net/ethernet/marvell/mvmdio.c | 9 +++++----
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt b/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt
index 34e7aaf..3320d5c 100644
--- a/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt
+++ b/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt
@@ -19,7 +19,7 @@ mdio {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,orion-mdio";
- reg = <0xd0072004 0x4>;
+ reg = <0xd0072000 0x8>;
};
And at the board level:
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 4c0abe8..0e7d880 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -91,7 +91,7 @@
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,orion-mdio";
- reg = <0xd0072004 0x4>;
+ reg = <0xd0072000 0x8>;
};
ethernet at d0070000 {
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index e4a89b2..16be140 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -29,6 +29,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
+#define MVMDIO_SMI_REG 0x0004
#define MVMDIO_SMI_DATA_SHIFT 0
#define MVMDIO_SMI_PHY_ADDR_SHIFT 16
#define MVMDIO_SMI_PHY_REG_SHIFT 21
@@ -52,7 +53,7 @@ static int orion_mdio_wait_ready(struct mii_bus *bus)
count = 0;
while (1) {
- val = readl(dev->regs);
+ val = readl(dev->regs + MVMDIO_SMI_REG);
if (!(val & MVMDIO_SMI_BUSY))
break;
@@ -87,12 +88,12 @@ static int orion_mdio_read(struct mii_bus *bus, int mii_id,
writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) |
(regnum << MVMDIO_SMI_PHY_REG_SHIFT) |
MVMDIO_SMI_READ_OPERATION),
- dev->regs);
+ dev->regs + MVMDIO_SMI_REG);
/* Wait for the value to become available */
count = 0;
while (1) {
- val = readl(dev->regs);
+ val = readl(dev->regs + MVMDIO_SMI_REG);
if (val & MVMDIO_SMI_READ_VALID)
break;
@@ -129,7 +130,7 @@ static int orion_mdio_write(struct mii_bus *bus, int mii_id,
(regnum << MVMDIO_SMI_PHY_REG_SHIFT) |
MVMDIO_SMI_WRITE_OPERATION |
(value << MVMDIO_SMI_DATA_SHIFT)),
- dev->regs);
+ dev->regs + MVMDIO_SMI_REG);
mutex_unlock(&dev->lock);
--
1.7.10.4
^ permalink raw reply related
* [RFC PATCH 3/4] net: mvmdio: enhance driver to support SMI error/done interrupts
From: Florian Fainelli @ 2013-01-25 10:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359108409-4378-1-git-send-email-florian@openwrt.org>
This patch enhances the "mvmdio" to support a SMI error/done interrupt
line which can be used along with a wait queue instead of doing
busy-waiting on the registers. This is a feature which is available in
the mv643xx_eth SMI code and thus reduces again the gap between the two.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
.../devicetree/bindings/net/marvell-orion-mdio.txt | 3 +
drivers/net/ethernet/marvell/mvmdio.c | 81 +++++++++++++++++---
2 files changed, 73 insertions(+), 11 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt b/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt
index 3320d5c..1abf47a 100644
--- a/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt
+++ b/Documentation/devicetree/bindings/net/marvell-orion-mdio.txt
@@ -9,6 +9,9 @@ Required properties:
- compatible: "marvell,orion-mdio"
- reg: address and length of the SMI register
+Optional properties:
+- interrupts: interrupt line number for the SMI error/done
+
The child nodes of the MDIO driver are the individual PHY devices
connected to this MDIO bus. They must have a "reg" property given the
PHY address on the MDIO bus.
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index 16be140..bdd9047 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -24,10 +24,14 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/phy.h>
+#include <linux/interrupt.h>
#include <linux/of_address.h>
#include <linux/of_mdio.h>
+#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
#define MVMDIO_SMI_REG 0x0004
#define MVMDIO_SMI_DATA_SHIFT 0
@@ -37,12 +41,28 @@
#define MVMDIO_SMI_WRITE_OPERATION 0
#define MVMDIO_SMI_READ_VALID BIT(27)
#define MVMDIO_SMI_BUSY BIT(28)
+#define MVMDIO_ERR_INT_CAUSE 0x0080
+#define MVMDIO_ERR_INT_SMI_DONE 0x00000010
+#define MVMDIO_ERR_INT_MASK 0x0084
struct orion_mdio_dev {
struct mutex lock;
void __iomem *regs;
+ /*
+ * If we have access to the error interrupt pin (which is
+ * somewhat misnamed as it not only reflects internal errors
+ * but also reflects SMI completion), use that to wait for
+ * SMI access completion instead of polling the SMI busy bit.
+ */
+ int err_interrupt;
+ wait_queue_head_t smi_busy_wait;
};
+static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev)
+{
+ return !(readl(dev->regs + MVMDIO_SMI_REG) & MVMDIO_SMI_BUSY);
+}
+
/* Wait for the SMI unit to be ready for another operation
*/
static int orion_mdio_wait_ready(struct mii_bus *bus)
@@ -51,19 +71,30 @@ static int orion_mdio_wait_ready(struct mii_bus *bus)
int count;
u32 val;
- count = 0;
- while (1) {
- val = readl(dev->regs + MVMDIO_SMI_REG);
- if (!(val & MVMDIO_SMI_BUSY))
- break;
-
- if (count > 100) {
- dev_err(bus->parent, "Timeout: SMI busy for too long\n");
- return -ETIMEDOUT;
+ if (dev->err_interrupt == NO_IRQ) {
+ count = 0;
+ while (1) {
+ val = readl(dev->regs + MVMDIO_SMI_REG);
+ if (!(val & MVMDIO_SMI_BUSY))
+ break;
+
+ if (count > 100) {
+ dev_err(bus->parent,
+ "Timeout: SMI busy for too long\n");
+ return -ETIMEDOUT;
+ }
+
+ udelay(10);
+ count++;
}
+ }
- udelay(10);
- count++;
+ if (!orion_mdio_smi_is_done(dev)) {
+ wait_event_timeout(dev->smi_busy_wait,
+ orion_mdio_smi_is_done(dev),
+ msecs_to_jiffies(100));
+ if (!orion_mdio_smi_is_done(dev))
+ return -ETIMEDOUT;
}
return 0;
@@ -142,6 +173,21 @@ static int orion_mdio_reset(struct mii_bus *bus)
return 0;
}
+static irqreturn_t orion_mdio_err_irq(int irq, void *dev_id)
+{
+ struct orion_mdio_dev *dev = dev_id;
+
+ if (readl(dev->regs + MVMDIO_ERR_INT_CAUSE) &
+ MVMDIO_ERR_INT_SMI_DONE) {
+ writel(~MVMDIO_ERR_INT_SMI_DONE,
+ dev->regs + MVMDIO_ERR_INT_CAUSE);
+ wake_up(&dev->smi_busy_wait);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
static int orion_mdio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -182,6 +228,19 @@ static int orion_mdio_probe(struct platform_device *pdev)
return -ENODEV;
}
+ dev->err_interrupt = NO_IRQ;
+ init_waitqueue_head(&dev->smi_busy_wait);
+
+ dev->err_interrupt = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ if (dev->err_interrupt != NO_IRQ) {
+ ret = devm_request_irq(&pdev->dev, dev->err_interrupt,
+ orion_mdio_err_irq,
+ IRQF_SHARED, pdev->name, dev);
+ if (!ret)
+ writel(MVMDIO_ERR_INT_SMI_DONE,
+ dev->regs + MVMDIO_ERR_INT_MASK);
+ }
+
mutex_init(&dev->lock);
ret = of_mdiobus_register(bus, np);
--
1.7.10.4
^ permalink raw reply related
* [RFC PATCH 4/4] net: mvmdio: add getter and setter for PHY addresses
From: Florian Fainelli @ 2013-01-25 10:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359108409-4378-1-git-send-email-florian@openwrt.org>
This patch adds orion_mdio_{set,get}_phy_addr(.., port_number, phy_addr)
which is a feature available in this MDIO driver to monitor a particular
PHY address. This brings mvmdio one step closer to what is used in
mv643x_eth.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
drivers/net/ethernet/marvell/mvmdio.c | 29 +++++++++++++++++++++++++++++
include/linux/marvell_mvmdio.h | 10 ++++++++++
2 files changed, 39 insertions(+)
create mode 100644 include/linux/marvell_mvmdio.h
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index bdd9047..09e2470 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -32,7 +32,9 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/wait.h>
+#include <linux/marvell_mvmdio.h>
+#define MVMDIO_PHY_ADDR 0x0000
#define MVMDIO_SMI_REG 0x0004
#define MVMDIO_SMI_DATA_SHIFT 0
#define MVMDIO_SMI_PHY_ADDR_SHIFT 16
@@ -188,6 +190,33 @@ static irqreturn_t orion_mdio_err_irq(int irq, void *dev_id)
return IRQ_NONE;
}
+void orion_mdio_phy_addr_set(struct platform_device *pdev,
+ int port_num, int phy_addr)
+{
+ struct orion_mdio_dev *dev =
+ platform_get_drvdata(pdev);
+ int addr_shift = 5 * port_num;
+ u32 data;
+
+ data = readl(dev->regs + MVMDIO_PHY_ADDR);
+ data &= ~(0x1f << addr_shift);
+ data |= (phy_addr & 0x1f) << addr_shift;
+ writel(data, dev->regs + MVMDIO_PHY_ADDR);
+}
+EXPORT_SYMBOL(orion_mdio_phy_addr_set);
+
+int orion_mdio_phy_addr_get(struct platform_device *pdev, int port_num)
+{
+ struct orion_mdio_dev *dev =
+ platform_get_drvdata(pdev);
+ unsigned int data;
+
+ data = readl(dev->regs + MVMDIO_PHY_ADDR);
+
+ return (data >> (5 * port_num)) & 0x1f;
+}
+EXPORT_SYMBOL(orion_mdio_phy_addr_get);
+
static int orion_mdio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
diff --git a/include/linux/marvell_mvmdio.h b/include/linux/marvell_mvmdio.h
new file mode 100644
index 0000000..c2dfec4
--- /dev/null
+++ b/include/linux/marvell_mvmdio.h
@@ -0,0 +1,10 @@
+#ifndef _MARVELL_MVMDIO_H
+#define _MARVELL_MVMDIO_H
+
+#include <linux/platform_device.h>
+
+void orion_mdio_phy_addr_set(struct platform_device *pdev,
+ int port_num, int phy_addr);
+int orion_mdio_phy_addr_get(struct platform_device *pdev, int port_num);
+
+#endif /* _MARVELL_MVMDIO_H */
--
1.7.10.4
^ permalink raw reply related
* [PATCH 12/15] ARM: mach-shmobile: sh73a0: Allow initialisation of GIC by DT
From: Mark Rutland @ 2013-01-25 10:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359080013-29189-13-git-send-email-horms+renesas@verge.net.au>
On Fri, Jan 25, 2013 at 02:13:30AM +0000, Simon Horman wrote:
> This allows the GIC interrupt controller of the sh73a0 SoC to be
> initialised using a flattened device tree blob.
>
> It does not allow the INTC interrupt controller which is also present on
> the sh73a0 SoC to be enabled via device tree. Nor does it handle sharing
> of interrupts between the GIC and INTC interrupt controllers.
>
> This limits the usefulness of this code to applications which only wish to
> access devices which use interrupts that can be handled by the GIC
> interrupt controller. Other applications should, for now, continue using
> non-device tree initialisation of the sh72a0 interrupt controllers.
>
> Includes update to use irqchip_init() by Thierry Reding
>
> Cc: Thierry Reding <thierry.reding@avionic-design.de>
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> ---
> arch/arm/boot/dts/sh73a0.dtsi | 33 ++++++++++++++++++++++++++
> arch/arm/mach-shmobile/include/mach/common.h | 1 +
> arch/arm/mach-shmobile/intc-sh73a0.c | 9 +++++++
> 3 files changed, 43 insertions(+)
> create mode 100644 arch/arm/boot/dts/sh73a0.dtsi
>
> diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
> new file mode 100644
> index 0000000..7dae1f4
> --- /dev/null
> +++ b/arch/arm/boot/dts/sh73a0.dtsi
> @@ -0,0 +1,33 @@
> +/*
> + * Device Tree Source for the SH73A0 SoC
> + *
> + * Copyright (C) 2012 Renesas Solutions Corp.
> + *
> + * 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/ "skeleton.dtsi"
> +
> +/ {
> + compatible = "renesas,sh73a0";
> +
> + cpus {
> + cpu at 0 {
> + compatible = "arm,cortex-a9";
> + };
> + cpu at 1 {
> + compatible = "arm,cortex-a9";
> + };
> + };
It would be good the have reg and device_type properties set for the cpu nodes,
so they're guaranteed to work with the logical map.
[...]
Thanks,
Mark.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox