* [RFC] sh: Take into account the base of physical memory in virt_to_phys()
From: Simon Horman @ 2011-09-15 11:12 UTC (permalink / raw)
To: linux-sh
Previously virt_to_phys() assumed that physical memory always started
at address 0. This is not always the case.
Tested on an sh7757lcr (32bit system) whose only System RAM region is
40000000-4effffff
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/sh/kexec-sh.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/kexec/arch/sh/kexec-sh.c b/kexec/arch/sh/kexec-sh.c
index 4b21ee8..b0381bb 100644
--- a/kexec/arch/sh/kexec-sh.c
+++ b/kexec/arch/sh/kexec-sh.c
@@ -188,10 +188,18 @@ void kexec_sh_setup_zero_page(char *zero_page_buf, size_t zero_page_size,
unsigned long virt_to_phys(unsigned long addr)
{
unsigned long seg = addr & 0xe0000000;
+ unsigned long long start, end;
+ int ret;
+
+ /* Assume there is only one "System RAM" region */
+ ret = parse_iomem_single("System RAM\n", &start, &end);
+ if (ret)
+ die("Could not parse System RAM region in /proc/iomem\n");
+
if (seg != 0x80000000 && seg != 0xc0000000)
die("Virtual address %p is not in P1 or P2\n", (void *)addr);
- return addr - seg;
+ return addr - seg + start;
}
/*
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH 2/5] PM / Runtime: Do not run callbacks under lock for
From: Ming Lei @ 2011-09-15 10:55 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM mailing list, LKML, Linux-sh list, Magnus Damm,
Kevin Hilman, jean.pihet
In-Reply-To: <201109142245.14808.rjw@sisk.pl>
On Thu, Sep 15, 2011 at 4:45 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Wednesday, September 14, 2011, Ming Lei wrote:
>> Hi,
>>
>> On Wed, Sep 14, 2011 at 12:06 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>>
>> >> >> If power.lock is released, the transition states(resuming or suspending)
>> >> >
>> >> >> may be observed in rpm_suspend or rpm_resume, then tasks schedule
>> >> >
>> >> >> will be produced in these two functions,
>> >> >
>> >> > I don't think so, because the interrupts are still off.
>> >>
>> >> Yes, the interrupts are still off on local CPU, but the release of spin lock may
>> >> cause another CPUs to run into rpm_suspend or rpm_resume and produce
>> >> task schedule inside the two functions.
>> >
>> > Not for the same device, though.
>>
>> I think it is probable to happen on the same device in theory, see below:
>>
>> - suppose irq_safe is set before calling two pm_runtime_suspend below
>> - suppose this patch has been applied
>>
>> CPU0 CPU1
>> pm_runtime_suspend
>> acquired power lock
>> rpm_suspend
>> pm_runtime_suspend
>> spining power lock
>> ...
>> release power lock
>> acquired power lock
>> run .runtime_suspend
>> found the dev suspending
>> wait for power state and schedule
>
> OK, I see what the problem is. The second CPU can see the status
> being RPM_SUSPENDING in the irq_safe case, which isn't possible
> without the patch.
>
> Good catch!
>
> I think in that case rpm_suspend() should just release the lock,
> run cpu_relax(), reacquire the lock and go to the "repeat" label.
Yes, it makes sense in this case.
BTW: looks like something is wrong about PM mail list, I often got
the messages below these days:
Delivery to the following recipient has been delayed:
linux-pm@lists.linux-foundation.org
Message will be retried for 1 more day(s)
thanks,
--
Ming Lei
^ permalink raw reply
* [PATCH 10/10 v2] ARM: mach-shmobile: clock-sh73a0: add DSIxPHY clock support
From: Kuninori Morimoto @ 2011-09-15 7:56 UTC (permalink / raw)
To: linux-sh
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2
o use PTR_ERR(xx) for return value
arch/arm/mach-shmobile/board-ag5evm.c | 16 ++++-
arch/arm/mach-shmobile/board-kota2.c | 17 ++++-
arch/arm/mach-shmobile/clock-sh73a0.c | 113 +++++++++++++++++++++++++++++++++
3 files changed, 139 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 75c334d..b36dc61 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -320,12 +320,11 @@ static struct resource mipidsi0_resources[] = {
},
};
-#define DSI0PHYCR 0xe615006c
static int sh_mipi_set_dot_clock(struct platform_device *pdev,
void __iomem *base,
int enable)
{
- struct clk *pck;
+ struct clk *pck, *phy;
int ret;
pck = clk_get(&pdev->dev, "dsip_clk");
@@ -334,18 +333,27 @@ static int sh_mipi_set_dot_clock(struct platform_device *pdev,
goto sh_mipi_set_dot_clock_pck_err;
}
+ phy = clk_get(&pdev->dev, "dsiphy_clk");
+ if (IS_ERR(phy)) {
+ ret = PTR_ERR(phy);
+ goto sh_mipi_set_dot_clock_phy_err;
+ }
+
if (enable) {
clk_set_rate(pck, clk_round_rate(pck, 24000000));
- __raw_writel(0x2a809010, DSI0PHYCR);
+ clk_set_rate(phy, clk_round_rate(pck, 510000000));
clk_enable(pck);
+ clk_enable(phy);
} else {
clk_disable(pck);
+ clk_disable(phy);
}
ret = 0;
+ clk_put(phy);
+sh_mipi_set_dot_clock_phy_err:
clk_put(pck);
-
sh_mipi_set_dot_clock_pck_err:
return ret;
}
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index 6c3866b..5b76d5d 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -367,12 +367,11 @@ static u32 sh_mipi_extra_dcs[] = {
};
#define DSI0PCKCR 0xe6150064
-#define DSI0PHYCR 0xe615006c
static int sh_mipi_set_dot_clock(struct platform_device *pdev,
void __iomem *base,
int enable)
{
- struct clk *pck;
+ struct clk *pck, *phy;
int ret;
pck = clk_get(&pdev->dev, "dsip_clk");
@@ -381,16 +380,28 @@ static int sh_mipi_set_dot_clock(struct platform_device *pdev,
goto sh_mipi_set_dot_clock_pck_err;
}
+ phy = clk_get(&pdev->dev, "dsiphy_clk");
+ if (IS_ERR(phy)) {
+ ret = PTR_ERR(phy);
+ goto sh_mipi_set_dot_clock_phy_err;
+ }
+
+
if (enable) {
+ /* 268.8MHz (33.6MHz x8) */
clk_set_rate(pck, clk_round_rate(pck, 19200000));
- __raw_writel(0x2a8b9a0d, DSI0PHYCR); /* 268.8MHz (33.6MHz x8) */
+ clk_set_rate(phy, clk_round_rate(phy, 268800000));
clk_enable(pck);
+ clk_enable(phy);
} else {
clk_disable(pck);
+ clk_disable(phy);
}
ret = 0;
+ clk_put(phy);
+sh_mipi_set_dot_clock_phy_err:
clk_put(pck);
sh_mipi_set_dot_clock_pck_err:
return ret;
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 80cb438..d447c7a 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -262,6 +262,114 @@ static struct clk div6_clks[DIV6_NR] = {
[DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
};
+/* DSI DIV */
+static unsigned long dsiphy_recalc(struct clk *clk)
+{
+ u32 value;
+
+ value = __raw_readl(clk->mapping->base);
+
+ /* FIXME */
+ if (!(value & 0x000B8000))
+ return clk->parent->rate;
+
+ value &= 0x3f;
+ value += 1;
+
+ if ((value < 12) ||
+ (value > 33)) {
+ pr_err("DSIPHY has wrong value (%d)", value);
+ return 0;
+ }
+
+ return clk->parent->rate / value;
+}
+
+static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk_rate_multi_range_round(clk, 12, 33, rate);
+}
+
+static void dsiphy_disable(struct clk *clk)
+{
+ u32 value;
+
+ value = __raw_readl(clk->mapping->base);
+ value &= ~0x000B8000;
+
+ __raw_writel(value , clk->mapping->base);
+}
+
+static int dsiphy_enable(struct clk *clk)
+{
+ u32 value;
+ int multi;
+
+ value = __raw_readl(clk->mapping->base);
+ multi = (value & 0x3f) + 1;
+
+ if ((multi < 12) || (multi > 33))
+ return -EIO;
+
+ __raw_writel(value | 0x000B8000, clk->mapping->base);
+
+ return 0;
+}
+
+static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 value;
+ int idx;
+
+ idx = rate / clk->parent->rate;
+ if ((idx < 12) || (idx > 33))
+ return -EINVAL;
+
+ idx += -1;
+
+ value = __raw_readl(clk->mapping->base);
+ value = (value & ~0x3f) + idx;
+
+ __raw_writel(value, clk->mapping->base);
+
+ return 0;
+}
+
+static struct clk_ops dsiphy_clk_ops = {
+ .recalc = dsiphy_recalc,
+ .round_rate = dsiphy_round_rate,
+ .set_rate = dsiphy_set_rate,
+ .enable = dsiphy_enable,
+ .disable = dsiphy_disable,
+};
+
+static struct clk_mapping dsi0phy_clk_mapping = {
+ .phys = DSI0PHYCR,
+ .len = 4,
+};
+
+static struct clk_mapping dsi1phy_clk_mapping = {
+ .phys = DSI1PHYCR,
+ .len = 4,
+};
+
+static struct clk dsi0phy_clk = {
+ .ops = &dsiphy_clk_ops,
+ .parent = &div6_clks[DIV6_DSI0P], /* late install */
+ .mapping = &dsi0phy_clk_mapping,
+};
+
+static struct clk dsi1phy_clk = {
+ .ops = &dsiphy_clk_ops,
+ .parent = &div6_clks[DIV6_DSI1P], /* late install */
+ .mapping = &dsi1phy_clk_mapping,
+};
+
+static struct clk *late_main_clks[] = {
+ &dsi0phy_clk,
+ &dsi1phy_clk,
+};
+
enum { MSTP001,
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP117, MSTP116, MSTP100,
MSTP219,
@@ -322,6 +430,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
+ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
@@ -394,6 +504,9 @@ void __init sh73a0_clock_init(void)
if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
+
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
if (!ret)
--
1.7.4.1
^ permalink raw reply related
* [PATCH 9/10 v2] fbdev: sh_mipi_dsi: add set_dot_clock() for each platform
From: Kuninori Morimoto @ 2011-09-15 7:55 UTC (permalink / raw)
To: linux-sh
Dot clock of SH MIPI are depends on each platform board.
This patch adds set_dot_clock() function for it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2
o use PTR_ERR(xx) for return value
arch/arm/mach-shmobile/board-ag5evm.c | 36 ++++++++++++++++++++++---
arch/arm/mach-shmobile/board-ap4evb.c | 25 ++++++++++++++++++
arch/arm/mach-shmobile/board-kota2.c | 40 +++++++++++++++++++++++++----
drivers/video/sh_mipi_dsi.c | 45 ++++++++-------------------------
include/video/sh_mipi_dsi.h | 3 ++
5 files changed, 104 insertions(+), 45 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 87e9091..75c334d 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -320,6 +320,36 @@ static struct resource mipidsi0_resources[] = {
},
};
+#define DSI0PHYCR 0xe615006c
+static int sh_mipi_set_dot_clock(struct platform_device *pdev,
+ void __iomem *base,
+ int enable)
+{
+ struct clk *pck;
+ int ret;
+
+ pck = clk_get(&pdev->dev, "dsip_clk");
+ if (IS_ERR(pck)) {
+ ret = PTR_ERR(pck);
+ goto sh_mipi_set_dot_clock_pck_err;
+ }
+
+ if (enable) {
+ clk_set_rate(pck, clk_round_rate(pck, 24000000));
+ __raw_writel(0x2a809010, DSI0PHYCR);
+ clk_enable(pck);
+ } else {
+ clk_disable(pck);
+ }
+
+ ret = 0;
+
+ clk_put(pck);
+
+sh_mipi_set_dot_clock_pck_err:
+ return ret;
+}
+
static struct sh_mipi_dsi_info mipidsi0_info = {
.data_format = MIPI_RGB888,
.lcd_chan = &lcdc0_info.ch[0],
@@ -328,6 +358,7 @@ static struct sh_mipi_dsi_info mipidsi0_info = {
.clksrc = 1,
.flags = SH_MIPI_DSI_HSABM |
SH_MIPI_DSI_SYNC_PULSES_MODE,
+ .set_dot_clock = sh_mipi_set_dot_clock,
};
static struct platform_device mipidsi0_device = {
@@ -467,8 +498,6 @@ void __init ag5evm_init_irq(void)
__raw_writew(__raw_readw(PINTCR0A) | (2<<10), PINTCR0A);
}
-#define DSI0PHYCR 0xe615006c
-
static void __init ag5evm_init(void)
{
sh73a0_pinmux_init();
@@ -549,9 +578,6 @@ static void __init ag5evm_init(void)
gpio_direction_output(GPIO_PORT235, 0);
lcd_backlight_reset();
- /* MIPI-DSI clock setup */
- __raw_writel(0x2a809010, DSI0PHYCR);
-
/* enable SDHI0 on CN15 [SD I/F] */
gpio_request(GPIO_FN_SDHICD0, NULL);
gpio_request(GPIO_FN_SDHIWP0, NULL);
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 114fd8a..5aa5ddd 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -575,12 +575,37 @@ static struct resource mipidsi0_resources[] = {
},
};
+#define PHYCTRL 0x0070
+static int sh_mipi_set_dot_clock(struct platform_device *pdev,
+ void __iomem *base,
+ int enable)
+{
+ struct clk *pck = clk_get(&pdev->dev, "dsip_clk");
+ void __iomem *phy = base + PHYCTRL;
+
+ if (IS_ERR(pck))
+ return PTR_ERR(pck);
+
+ if (enable) {
+ clk_set_rate(pck, clk_round_rate(pck, 24000000));
+ iowrite32(ioread32(phy) | (0xb << 8), phy);
+ clk_enable(pck);
+ } else {
+ clk_disable(pck);
+ }
+
+ clk_put(pck);
+
+ return 0;
+}
+
static struct sh_mipi_dsi_info mipidsi0_info = {
.data_format = MIPI_RGB888,
.lcd_chan = &lcdc_info.ch[0],
.lane = 2,
.vsynw_offset = 17,
.flags = SH_MIPI_DSI_SYNC_PULSES_MODE,
+ .set_dot_clock = sh_mipi_set_dot_clock,
};
static struct platform_device mipidsi0_device = {
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index a2be703..6c3866b 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -365,6 +366,36 @@ static u32 sh_mipi_extra_dcs[] = {
SH_MIPI_DCS(0x2c), /* memory write on */
};
+#define DSI0PCKCR 0xe6150064
+#define DSI0PHYCR 0xe615006c
+static int sh_mipi_set_dot_clock(struct platform_device *pdev,
+ void __iomem *base,
+ int enable)
+{
+ struct clk *pck;
+ int ret;
+
+ pck = clk_get(&pdev->dev, "dsip_clk");
+ if (IS_ERR(pck)) {
+ ret = PTR_ERR(pck);
+ goto sh_mipi_set_dot_clock_pck_err;
+ }
+
+ if (enable) {
+ clk_set_rate(pck, clk_round_rate(pck, 19200000));
+ __raw_writel(0x2a8b9a0d, DSI0PHYCR); /* 268.8MHz (33.6MHz x8) */
+ clk_enable(pck);
+ } else {
+ clk_disable(pck);
+ }
+
+ ret = 0;
+
+ clk_put(pck);
+sh_mipi_set_dot_clock_pck_err:
+ return ret;
+}
+
static struct sh_mipi_dsi_info mipidsi0_info = {
.data_format = MIPI_RGB888,
.lcd_chan = &lcdc0_info.ch[0],
@@ -377,6 +408,7 @@ static struct sh_mipi_dsi_info mipidsi0_info = {
SH_MIPI_DSI_SYNC_BURST_MODE,
.extra_array = sh_mipi_extra_dcs,
.extra_array_len= ARRAY_SIZE(sh_mipi_extra_dcs),
+ .set_dot_clock = sh_mipi_set_dot_clock,
};
static struct platform_device mipidsi0_device = {
@@ -434,9 +466,6 @@ void __init kota2_init_irq(void)
__raw_writew(2 << 10, PINTCR0A);
}
-#define DSI0PCKCR 0xe6150064
-#define DSI0PHYCR 0xe615006c
-
static void __init kota2_init(void)
{
sh73a0_pinmux_init();
@@ -534,9 +563,8 @@ static void __init kota2_init(void)
gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
- /* MIPI-DSI clock setup */
- __raw_writel(0x00000119, DSI0PCKCR);
- __raw_writel(0x2a8b9111, DSI0PHYCR);
+ /* MIPI-DSI clock clean up */
+ __raw_writel(0x00000000, DSI0PCKCR);
/* Unreset LCD Panel */
gpio_request(GPIO_PORT217, NULL);
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 166b468..e42cd81 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -59,7 +59,6 @@ struct sh_mipi {
void __iomem *base;
void __iomem *linkbase;
struct clk *dsit_clk;
- struct clk *dsip_clk;
struct device *dev;
void *next_board_data;
@@ -313,8 +312,8 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
/* DSI-Tx bias on */
iowrite32(0x00000001, base + PHYCTRL);
udelay(200);
- /* Deassert resets, power on, set multiplier */
- iowrite32(0x03070b01, base + PHYCTRL);
+ /* Deassert resets, power on */
+ iowrite32(0x03070001, base + PHYCTRL);
/* setup l-bridge */
@@ -441,6 +440,9 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
if (!res || !res2 || idx >= ARRAY_SIZE(mipi_dsi) || !pdata)
return -ENODEV;
+ if (!pdata->set_dot_clock)
+ return -EINVAL;
+
mutex_lock(&array_lock);
if (idx < 0)
for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++)
@@ -501,34 +503,10 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate);
- mipi->dsip_clk = clk_get(&pdev->dev, "dsip_clk");
- if (IS_ERR(mipi->dsip_clk)) {
- ret = PTR_ERR(mipi->dsip_clk);
- goto eclkpget;
- }
-
- f_current = clk_get_rate(mipi->dsip_clk);
- /* Between 10 and 50MHz */
- rate = clk_round_rate(mipi->dsip_clk, 24000000);
- if (rate > 0 && rate != f_current)
- ret = clk_set_rate(mipi->dsip_clk, rate);
- else
- ret = rate;
- if (ret < 0)
- goto esetprate;
-
- dev_dbg(&pdev->dev, "DSI-P clk %lu -> %lu\n", f_current, rate);
-
- msleep(10);
-
ret = clk_enable(mipi->dsit_clk);
if (ret < 0)
goto eclkton;
- ret = clk_enable(mipi->dsip_clk);
- if (ret < 0)
- goto eclkpon;
-
mipi_dsi[idx] = mipi;
pm_runtime_enable(&pdev->dev);
@@ -538,6 +516,10 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
if (ret < 0)
goto emipisetup;
+ ret = pdata->set_dot_clock(pdev, mipi->base, 1);
+ if (ret < 0)
+ goto emipisetup;
+
mutex_unlock(&array_lock);
platform_set_drvdata(pdev, mipi);
@@ -557,13 +539,8 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
emipisetup:
mipi_dsi[idx] = NULL;
pm_runtime_disable(&pdev->dev);
- clk_disable(mipi->dsip_clk);
-eclkpon:
clk_disable(mipi->dsit_clk);
eclkton:
-esetprate:
- clk_put(mipi->dsip_clk);
-eclkpget:
esettrate:
clk_put(mipi->dsit_clk);
eclktget:
@@ -614,10 +591,10 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
pdata->lcd_chan->board_cfg.board_data = NULL;
pm_runtime_disable(&pdev->dev);
- clk_disable(mipi->dsip_clk);
clk_disable(mipi->dsit_clk);
clk_put(mipi->dsit_clk);
- clk_put(mipi->dsip_clk);
+ pdata->set_dot_clock(pdev, mipi->base, 0);
+
iounmap(mipi->linkbase);
if (res2)
release_mem_region(res2->start, resource_size(res2));
diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h
index fb3950e..5ded705 100644
--- a/include/video/sh_mipi_dsi.h
+++ b/include/video/sh_mipi_dsi.h
@@ -61,6 +61,9 @@ struct sh_mipi_dsi_info {
unsigned int vsynw_offset;
u32 *extra_array;
int extra_array_len;
+ int (*set_dot_clock)(struct platform_device *pdev,
+ void __iomem *base,
+ int enable);
};
#endif
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH 09/10] fbdev: sh_mipi_dsi: add set_dot_clock() for each platform
From: Kuninori Morimoto @ 2011-09-15 7:47 UTC (permalink / raw)
To: linux-sh
In-Reply-To: <87ehzqqabh.wl%kuninori.morimoto.gx@renesas.com>
Hi Paul
Thank you for checking my patch
> I'm not sure why you're using this convention of clobbering the return
> value. There are a number of reasons why clk_get() could fail, and you're
> simply discarding that information outright and unconditionally kicking
> up -EIO. You should simply do this as:
>
> if (IS_ERR(...)) {
> ret = PTR_ERR(...);
> ...
> }
>
> in order to propagate the error value all the way down the chain. This
> seems to apply to some of the other patches in this series, too.
OK. I understand.
I send v2 of [PATCH 9/10], [PATCH 10/10]
Best regards
---
Kuninori Morimoto
^ permalink raw reply
* Re: [PATCH 09/10] fbdev: sh_mipi_dsi: add set_dot_clock() for each platform
From: Paul Mundt @ 2011-09-15 5:57 UTC (permalink / raw)
To: linux-sh
In-Reply-To: <87ehzqqabh.wl%kuninori.morimoto.gx@renesas.com>
On Fri, Sep 09, 2011 at 03:28:22AM -0700, Kuninori Morimoto wrote:
> +static int sh_mipi_set_dot_clock(struct platform_device *pdev,
> + void __iomem *base,
> + int enable)
> +{
> + struct clk *pck;
> + int ret = -EIO;
> +
> + pck = clk_get(&pdev->dev, "dsip_clk");
> + if (IS_ERR(pck))
> + goto sh_mipi_set_dot_clock_pck_err;
> +
> + if (enable) {
> + clk_set_rate(pck, clk_round_rate(pck, 24000000));
> + __raw_writel(0x2a809010, DSI0PHYCR);
> + clk_enable(pck);
> + } else {
> + clk_disable(pck);
> + }
> +
> + ret = 0;
> +
> + clk_put(pck);
> +
> +sh_mipi_set_dot_clock_pck_err:
> + return ret;
> +}
> +
I'm not sure why you're using this convention of clobbering the return
value. There are a number of reasons why clk_get() could fail, and you're
simply discarding that information outright and unconditionally kicking
up -EIO. You should simply do this as:
if (IS_ERR(...)) {
ret = PTR_ERR(...);
...
}
in order to propagate the error value all the way down the chain. This
seems to apply to some of the other patches in this series, too.
^ permalink raw reply
* 群发软件+买家搜索机+109届广交会买家
From: 仅10元每天 @ 2011-09-15 5:41 UTC (permalink / raw)
To: linux-sh
In-Reply-To: <20111213084743353137@amidress.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 15767 bytes --]
������������������������������������+109������������������������������������������������������������������������������������������������������������������������������������������������������������������,B2B���������������������������������������������500���������,���������10������������������������������������
���������������������������������������������������������������������������������������������������
���������������������������������������������������������������������������������������������������
1������������������������������������������������������ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5���������������������������������������������
2���������500������������������������������������������������������ ���������������������������500��������������������������������������������������������������������������������������������������� ���������
3���������������������������������������������������������������Email������������������������������������ ���������������������������������������������1-2���������������������������������������������������������������EMAIL������������������������������������������������������
������������������������������������������������������QQ: 1339625218 ������������������������������������������������������������������������: 1339625218@qq.com
������������������������������������������������������QQ: 1339625218 ������������������������������������������������������������������������: 1339625218@qq.com
������������������������������������������������������QQ: 1339625218 ������������������������������������������������������������������������: 1339625218@qq.com
������������������������������������:
������������������8������������������(������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������)���������
1���������2011������������������109���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
2������������������������������������������������������������������������������������������2011���������������������������������������������+2012���������������������������������������������������������������������������������������������������������������������������������������
3������������������������������������������������������������������������,���������451660������������������������������������ (������������������������������������������������������ 2011-05-16���������)
4���������2008���������,2009���������,2010��������� ������������������+������������������������������������������������������������������������������������������103 104 105 106 107 108 ��������������������������� ���������120.6������������������������������������
5���������2010������������������������������������������������������������������������PPAI��������������������������������������������� PPAI Members Directory������������������������������������������������������������������������������������������
6���������2010���������������������������������������������������������������������������������������������������������������������(���������������������������������������������������������������)������������������7.2������������������������������������������������������������������������������������������������������������
7���������48.68������������������������������������������������������������������������������������������������������������������������������������������������ 1-2���������������������������������������������2���������������������������1������������������������������������������������������ 2���������������������������������������������������������������������������������������������������������������������36���������������������������
8���������2009���������������������������������������������������������������piers��������������������������� 1���������������������������
������������������������������������������������������������������������������������������������������������������������������ (���������������������������������������������������������������������������������������������������������������������������������������������������������) ������������������������������������������������������ ���������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������{.n���+���������������������+%���������������������\x17������w������{.n���+������������{���������������{ay���\x1d���������������,j\a������f���������h���������������������������z_������\x03(���������������������j"������\x1a���^[m������������\a������G������������������?���������������&���������~������
^ permalink raw reply
* Re: [PATCH 2/5] PM / Runtime: Do not run callbacks under lock for power.irq_safe set
From: Rafael J. Wysocki @ 2011-09-14 20:45 UTC (permalink / raw)
To: Ming Lei
Cc: Linux PM mailing list, LKML, Linux-sh list, Magnus Damm,
Kevin Hilman, jean.pihet
In-Reply-To: <CACVXFVMFZJioG_vgJ_tx9rA8_=H0HcKZLCyLcTu8oSSSmUoNJg@mail.gmail.com>
On Wednesday, September 14, 2011, Ming Lei wrote:
> Hi,
>
> On Wed, Sep 14, 2011 at 12:06 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>
> >> >> If power.lock is released, the transition states(resuming or suspending)
> >> >
> >> >> may be observed in rpm_suspend or rpm_resume, then tasks schedule
> >> >
> >> >> will be produced in these two functions,
> >> >
> >> > I don't think so, because the interrupts are still off.
> >>
> >> Yes, the interrupts are still off on local CPU, but the release of spin lock may
> >> cause another CPUs to run into rpm_suspend or rpm_resume and produce
> >> task schedule inside the two functions.
> >
> > Not for the same device, though.
>
> I think it is probable to happen on the same device in theory, see below:
>
> - suppose irq_safe is set before calling two pm_runtime_suspend below
> - suppose this patch has been applied
>
> CPU0 CPU1
> pm_runtime_suspend
> acquired power lock
> rpm_suspend
> pm_runtime_suspend
> spining power lock
> ...
> release power lock
> acquired power lock
> run .runtime_suspend
> found the dev suspending
> wait for power state and schedule
OK, I see what the problem is. The second CPU can see the status
being RPM_SUSPENDING in the irq_safe case, which isn't possible
without the patch.
Good catch!
I think in that case rpm_suspend() should just release the lock,
run cpu_relax(), reacquire the lock and go to the "repeat" label.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH] serial: sh-sci: don't filter on DMA device, use only
From: Alan Cox @ 2011-09-14 18:52 UTC (permalink / raw)
To: Vinod Koul
Cc: Paul Mundt, g.liakhovetski@gmx.de, Williams, Dan J,
magnus.damm@gmail.com, linux-sh@vger.kernel.org,
linux-kernel@vger.kernel.org, damm@opensource.se
In-Reply-To: <1315977410.26251.476.camel@vkoul-udesk3>
On Wed, 14 Sep 2011 10:46:50 +0530
Vinod Koul <vinod.koul@intel.com> wrote:
> On Fri, 2011-09-09 at 01:01 +0530, Vinod Koul wrote:
> > On Thu, 2011-09-08 at 10:21 +0900, Paul Mundt wrote:
> > > On Thu, Sep 08, 2011 at 03:07:53AM +0530, Koul, Vinod wrote:
> > > > On Wed, 2011-09-07 at 22:01 +0200, Guennadi Liakhovetski wrote:
> >
> > I relooked at the patch, since the filtering is already done in
> > your .alloc_chan_resources, (which should be fixed when we fix
> > filtering), I am going to apply this patch
> Since this is for serial driver, I can carry this patch with ACK from
> Alan or Alan can take this patch with Ack from me
Greg normally carries them but I'm happy with this going via your tree.
^ permalink raw reply
* Re: [PATCH] serial: sh-sci: don't filter on DMA device, use only
From: Vinod Koul @ 2011-09-14 5:28 UTC (permalink / raw)
To: Paul Mundt, alan
Cc: g.liakhovetski@gmx.de, Williams, Dan J, magnus.damm@gmail.com,
linux-sh@vger.kernel.org, linux-kernel@vger.kernel.org,
damm@opensource.se
In-Reply-To: <1315510263.26251.296.camel@vkoul-udesk3>
On Fri, 2011-09-09 at 01:01 +0530, Vinod Koul wrote:
> On Thu, 2011-09-08 at 10:21 +0900, Paul Mundt wrote:
> > On Thu, Sep 08, 2011 at 03:07:53AM +0530, Koul, Vinod wrote:
> > > On Wed, 2011-09-07 at 22:01 +0200, Guennadi Liakhovetski wrote:
>
> I relooked at the patch, since the filtering is already done in
> your .alloc_chan_resources, (which should be fixed when we fix
> filtering), I am going to apply this patch
Since this is for serial driver, I can carry this patch with ACK from
Alan or Alan can take this patch with Ack from me
--
~Vinod
^ permalink raw reply
* Re: [PATCH 2/5] PM / Runtime: Do not run callbacks under lock for
From: Ming Lei @ 2011-09-14 1:12 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM mailing list, LKML, Linux-sh list, Magnus Damm,
Kevin Hilman, jean.pihet
In-Reply-To: <201109131806.39050.rjw@sisk.pl>
Hi,
On Wed, Sep 14, 2011 at 12:06 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> >> If power.lock is released, the transition states(resuming or suspending)
>> >
>> >> may be observed in rpm_suspend or rpm_resume, then tasks schedule
>> >
>> >> will be produced in these two functions,
>> >
>> > I don't think so, because the interrupts are still off.
>>
>> Yes, the interrupts are still off on local CPU, but the release of spin lock may
>> cause another CPUs to run into rpm_suspend or rpm_resume and produce
>> task schedule inside the two functions.
>
> Not for the same device, though.
I think it is probable to happen on the same device in theory, see below:
- suppose irq_safe is set before calling two pm_runtime_suspend below
- suppose this patch has been applied
CPU0 CPU1
pm_runtime_suspend
acquired power lock
rpm_suspend
pm_runtime_suspend
spining power lock
...
release power lock
acquired power lock
run .runtime_suspend
found the dev suspending
wait for power state and schedule
>
> Also, I'm not quite sure what scenario exactly are you referring to.
> Could you please give an example?
I have no actual examples about it, just a theory analysis.
Also, maybe the patch below can avoid the race above.
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index a6750fc..87c9a37 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -150,6 +150,9 @@ static int rpm_check_suspend_allowed(struct device *dev)
retval = -EAGAIN;
else if (dev->power.runtime_status = RPM_SUSPENDED)
retval = 1;
+ else if (dev->power.runtime_status != RPM_ACTIVE &&
+ dev->power.irq_safe)
+ retval = -EAGAIN;
return retval;
}
thanks,
--
Ming Lei
^ permalink raw reply related
* 群发软件+买家搜索机+109届广交会买家
From: 仅10元每天 @ 2011-09-14 0:58 UTC (permalink / raw)
To: linux-sh
In-Reply-To: <20111213084743353137@amidress.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 15767 bytes --]
������������������������������������+109������������������������������������������������������������������������������������������������������������������������������������������������������������������,B2B���������������������������������������������500���������,���������10������������������������������������
���������������������������������������������������������������������������������������������������
���������������������������������������������������������������������������������������������������
1������������������������������������������������������ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5���������������������������������������������
2���������500������������������������������������������������������ ���������������������������500��������������������������������������������������������������������������������������������������� ���������
3���������������������������������������������������������������Email������������������������������������ ���������������������������������������������1-2���������������������������������������������������������������EMAIL������������������������������������������������������
������������������������������������������������������QQ: 1339625218 ������������������������������������������������������������������������: 1339625218@qq.com
������������������������������������������������������QQ: 1339625218 ������������������������������������������������������������������������: 1339625218@qq.com
������������������������������������������������������QQ: 1339625218 ������������������������������������������������������������������������: 1339625218@qq.com
������������������������������������:
������������������8������������������(������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������)���������
1���������2011������������������109���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
2������������������������������������������������������������������������������������������2011���������������������������������������������+2012���������������������������������������������������������������������������������������������������������������������������������������
3������������������������������������������������������������������������,���������451660������������������������������������ (������������������������������������������������������ 2011-05-16���������)
4���������2008���������,2009���������,2010��������� ������������������+������������������������������������������������������������������������������������������103 104 105 106 107 108 ��������������������������� ���������120.6������������������������������������
5���������2010������������������������������������������������������������������������PPAI��������������������������������������������� PPAI Members Directory������������������������������������������������������������������������������������������
6���������2010���������������������������������������������������������������������������������������������������������������������(���������������������������������������������������������������)������������������7.2������������������������������������������������������������������������������������������������������������
7���������48.68������������������������������������������������������������������������������������������������������������������������������������������������ 1-2���������������������������������������������2���������������������������1������������������������������������������������������ 2���������������������������������������������������������������������������������������������������������������������36���������������������������
8���������2009���������������������������������������������������������������piers��������������������������� 1���������������������������
������������������������������������������������������������������������������������������������������������������������������ (���������������������������������������������������������������������������������������������������������������������������������������������������������) ������������������������������������������������������ ���������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������{.n���+���������������������+%���������������������\x17������w������{.n���+������������{���������������{ay���\x1d���������������,j\a������f���������h���������������������������z_������\x03(���������������������j"������\x1a���^[m������������\a������G������������������?���������������&���������~������
^ permalink raw reply
* Re: [PATCH 2/5] PM / Runtime: Do not run callbacks under lock for power.irq_safe set
From: Rafael J. Wysocki @ 2011-09-13 16:06 UTC (permalink / raw)
To: Ming Lei
Cc: Linux PM mailing list, LKML, Linux-sh list, Magnus Damm,
Kevin Hilman, jean.pihet
In-Reply-To: <CACVXFVN5E6pToFk_nn0xgNrUW-DQzVssmPFDpHckSaHSRwWjoQ@mail.gmail.com>
On Tuesday, September 13, 2011, Ming Lei wrote:
> Hi,
>
> On Tue, Sep 13, 2011 at 5:44 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > Hi,
> >
> > On Monday, September 12, 2011, Ming Lei wrote:
> >
> >> Hi,
> >
> >>
> >
> >> On Wed, Aug 31, 2011 at 6:20 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >
> >> > From: Rafael J. Wysocki <rjw@sisk.pl>
> >
> >> >
> >
> >> > The rpm_suspend() and rpm_resume() routines execute subsystem or PM
> >
> >> > domain callbacks under power.lock if power.irq_safe is set for the
> >
> >> > given device. This is inconsistent with that rpm_idle() does after
> >
> >> > commit 02b2677 (PM / Runtime: Allow _put_sync() from
> >
> >> > interrupts-disabled context) and is problematic for subsystems and PM
> >
> >> > domains wanting to use power.lock for synchronization in their
> >
> >> > runtime PM callbacks. For this reason, make runtime PM core functions
> >
> >> > always release power.lock before invoking subsystem or PM domain
> >
> >>
> >
> >> If power.lock is released, the transition states(resuming or suspending)
> >
> >> may be observed in rpm_suspend or rpm_resume, then tasks schedule
> >
> >> will be produced in these two functions,
> >
> > I don't think so, because the interrupts are still off.
>
> Yes, the interrupts are still off on local CPU, but the release of spin lock may
> cause another CPUs to run into rpm_suspend or rpm_resume and produce
> task schedule inside the two functions.
Not for the same device, though.
Also, I'm not quite sure what scenario exactly are you referring to.
Could you please give an example?
Thanks,
Rafael
^ permalink raw reply
* 群发软件+买家搜索机+109届广交会买家
From: 仅10元每天 @ 2011-09-13 15:36 UTC (permalink / raw)
To: linux-sh
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 15767 bytes --]
������������������������������������+109������������������������������������������������������������������������������������������������������������������������������������������������������������������,B2B���������������������������������������������500���������,���������10������������������������������������
���������������������������������������������������������������������������������������������������
���������������������������������������������������������������������������������������������������
1������������������������������������������������������ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������5���������������������������������������������
2���������500������������������������������������������������������ ���������������������������500��������������������������������������������������������������������������������������������������� ���������
3���������������������������������������������������������������Email������������������������������������ ���������������������������������������������1-2���������������������������������������������������������������EMAIL������������������������������������������������������
������������������������������������������������������QQ: 1339625218 ������������������������������������������������������������������������: 1339625218@qq.com
������������������������������������������������������QQ: 1339625218 ������������������������������������������������������������������������: 1339625218@qq.com
������������������������������������������������������QQ: 1339625218 ������������������������������������������������������������������������: 1339625218@qq.com
������������������������������������:
������������������8������������������(������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������)���������
1���������2011������������������109���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
2������������������������������������������������������������������������������������������2011���������������������������������������������+2012���������������������������������������������������������������������������������������������������������������������������������������
3������������������������������������������������������������������������,���������451660������������������������������������ (������������������������������������������������������ 2011-05-16���������)
4���������2008���������,2009���������,2010��������� ������������������+������������������������������������������������������������������������������������������103 104 105 106 107 108 ��������������������������� ���������120.6������������������������������������
5���������2010������������������������������������������������������������������������PPAI��������������������������������������������� PPAI Members Directory������������������������������������������������������������������������������������������
6���������2010���������������������������������������������������������������������������������������������������������������������(���������������������������������������������������������������)������������������7.2������������������������������������������������������������������������������������������������������������
7���������48.68������������������������������������������������������������������������������������������������������������������������������������������������ 1-2���������������������������������������������2���������������������������1������������������������������������������������������ 2���������������������������������������������������������������������������������������������������������������������36���������������������������
8���������2009���������������������������������������������������������������piers��������������������������� 1���������������������������
������������������������������������������������������������������������������������������������������������������������������ (���������������������������������������������������������������������������������������������������������������������������������������������������������) ������������������������������������������������������ ���������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������������������������������-���������������������������������������������
������������{.n���+���������������������+%���������������������\x17������w������{.n���+������������{���������������{ay���\x1d���������������,j\a������f���������h���������������������������z_������\x03(���������������������j"������\x1a���^[m������������\a������G������������������?���������������&���������~������
^ permalink raw reply
* Re: [PATCH 2/5] PM / Runtime: Do not run callbacks under lock for
From: Ming Lei @ 2011-09-13 1:22 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM mailing list, LKML, Linux-sh list, Magnus Damm,
Kevin Hilman, jean.pihet
In-Reply-To: <201109122344.02386.rjw@sisk.pl>
Hi,
On Tue, Sep 13, 2011 at 5:44 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> Hi,
>
> On Monday, September 12, 2011, Ming Lei wrote:
>
>> Hi,
>
>>
>
>> On Wed, Aug 31, 2011 at 6:20 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>
>> > From: Rafael J. Wysocki <rjw@sisk.pl>
>
>> >
>
>> > The rpm_suspend() and rpm_resume() routines execute subsystem or PM
>
>> > domain callbacks under power.lock if power.irq_safe is set for the
>
>> > given device. This is inconsistent with that rpm_idle() does after
>
>> > commit 02b2677 (PM / Runtime: Allow _put_sync() from
>
>> > interrupts-disabled context) and is problematic for subsystems and PM
>
>> > domains wanting to use power.lock for synchronization in their
>
>> > runtime PM callbacks. For this reason, make runtime PM core functions
>
>> > always release power.lock before invoking subsystem or PM domain
>
>>
>
>> If power.lock is released, the transition states(resuming or suspending)
>
>> may be observed in rpm_suspend or rpm_resume, then tasks schedule
>
>> will be produced in these two functions,
>
> I don't think so, because the interrupts are still off.
Yes, the interrupts are still off on local CPU, but the release of spin lock may
cause another CPUs to run into rpm_suspend or rpm_resume and produce
task schedule inside the two functions.
>
>> so the functions below can't be
>
>>
>
>> pm_runtime_suspend()
>
>> pm_runtime_autosuspend()
>
>> pm_runtime_resume()
>
>> pm_runtime_put_sync_suspend()
>
>> pm_runtime_put_sync_autosuspend()
>
>>
>
>> called in irq-off contexts safely even though irq_safe flag is set.
>
> The patch doesn't cause rpm_suspend() and rpm_resume() to turn interrupts
>
> on if irq_safe is set, it only causes them to release the lock
> (temporarily).
thanks,
--
Ming Lei
^ permalink raw reply
* Re: [PATCH 2/5] PM / Runtime: Do not run callbacks under lock for power.irq_safe set
From: Rafael J. Wysocki @ 2011-09-12 21:52 UTC (permalink / raw)
To: Ming Lei
Cc: Linux PM mailing list, LKML, Linux-sh list, Magnus Damm,
Kevin Hilman, jean.pihet
In-Reply-To: <CACVXFVPshpc-aVHGMYWkthffMRYLFh4BadnEAhf+eQ47CwWLZw@mail.gmail.com>
On Monday, September 12, 2011, Ming Lei wrote:
> Hi,
>
> On Wed, Aug 31, 2011 at 6:20 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > From: Rafael J. Wysocki <rjw@sisk.pl>
> >
> > The rpm_suspend() and rpm_resume() routines execute subsystem or PM
> > domain callbacks under power.lock if power.irq_safe is set for the
> > given device. This is inconsistent with that rpm_idle() does after
> > commit 02b2677 (PM / Runtime: Allow _put_sync() from
> > interrupts-disabled context) and is problematic for subsystems and PM
> > domains wanting to use power.lock for synchronization in their
> > runtime PM callbacks. For this reason, make runtime PM core functions
> > always release power.lock before invoking subsystem or PM domain
>
> If power.lock is released, the transition states(resuming or suspending)
> may be observed in rpm_suspend or rpm_resume, then tasks schedule
> will be produced in these two functions,
I don't think so, because the interrupts are still off.
> so the functions below can't be
>
> pm_runtime_suspend()
> pm_runtime_autosuspend()
> pm_runtime_resume()
> pm_runtime_put_sync_suspend()
> pm_runtime_put_sync_autosuspend()
>
> called in irq-off contexts safely even though irq_safe flag is set.
The patch doesn't cause rpm_suspend() and rpm_resume() to turn interrupts
on if irq_safe is set, it only causes them to release the lock (temporarily).
Thanks,
Rafael
^ permalink raw reply
* [PATCH 2/2 v2] SPI: spi_sh_msiof: implement DMA support
From: Guennadi Liakhovetski @ 2011-09-12 9:27 UTC (permalink / raw)
To: spi-devel-general; +Cc: linux-sh, Grant Likely, Magnus Damm
In-Reply-To: <Pine.LNX.4.64.1109121118500.9638@axis700.grange>
Use the sh_dma dmaengine driver to support DMA on MSIOF.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
v2: extracted the "unbalanced spi_master_put()" fix into a separate patch
drivers/spi/spi-sh-msiof.c | 392 +++++++++++++++++++++++++++++++++++++++---
include/linux/spi/sh_msiof.h | 2 +
2 files changed, 366 insertions(+), 28 deletions(-)
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index 722dad5..8622b32 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -13,14 +13,18 @@
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/mm.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/sh_dma.h>
#include <linux/spi/sh_msiof.h>
#include <linux/spi/spi.h>
@@ -28,6 +32,13 @@
#include <asm/unaligned.h>
+struct sh_msiof_dma {
+ struct sh_dmae_slave dma_slave;
+ struct dma_chan *chan;
+ struct sg_table sg;
+ struct dma_async_tx_descriptor *desc;
+};
+
struct sh_msiof_spi_priv {
struct spi_bitbang bitbang; /* must be first for spi_bitbang.c */
void __iomem *mapbase;
@@ -38,6 +49,10 @@ struct sh_msiof_spi_priv {
unsigned long flags;
int tx_fifo_size;
int rx_fifo_size;
+ struct sh_msiof_dma dma_tx;
+ struct sh_msiof_dma dma_rx;
+ struct completion dma_done;
+ struct page *dummypage;
};
#define TMDR1 0x00
@@ -64,8 +79,12 @@ struct sh_msiof_spi_priv {
#define CTR_TXE (1 << 9)
#define CTR_RXE (1 << 8)
-#define STR_TEOF (1 << 23)
-#define STR_REOF (1 << 7)
+#define IER_TDMA (1 << 31)
+#define IER_TDREQ (1 << 28)
+#define IER_TEOF (1 << 23)
+#define IER_RDMA (1 << 15)
+#define IER_RDREQ (1 << 12)
+#define IER_REOF (1 << 7)
static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs)
{
@@ -208,8 +227,6 @@ static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p,
if (rx_buf)
sh_msiof_write(p, RMDR2, dr2);
-
- sh_msiof_write(p, IER, STR_TEOF | STR_REOF);
}
static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p)
@@ -401,9 +418,9 @@ static void sh_msiof_spi_chipselect(struct spi_device *spi, int is_on)
/* chip select is active low unless SPI_CS_HIGH is set */
if (spi->mode & SPI_CS_HIGH)
- value = (is_on = BITBANG_CS_ACTIVE) ? 1 : 0;
+ value = is_on = BITBANG_CS_ACTIVE;
else
- value = (is_on = BITBANG_CS_ACTIVE) ? 0 : 1;
+ value = is_on != BITBANG_CS_ACTIVE;
if (is_on = BITBANG_CS_ACTIVE) {
if (!test_and_set_bit(0, &p->flags)) {
@@ -429,6 +446,36 @@ static void sh_msiof_spi_chipselect(struct spi_device *spi, int is_on)
}
}
+static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf)
+{
+ /* setup clock and rx/tx signals */
+ int ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE);
+ if (rx_buf && !ret)
+ ret = sh_msiof_modify_ctr_wait(p, 0, CTR_RXE);
+ if (!ret)
+ ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TXE);
+
+ /* start by setting frame bit */
+ if (!ret)
+ ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE);
+
+ return ret;
+}
+
+static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf)
+{
+ /* shut down frame, tx/tx and clock signals */
+ int ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0);
+ if (!ret)
+ ret = sh_msiof_modify_ctr_wait(p, CTR_TXE, 0);
+ if (rx_buf && !ret)
+ ret = sh_msiof_modify_ctr_wait(p, CTR_RXE, 0);
+ if (!ret)
+ ret = sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0);
+
+ return ret;
+}
+
static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
void (*tx_fifo)(struct sh_msiof_spi_priv *,
const void *, int, int),
@@ -456,16 +503,11 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
if (tx_buf)
tx_fifo(p, tx_buf, words, fifo_shift);
- /* setup clock and rx/tx signals */
- ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE);
- if (rx_buf)
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_RXE);
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TXE);
-
- /* start by setting frame bit */
INIT_COMPLETION(p->done);
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE);
- if (ret) {
+ sh_msiof_write(p, IER, IER_TEOF | IER_REOF);
+
+ ret = sh_msiof_spi_start(p, rx_buf);
+ if (ret < 0) {
dev_err(&p->pdev->dev, "failed to start hardware\n");
goto err;
}
@@ -480,13 +522,8 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
/* clear status bits */
sh_msiof_reset_str(p);
- /* shut down frame, tx/tx and clock signals */
- ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0);
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_TXE, 0);
- if (rx_buf)
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_RXE, 0);
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0);
- if (ret) {
+ ret = sh_msiof_spi_stop(p, rx_buf);
+ if (ret < 0) {
dev_err(&p->pdev->dev, "failed to shut down hardware\n");
goto err;
}
@@ -498,6 +535,220 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
return ret;
}
+static void sh_msiof_setup_sg(struct sh_msiof_spi_priv *p,
+ const void *buffer,
+ unsigned int length,
+ struct sg_table *sgtab)
+{
+ struct scatterlist *sg;
+ int bytesleft = length;
+ const void *bufp = buffer;
+ int mapbytes;
+ int i;
+
+ if (buffer) {
+ for_each_sg(sgtab->sgl, sg, sgtab->nents, i) {
+ /*
+ * If there are fewer bytes left than what fits
+ * in the current page (plus page alignment offset)
+ * we just feed in this, else we stuff in as much
+ * as we can.
+ */
+ if (bytesleft < (PAGE_SIZE - offset_in_page(bufp)))
+ mapbytes = bytesleft;
+ else
+ mapbytes = PAGE_SIZE - offset_in_page(bufp);
+ sg_set_page(sg, virt_to_page(bufp),
+ mapbytes, offset_in_page(bufp));
+ bytesleft -= mapbytes;
+ bufp += mapbytes;
+ }
+ } else {
+ /* Map the dummy buffer on every page */
+ for_each_sg(sgtab->sgl, sg, sgtab->nents, i) {
+ if (bytesleft < PAGE_SIZE)
+ mapbytes = bytesleft;
+ else
+ mapbytes = PAGE_SIZE;
+ sg_set_page(sg, p->dummypage, mapbytes, 0);
+ bytesleft -= mapbytes;
+ }
+ }
+ BUG_ON(bytesleft);
+}
+
+static int sh_msiof_spi_setup_xfer_dma(struct sh_msiof_spi_priv *p, struct sh_msiof_dma *dma,
+ const void *buffer, size_t len, enum dma_data_direction dir)
+{
+ int ret, sglen;
+ unsigned int pages;
+ unsigned long flags = DMA_CTRL_ACK;
+
+ /* Create sglists for the transfers */
+ pages = (PAGE_ALIGN(len) >> PAGE_SHIFT);
+
+ ret = sg_alloc_table(&dma->sg, pages, GFP_KERNEL);
+ if (ret < 0)
+ return ret;
+
+ sh_msiof_setup_sg(p, buffer, len, &dma->sg);
+
+ /* Map DMA buffers */
+ sglen = dma_map_sg(&p->pdev->dev, dma->sg.sgl,
+ dma->sg.orig_nents, dir);
+ if (sglen < 0) {
+ ret = sglen;
+ goto emapsg;
+ } else if (!sglen) {
+ ret = -EINVAL;
+ goto emapsg;
+ }
+
+ if (dir = DMA_FROM_DEVICE)
+ flags |= DMA_PREP_INTERRUPT;
+
+ dma->desc = dma->chan->device->device_prep_slave_sg(dma->chan,
+ dma->sg.sgl, sglen, dir, flags);
+ if (!dma->desc) {
+ ret = -ENOMEM;
+ goto edmaprep;
+ }
+
+ dma->sg.nents = sglen;
+
+ return 0;
+
+edmaprep:
+ dma_unmap_sg(&p->pdev->dev, dma->sg.sgl, sglen, dir);
+emapsg:
+ sg_free_table(&dma->sg);
+
+ return ret;
+}
+
+static void sh_msiof_spi_free_xfer_dma(struct sh_msiof_spi_priv *p, struct sh_msiof_dma *dma,
+ enum dma_data_direction dir)
+{
+ dma_unmap_sg(&p->pdev->dev, dma->sg.sgl, dma->sg.nents, dir);
+ sg_free_table(&dma->sg);
+}
+
+static void sh_msiof_spi_dma_callback(void *arg)
+{
+ struct sh_msiof_spi_priv *p = arg;
+
+ dma_sync_sg_for_device(&p->pdev->dev, p->dma_rx.sg.sgl,
+ p->dma_rx.sg.nents, DMA_FROM_DEVICE);
+
+ sh_msiof_spi_free_xfer_dma(p, &p->dma_rx, DMA_FROM_DEVICE);
+ sh_msiof_spi_free_xfer_dma(p, &p->dma_tx, DMA_TO_DEVICE);
+
+ complete(&p->dma_done);
+}
+
+static int sh_msiof_spi_txrx_dma_single(struct sh_msiof_spi_priv *p, int bits,
+ const void *tx_buf, const void *rx_buf, size_t len)
+{
+ int ret, cookie, words;
+
+ if (bits <= 8)
+ words = len;
+ else if (bits <= 16)
+ words = len >> 1;
+ else
+ words = len >> 2;
+
+ ret = sh_msiof_spi_setup_xfer_dma(p, &p->dma_tx, tx_buf, len, DMA_TO_DEVICE);
+ if (ret < 0)
+ return ret;
+
+ dma_sync_sg_for_device(&p->pdev->dev, p->dma_tx.sg.sgl,
+ p->dma_tx.sg.nents, DMA_TO_DEVICE);
+
+ ret = sh_msiof_spi_setup_xfer_dma(p, &p->dma_rx, rx_buf, len, DMA_FROM_DEVICE);
+ if (ret < 0)
+ goto esdmarx;
+
+ /* Put the callback on the RX transfer only, that should finish last */
+ p->dma_rx.desc->callback = sh_msiof_spi_dma_callback;
+ p->dma_rx.desc->callback_param = p;
+
+ /* Submit and fire RX and TX with TX last so we're ready to read! */
+ cookie = p->dma_rx.desc->tx_submit(p->dma_rx.desc);
+ if (dma_submit_error(cookie)) {
+ ret = cookie;
+ goto esubmitrx;
+ }
+ p->dma_rx.chan->device->device_issue_pending(p->dma_rx.chan);
+
+ /* setup msiof transfer mode registers */
+ sh_msiof_spi_set_mode_regs(p, tx_buf, p->dummypage, bits, words);
+
+ cookie = p->dma_tx.desc->tx_submit(p->dma_tx.desc);
+ if (dma_submit_error(cookie)) {
+ ret = cookie;
+ goto esubmittx;
+ }
+ p->dma_tx.chan->device->device_issue_pending(p->dma_tx.chan);
+
+ INIT_COMPLETION(p->dma_done);
+ sh_msiof_write(p, IER, IER_RDREQ | IER_TDREQ | IER_RDMA | IER_TDMA);
+
+ /* As long as there's something to send, we'll also be receiving. */
+ ret = sh_msiof_spi_start(p, p->dummypage);
+ if (ret < 0) {
+ dev_err(&p->pdev->dev, "failed to start hardware: %d\n", ret);
+ goto espistart;
+ }
+
+ wait_for_completion(&p->dma_done);
+
+ /* clear status bits */
+ sh_msiof_reset_str(p);
+
+ ret = sh_msiof_spi_stop(p, p->dummypage);
+ if (ret < 0) {
+ dev_err(&p->pdev->dev, "failed to stop hardware: %d\n", ret);
+ goto espistop;
+ }
+
+ return len;
+
+espistop:
+espistart:
+ dmaengine_device_control(p->dma_tx.chan, DMA_TERMINATE_ALL, 0);
+esubmittx:
+ dmaengine_device_control(p->dma_rx.chan, DMA_TERMINATE_ALL, 0);
+esubmitrx:
+ sh_msiof_spi_free_xfer_dma(p, &p->dma_rx, DMA_FROM_DEVICE);
+esdmarx:
+ sh_msiof_spi_free_xfer_dma(p, &p->dma_tx, DMA_TO_DEVICE);
+
+ return ret;
+}
+
+static int sh_msiof_spi_txrx_dma(struct sh_msiof_spi_priv *p, struct spi_transfer *t, int bits)
+{
+ int i, ret = 0;
+ size_t left = t->len;
+ off_t offs = 0;
+
+ /* Up to 256 words per group, we only use a single group */
+ for (i = 0; i < (t->len + 255) / 256; i++) {
+ const void *rx_buf = t->rx_buf ? t->rx_buf + offs : NULL;
+ const void *tx_buf = t->tx_buf ? t->tx_buf + offs : NULL;
+
+ ret = sh_msiof_spi_txrx_dma_single(p, bits, tx_buf, rx_buf,
+ min_t(size_t, left, 256));
+ if (ret < 0)
+ return ret;
+ left -= ret;
+ offs += ret;
+ }
+
+ return ret <= 0 ? ret : t->len;
+}
+
static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
{
struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master);
@@ -512,6 +763,19 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
bits = sh_msiof_spi_bits(spi, t);
+ /* setup clocks (clock already enabled in chipselect()) */
+ sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk),
+ sh_msiof_spi_hz(spi, t));
+
+ if (p->dma_rx.chan && p->dma_tx.chan && t->len > 15 &&
+ !(t->len & 3) && !((int)t->rx_buf & 3) && !((int)t->tx_buf & 3)) {
+ int ret = sh_msiof_spi_txrx_dma(p, t, bits);
+ if (ret < 0)
+ dev_warn(&spi->dev, "fall back to PIO: %d\n", ret);
+ else
+ return ret;
+ }
+
if (bits <= 8 && t->len > 15 && !(t->len & 3)) {
bits = 32;
swab = true;
@@ -559,10 +823,6 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
rx_fifo = sh_msiof_spi_read_fifo_32;
}
- /* setup clocks (clock already enabled in chipselect()) */
- sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk),
- sh_msiof_spi_hz(spi, t));
-
/* transfer in fifo sized chunks */
words = t->len / bytes_per_word;
bytes_done = 0;
@@ -591,6 +851,78 @@ static u32 sh_msiof_spi_txrx_word(struct spi_device *spi, unsigned nsecs,
return 0;
}
+static bool sh_msiof_filter(struct dma_chan *chan, void *arg)
+{
+ dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg);
+ chan->private = arg;
+ return true;
+}
+
+static void sh_msiof_request_dma(struct sh_msiof_spi_priv *p)
+{
+ struct sh_dmae_slave *tx = &p->dma_tx.dma_slave,
+ *rx = &p->dma_rx.dma_slave;
+ dma_cap_mask_t mask;
+
+ tx->slave_id = p->info->slave_id_tx;
+ rx->slave_id = p->info->slave_id_rx;
+
+ /* We can only either use DMA for both Tx and Rx or not use it at all */
+ if (tx->slave_id <= 0 || rx->slave_id <= 0)
+ return;
+
+ dev_warn(&p->pdev->dev, "Experimental DMA support enabled.\n");
+
+ p->dummypage = alloc_page(GFP_KERNEL);
+ if (!p->dummypage)
+ return;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ p->dma_tx.chan = dma_request_channel(mask, sh_msiof_filter, tx);
+ dev_dbg(&p->pdev->dev, "%s: TX: got channel %p\n", __func__,
+ p->dma_tx.chan);
+
+ if (!p->dma_tx.chan)
+ goto echantx;
+
+ p->dma_rx.chan = dma_request_channel(mask, sh_msiof_filter, rx);
+ dev_dbg(&p->pdev->dev, "%s: RX: got channel %p\n", __func__,
+ p->dma_rx.chan);
+
+ if (!p->dma_rx.chan)
+ goto echanrx;
+
+ init_completion(&p->dma_done);
+
+ return;
+
+echanrx:
+ dma_release_channel(p->dma_tx.chan);
+ p->dma_tx.chan = NULL;
+echantx:
+ __free_pages(p->dummypage, 0);
+}
+
+static void sh_msiof_release_dma(struct sh_msiof_spi_priv *p)
+{
+ /* Descriptors are freed automatically */
+ if (p->dma_tx.chan) {
+ struct dma_chan *chan = p->dma_tx.chan;
+ p->dma_tx.chan = NULL;
+ dma_release_channel(chan);
+ }
+ if (p->dma_rx.chan) {
+ struct dma_chan *chan = p->dma_rx.chan;
+ p->dma_rx.chan = NULL;
+ dma_release_channel(chan);
+ }
+
+ if (p->dummypage)
+ __free_pages(p->dummypage, 0);
+}
+
static int sh_msiof_spi_probe(struct platform_device *pdev)
{
struct resource *r;
@@ -645,6 +977,8 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
p->pdev = pdev;
pm_runtime_enable(&pdev->dev);
+ sh_msiof_request_dma(p);
+
/* The standard version of MSIOF use 64 word FIFOs */
p->tx_fifo_size = 64;
p->rx_fifo_size = 64;
@@ -656,8 +990,8 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
p->rx_fifo_size = p->info->rx_fifo_override;
/* init master and bitbang code */
- master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
- master->mode_bits |= SPI_LSB_FIRST | SPI_3WIRE;
+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
+ SPI_LSB_FIRST | SPI_3WIRE;
master->flags = 0;
master->bus_num = pdev->id;
master->num_chipselect = p->info->num_chipselect;
@@ -677,6 +1011,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
if (ret = 0)
return 0;
+ sh_msiof_release_dma(p);
pm_runtime_disable(&pdev->dev);
err3:
iounmap(p->mapbase);
@@ -695,6 +1030,7 @@ static int sh_msiof_spi_remove(struct platform_device *pdev)
ret = spi_bitbang_stop(&p->bitbang);
if (!ret) {
+ sh_msiof_release_dma(p);
pm_runtime_disable(&pdev->dev);
free_irq(platform_get_irq(pdev, 0), p);
iounmap(p->mapbase);
diff --git a/include/linux/spi/sh_msiof.h b/include/linux/spi/sh_msiof.h
index 2e8db3d..69c0f6e 100644
--- a/include/linux/spi/sh_msiof.h
+++ b/include/linux/spi/sh_msiof.h
@@ -5,6 +5,8 @@ struct sh_msiof_spi_info {
int tx_fifo_override;
int rx_fifo_override;
u16 num_chipselect;
+ unsigned int slave_id_tx;
+ unsigned int slave_id_rx;
};
#endif /* __SPI_SH_MSIOF_H__ */
--
1.7.2.5
^ permalink raw reply related
* [PATCH 1/2 v2] SPI: spi-sh-msiof: remove unbalanced spi_master_put()
From: Guennadi Liakhovetski @ 2011-09-12 9:27 UTC (permalink / raw)
To: spi-devel-general; +Cc: linux-sh, Grant Likely, Magnus Damm
In-Reply-To: <Pine.LNX.4.64.1109121118500.9638@axis700.grange>
The call to spi_bitbang_stop() in sh_msiof_spi_remove() already releases
the master, which can be verified by checking, that the
spi_master_release() function gets called. Therefore the call to
spi_master_put() in sh_msiof_spi_remove() in this driver is superfluous.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
drivers/spi/spi-sh-msiof.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index e00d94b..722dad5 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -699,7 +699,6 @@ static int sh_msiof_spi_remove(struct platform_device *pdev)
free_irq(platform_get_irq(pdev, 0), p);
iounmap(p->mapbase);
clk_put(p->clk);
- spi_master_put(p->bitbang.master);
}
return ret;
}
--
1.7.2.5
^ permalink raw reply related
* [PATCH 0/2 v2] spi: MSIOF: unbalanced spi_master_put() + DMA
From: Guennadi Liakhovetski @ 2011-09-12 9:27 UTC (permalink / raw)
To: spi-devel-general; +Cc: linux-sh, Grant Likely, Magnus Damm
In-Reply-To: <Pine.LNX.4.64.1109021712180.4731@axis700.grange>
Hi
As requested by Magnus, I'm splitting v1 of the "SPI: spi_sh_msiof:
implement DMA support" patch
http://marc.info/?l=linux-sh&m\x131497642316782&w=2
in two, separating the "unbalanced spi_master_put()" fix into a separate
patch. Otherwise no changes. Patch "sh: use DMA with MSIOF SPI on the
sh7724 ecovec board"
http://marc.info/?l=linux-sh&m\x131497642716790&w=2
is unchanged, so, not re-posted.
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* Re: [PATCH 2/5] PM / Runtime: Do not run callbacks under lock for
From: Ming Lei @ 2011-09-12 8:26 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM mailing list, LKML, Linux-sh list, Magnus Damm,
Kevin Hilman, jean.pihet
In-Reply-To: <201108310020.26104.rjw@sisk.pl>
Hi,
On Wed, Aug 31, 2011 at 6:20 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
>
> The rpm_suspend() and rpm_resume() routines execute subsystem or PM
> domain callbacks under power.lock if power.irq_safe is set for the
> given device. This is inconsistent with that rpm_idle() does after
> commit 02b2677 (PM / Runtime: Allow _put_sync() from
> interrupts-disabled context) and is problematic for subsystems and PM
> domains wanting to use power.lock for synchronization in their
> runtime PM callbacks. For this reason, make runtime PM core functions
> always release power.lock before invoking subsystem or PM domain
If power.lock is released, the transition states(resuming or suspending)
may be observed in rpm_suspend or rpm_resume, then tasks schedule
will be produced in these two functions, so the functions below can't be
pm_runtime_suspend()
pm_runtime_autosuspend()
pm_runtime_resume()
pm_runtime_put_sync_suspend()
pm_runtime_put_sync_autosuspend()
called in irq-off contexts safely even though irq_safe flag is set.
> callbacks.
>
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
> ---
> drivers/base/power/runtime.c | 50 ++++++++++++++++++++++++-------------------
> 1 file changed, 28 insertions(+), 22 deletions(-)
>
> Index: linux/drivers/base/power/runtime.c
> =================================> --- linux.orig/drivers/base/power/runtime.c
> +++ linux/drivers/base/power/runtime.c
> @@ -155,6 +155,31 @@ static int rpm_check_suspend_allowed(str
> }
>
> /**
> + * __rpm_callback - Run a given runtime PM callback for a given device.
> + * @cb: Runtime PM callback to run.
> + * @dev: Device to run the callback for.
> + */
> +static int __rpm_callback(int (*cb)(struct device *), struct device *dev)
> + __releases(&dev->power.lock) __acquires(&dev->power.lock)
> +{
> + int retval;
> +
> + if (dev->power.irq_safe)
> + spin_unlock(&dev->power.lock);
> + else
> + spin_unlock_irq(&dev->power.lock);
> +
> + retval = cb(dev);
> +
> + if (dev->power.irq_safe)
> + spin_lock(&dev->power.lock);
> + else
> + spin_lock_irq(&dev->power.lock);
> +
> + return retval;
> +}
> +
> +/**
> * rpm_idle - Notify device bus type if the device can be suspended.
> * @dev: Device to notify the bus type about.
> * @rpmflags: Flag bits.
> @@ -225,19 +250,8 @@ static int rpm_idle(struct device *dev,
> else
> callback = NULL;
>
> - if (callback) {
> - if (dev->power.irq_safe)
> - spin_unlock(&dev->power.lock);
> - else
> - spin_unlock_irq(&dev->power.lock);
> -
> - callback(dev);
> -
> - if (dev->power.irq_safe)
> - spin_lock(&dev->power.lock);
> - else
> - spin_lock_irq(&dev->power.lock);
> - }
> + if (callback)
> + __rpm_callback(callback, dev);
>
> dev->power.idle_notification = false;
> wake_up_all(&dev->power.wait_queue);
> @@ -252,22 +266,14 @@ static int rpm_idle(struct device *dev,
> * @dev: Device to run the callback for.
> */
> static int rpm_callback(int (*cb)(struct device *), struct device *dev)
> - __releases(&dev->power.lock) __acquires(&dev->power.lock)
> {
> int retval;
>
> if (!cb)
> return -ENOSYS;
>
> - if (dev->power.irq_safe) {
> - retval = cb(dev);
> - } else {
> - spin_unlock_irq(&dev->power.lock);
> -
> - retval = cb(dev);
> + retval = __rpm_callback(cb, dev);
>
> - spin_lock_irq(&dev->power.lock);
> - }
> dev->power.runtime_error = retval;
> return retval != -EACCES ? retval : -EIO;
> }
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
thanks,
--
Ming Lei
^ permalink raw reply
* Business transaction.
From: Mr. Daniel Tsai @ 2011-09-11 15:07 UTC (permalink / raw)
To: danieltsai0
Hello my friend. My name is Daniel Tsai and
I live in Hong Kong. I want you to be my
partner in a business transaction of 44.5Million USD.
If you are interested for more details,
you MUST reply me to my private email address:
danieltsai11@yahoo.com.hk or danieltsai95@aol.com
when I get your message, I will tell you what
to do next. Thank you.
Mr. Daniel Tsai
^ permalink raw reply
* Re: [PATCH 0/5] Convert ARM subarchitectures to generic wfi macro.
From: Russell King - ARM Linux @ 2011-09-09 19:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110909154254.GA23810@elliptictech.com>
On Fri, Sep 09, 2011 at 11:42:54AM -0400, Nick Bowler wrote:
> And after all that, I forgot to CC Russell on these patches. Oops.
Doesn't matter, I get them anyway (provided lakml is in the cc).
^ permalink raw reply
* [PATCH] V4L: sh_mobile_csi2: fix unbalanced pm_runtime_put()
From: Guennadi Liakhovetski @ 2011-09-09 17:14 UTC (permalink / raw)
To: Linux Media Mailing List; +Cc: linux-sh
If the sh_mobile_csi2 driver didn't attach to a client, normally, because
the respective device connects to the SoC over the parallel CEU interface
and doesn't use the CSI-2 controller, it also shouldn't call
pm_runtime_put() on attempted disconnect.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
If it also applies to the current Linus' tree, it could be a good idea to
push it to 3.1. But in practice it's not a very serious bug, it would only
affect systems with a serial / CSI-2 _and_ a parallel cameras connected
simultaneously to one CEU interface, where the user switches between them
at runtime. In any case it should be trivial to backport it to 3.1.
drivers/media/video/sh_mobile_csi2.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c
index 91c680a..37706eb 100644
--- a/drivers/media/video/sh_mobile_csi2.c
+++ b/drivers/media/video/sh_mobile_csi2.c
@@ -208,6 +208,9 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv)
unsigned long common_flags, csi2_flags;
int i, ret;
+ if (priv->client)
+ return -EBUSY;
+
for (i = 0; i < pdata->num_clients; i++)
if (&pdata->clients[i].pdev->dev = icd->pdev)
break;
@@ -262,6 +265,9 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv)
static void sh_csi2_client_disconnect(struct sh_csi2 *priv)
{
+ if (!priv->client)
+ return;
+
priv->client = NULL;
pm_runtime_put(v4l2_get_subdevdata(&priv->subdev));
--
1.7.2.5
^ permalink raw reply related
* Re: [PATCH 0/5] Convert ARM subarchitectures to generic wfi macro.
From: Nick Bowler @ 2011-09-09 15:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1315582012-23507-1-git-send-email-nbowler@elliptictech.com>
And after all that, I forgot to CC Russell on these patches. Oops.
On 2011-09-09 11:26 -0400, Nick Bowler wrote:
> This series cleans up all remaining ARM subarchitectures that I could
> find to use the generic wfi macro. As I don't have any of the boards in
> question, I've only compile-tested these patches to the extent that I
> was able.
>
> See the previous discussion in https://lkml.org/lkml/2011/8/19/433 for
> more background.
>
> Nick Bowler (5):
> ARM: realview: Use wfi macro in platform_do_lowpower.
> ARM: exynos4: Use wfi macro in platform_do_lowpower.
> ARM: shmobile: Use wfi macro in platform_cpu_die.
> ARM: tegra: Use wfi macro in platform_do_lowpower.
> ARM: omap4: Kill private do_wfi macro.
>
> arch/arm/mach-exynos4/hotplug.c | 9 ++-------
> arch/arm/mach-omap2/include/mach/omap4-common.h | 11 -----------
> arch/arm/mach-omap2/omap-hotplug.c | 7 +++----
> arch/arm/mach-omap2/pm44xx.c | 4 +++-
> arch/arm/mach-realview/hotplug.c | 9 ++-------
> arch/arm/mach-shmobile/hotplug.c | 10 +++-------
> arch/arm/mach-tegra/hotplug.c | 9 ++-------
> 7 files changed, 15 insertions(+), 44 deletions(-)
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
^ permalink raw reply
* [PATCH 3/5] ARM: shmobile: Use wfi macro in platform_cpu_die.
From: Nick Bowler @ 2011-09-09 15:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1315582012-23507-1-git-send-email-nbowler@elliptictech.com>
Current Shmobile CPU hotplug code includes a hardcoded WFI instruction,
in ARM encoding. The hardcoded instruction is both hard to understand
and doomed to failure when building the kernel in Thumb-2 mode.
Signed-off-by: Nick Bowler <nbowler@elliptictech.com>
---
Compile tested in both ARM and Thumb-2 mode, and the resulting hotplug.o
contains the correct instruction sequence, but the final kernel failed
to link for apparently unrelated reasons:
In ARM mode:
LD .tmp_vmlinux1
arch/arm/kernel/built-in.o: In function `twd_timer_setup':
io.c:(.cpuinit.text+0x600): undefined reference to `gic_enable_ppi'
arch/arm/mach-shmobile/built-in.o: In function `smp_init_cpus':
pfc-sh7372.c:(.init.text+0xbb0): undefined reference to `gic_raise_softirq'
In Thumb-2 mode:
LD .tmp_vmlinux1
arch/arm/kernel/built-in.o: In function `get_wchan':
io.c:(.text+0x1542): undefined reference to `unwind_frame'
arch/arm/kernel/built-in.o: In function `walk_stackframe':
io.c:(.text+0x27f0): undefined reference to `unwind_frame'
arch/arm/kernel/built-in.o: In function `profile_pc':
io.c:(.text+0x2828): undefined reference to `unwind_frame'
arch/arm/kernel/built-in.o: In function `twd_timer_setup':
io.c:(.cpuinit.text+0x42e): undefined reference to `gic_enable_ppi'
arch/arm/mach-shmobile/built-in.o: In function `smp_init_cpus':
pfc-sh7372.c:(.init.text+0x8e8): undefined reference to `gic_raise_softirq'
---
arch/arm/mach-shmobile/hotplug.c | 10 +++-------
1 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c
index 238a0d9..1e83087 100644
--- a/arch/arm/mach-shmobile/hotplug.c
+++ b/arch/arm/mach-shmobile/hotplug.c
@@ -13,6 +13,8 @@
#include <linux/errno.h>
#include <linux/smp.h>
+#include <asm/system.h>
+
int platform_cpu_kill(unsigned int cpu)
{
return 1;
@@ -21,13 +23,7 @@ int platform_cpu_kill(unsigned int cpu)
void platform_cpu_die(unsigned int cpu)
{
while (1) {
- /*
- * here's the WFI
- */
- asm(".word 0xe320f003\n"
- :
- :
- : "memory", "cc");
+ wfi();
}
}
--
1.7.3.4
^ 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