* [PATCH v5 3/5] OMAP4: hwmod data: add mailbox data
From: Cousson, Benoit @ 2011-02-15 22:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTinA2a60TSM7qDC1LQiRaUTs0DR3bDMv+oVsVOE0@mail.gmail.com>
Hi Omar,
On 2/15/2011 10:55 PM, Ramirez Luna, Omar wrote:
> Hi Benoit,
>
> On Mon, Feb 14, 2011 at 9:00 AM, Cousson, Benoit<b-cousson@ti.com> wrote:
>>> +static struct omap_hwmod_irq_info omap44xx_mailbox_irqs[] = {
>>> + { .name = "mbox", .irq = 26 + OMAP44XX_IRQ_GIC_START, },
>>
>> The original entry was unnamed since it is an unique entry and thus does not
>> need to be differentiate on this platform.
>>
>> { .irq = 26 + OMAP44XX_IRQ_GIC_START },
>>
>> Do you really need to have a name here? The strategy being to provide a name
>> only if more than one entry exist.
>> It is perfectibility doable, I'm just trying to understand your rational.
>
> It is this way instead of plain platform_get_irq because omap2420 has
> two interrupt sources to MPU and mailbox driver uses
> platform_get_irq_byname to get the irq number.
This is what I was thinking, except that on OMAP2420 the names are:
+ { .name = "dsp", .irq = 26, },
+ { .name = "iva", .irq = 34, },
and on OMAP2430 and OMAP3
+ { .name = "dsp", .irq = 26, },
so why is it named "mbox" on OMAP4?
If you have to do several platform_get_irq_byname to get this one, I'd
prefer to get rid of that name for OMAP4. It will make mailbox irq
consistent with the other hwmods.
Thanks,
Benoit
^ permalink raw reply
* [PATCH 1/4] spi/pl022: use dmaengine helper macros
From: Grant Likely @ 2011-02-15 22:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297166592-5098-1-git-send-email-linus.walleij@stericsson.com>
On Tue, Feb 08, 2011 at 01:03:12PM +0100, Linus Walleij wrote:
> This simplifies the DMA code a bit by using the dmaengine helpers.
> The cookie from descriptor submission can be ignored in this case
> as has been established in review of the MMCI/PL180 driver.
>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied, thanks.
g.
> ---
> drivers/spi/amba-pl022.c | 27 ++++++++++-----------------
> 1 files changed, 10 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
> index 71a1219..4220aad 100644
> --- a/drivers/spi/amba-pl022.c
> +++ b/drivers/spi/amba-pl022.c
> @@ -917,7 +917,6 @@ static int configure_dma(struct pl022 *pl022)
> struct dma_chan *txchan = pl022->dma_tx_channel;
> struct dma_async_tx_descriptor *rxdesc;
> struct dma_async_tx_descriptor *txdesc;
> - dma_cookie_t cookie;
>
> /* Check that the channels are available */
> if (!rxchan || !txchan)
> @@ -962,10 +961,8 @@ static int configure_dma(struct pl022 *pl022)
> tx_conf.dst_addr_width = rx_conf.src_addr_width;
> BUG_ON(rx_conf.src_addr_width != tx_conf.dst_addr_width);
>
> - rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG,
> - (unsigned long) &rx_conf);
> - txchan->device->device_control(txchan, DMA_SLAVE_CONFIG,
> - (unsigned long) &tx_conf);
> + dmaengine_slave_config(rxchan, &rx_conf);
> + dmaengine_slave_config(txchan, &tx_conf);
>
> /* Create sglists for the transfers */
> pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1;
> @@ -1018,23 +1015,19 @@ static int configure_dma(struct pl022 *pl022)
> rxdesc->callback_param = pl022;
>
> /* Submit and fire RX and TX with TX last so we're ready to read! */
> - cookie = rxdesc->tx_submit(rxdesc);
> - if (dma_submit_error(cookie))
> - goto err_submit_rx;
> - cookie = txdesc->tx_submit(txdesc);
> - if (dma_submit_error(cookie))
> - goto err_submit_tx;
> - rxchan->device->device_issue_pending(rxchan);
> - txchan->device->device_issue_pending(txchan);
> + dmaengine_submit(rxdesc);
> + dmaengine_submit(txdesc);
> + dma_async_issue_pending(rxchan);
> + dma_async_issue_pending(txchan);
>
> return 0;
>
> err_submit_tx:
> err_submit_rx:
> err_txdesc:
> - txchan->device->device_control(txchan, DMA_TERMINATE_ALL, 0);
> + dmaengine_terminate_all(txchan);
> err_rxdesc:
> - rxchan->device->device_control(rxchan, DMA_TERMINATE_ALL, 0);
> + dmaengine_terminate_all(rxchan);
> dma_unmap_sg(txchan->device->dev, pl022->sgt_tx.sgl,
> pl022->sgt_tx.nents, DMA_TO_DEVICE);
> err_tx_sgmap:
> @@ -1101,8 +1094,8 @@ static void terminate_dma(struct pl022 *pl022)
> struct dma_chan *rxchan = pl022->dma_rx_channel;
> struct dma_chan *txchan = pl022->dma_tx_channel;
>
> - rxchan->device->device_control(rxchan, DMA_TERMINATE_ALL, 0);
> - txchan->device->device_control(txchan, DMA_TERMINATE_ALL, 0);
> + dmaengine_terminate_all(rxchan);
> + dmaengine_terminate_all(txchan);
> unmap_free_dma_scatter(pl022);
> }
>
> --
> 1.7.3.2
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 2/4] spi/pl022: disable core voltage when idle
From: Grant Likely @ 2011-02-15 22:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297166612-5135-1-git-send-email-linus.walleij@stericsson.com>
On Tue, Feb 08, 2011 at 01:03:32PM +0100, Linus Walleij wrote:
> This utilizes the new core voltage switch to power off the PL022
> core voltage when it's not in use transmitting packets, if and
> only if a core voltage switch is available.
>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied, thanks.
g.
> ---
> drivers/spi/amba-pl022.c | 17 +++++++++++++----
> 1 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
> index 4220aad..8fdf530 100644
> --- a/drivers/spi/amba-pl022.c
> +++ b/drivers/spi/amba-pl022.c
> @@ -508,9 +508,10 @@ static void giveback(struct pl022 *pl022)
> msg->state = NULL;
> if (msg->complete)
> msg->complete(msg->context);
> - /* This message is completed, so let's turn off the clocks! */
> + /* This message is completed, so let's turn off the clocks & power */
> clk_disable(pl022->clk);
> amba_pclk_disable(pl022->adev);
> + amba_vcore_disable(pl022->adev);
> }
>
> /**
> @@ -1475,9 +1476,11 @@ static void pump_messages(struct work_struct *work)
> /* Setup the SPI using the per chip configuration */
> pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi);
> /*
> - * We enable the clocks here, then the clocks will be disabled when
> - * giveback() is called in each method (poll/interrupt/DMA)
> + * We enable the core voltage and clocks here, then the clocks
> + * and core will be disabled when giveback() is called in each method
> + * (poll/interrupt/DMA)
> */
> + amba_vcore_enable(pl022->adev);
> amba_pclk_enable(pl022->adev);
> clk_enable(pl022->clk);
> restore_state(pl022);
> @@ -2123,8 +2126,12 @@ pl022_probe(struct amba_device *adev, struct amba_id *id)
> goto err_spi_register;
> }
> dev_dbg(dev, "probe succeded\n");
> - /* Disable the silicon block pclk and clock it when needed */
> + /*
> + * Disable the silicon block pclk and any voltage domain and just
> + * power it up and clock it when it's needed
> + */
> amba_pclk_disable(adev);
> + amba_vcore_disable(adev);
> return 0;
>
> err_spi_register:
> @@ -2189,9 +2196,11 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state)
> return status;
> }
>
> + amba_vcore_enable(adev);
> amba_pclk_enable(adev);
> load_ssp_default_config(pl022);
> amba_pclk_disable(adev);
> + amba_vcore_disable(adev);
> dev_dbg(&adev->dev, "suspended\n");
> return 0;
> }
> --
> 1.7.3.2
>
^ permalink raw reply
* [PATCH 3/4] spi/pl022: remove dangling status check
From: Grant Likely @ 2011-02-15 22:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297166621-5169-1-git-send-email-linus.walleij@stericsson.com>
On Tue, Feb 08, 2011 at 01:03:41PM +0100, Linus Walleij wrote:
> From: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>
>
> Signed-off-by: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied, thanks.
g.
> ---
> drivers/spi/amba-pl022.c | 2 --
> 1 files changed, 0 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
> index 8fdf530..2b591f0 100644
> --- a/drivers/spi/amba-pl022.c
> +++ b/drivers/spi/amba-pl022.c
> @@ -1906,8 +1906,6 @@ static int pl022_setup(struct spi_device *spi)
> && ((pl022->master_info)->enable_dma)) {
> chip->enable_dma = true;
> dev_dbg(&spi->dev, "DMA mode set in controller state\n");
> - if (status < 0)
> - goto err_config_params;
> SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED,
> SSP_DMACR_MASK_RXDMAE, 0);
> SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED,
> --
> 1.7.3.2
>
^ permalink raw reply
* [PATCH 4/4] spi/pl022: minor kerneldoc updates
From: Grant Likely @ 2011-02-15 22:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297166635-5205-1-git-send-email-linus.walleij@stericsson.com>
On Tue, Feb 08, 2011 at 01:03:55PM +0100, Linus Walleij wrote:
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied, thanks.
g.
> ---
> drivers/spi/amba-pl022.c | 25 ++++++++++++++++---------
> 1 files changed, 16 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
> index 2b591f0..4cd05cc 100644
> --- a/drivers/spi/amba-pl022.c
> +++ b/drivers/spi/amba-pl022.c
> @@ -329,15 +329,16 @@ struct vendor_data {
> /**
> * struct pl022 - This is the private SSP driver data structure
> * @adev: AMBA device model hookup
> - * @vendor: Vendor data for the IP block
> - * @phybase: The physical memory where the SSP device resides
> - * @virtbase: The virtual memory where the SSP is mapped
> + * @vendor: vendor data for the IP block
> + * @phybase: the physical memory where the SSP device resides
> + * @virtbase: the virtual memory where the SSP is mapped
> + * @clk: outgoing clock "SPICLK" for the SPI bus
> * @master: SPI framework hookup
> * @master_info: controller-specific data from machine setup
> - * @regs: SSP controller register's virtual address
> - * @pump_messages: Work struct for scheduling work to the workqueue
> - * @lock: spinlock to syncronise access to driver data
> * @workqueue: a workqueue on which any spi_message request is queued
> + * @pump_messages: work struct for scheduling work to the workqueue
> + * @queue_lock: spinlock to syncronise access to message queue
> + * @queue: message queue
> * @busy: workqueue is busy
> * @running: workqueue is running
> * @pump_transfers: Tasklet used in Interrupt Transfer mode
> @@ -348,8 +349,14 @@ struct vendor_data {
> * @tx_end: end position in TX buffer to be read
> * @rx: current position in RX buffer to be written
> * @rx_end: end position in RX buffer to be written
> - * @readingtype: the type of read currently going on
> - * @writingtype: the type or write currently going on
> + * @read: the type of read currently going on
> + * @write: the type of write currently going on
> + * @exp_fifo_level: expected FIFO level
> + * @dma_rx_channel: optional channel for RX DMA
> + * @dma_tx_channel: optional channel for TX DMA
> + * @sgt_rx: scattertable for the RX transfer
> + * @sgt_tx: scattertable for the TX transfer
> + * @dummypage: a dummy page used for driving data on the bus with DMA
> */
> struct pl022 {
> struct amba_device *adev;
> @@ -397,8 +404,8 @@ struct pl022 {
> * @cpsr: Value of Clock prescale register
> * @n_bytes: how many bytes(power of 2) reqd for a given data width of client
> * @enable_dma: Whether to enable DMA or not
> - * @write: function ptr to be used to write when doing xfer for this chip
> * @read: function ptr to be used to read when doing xfer for this chip
> + * @write: function ptr to be used to write when doing xfer for this chip
> * @cs_control: chip select callback provided by chip
> * @xfer_type: polling/interrupt/DMA
> *
> --
> 1.7.3.2
>
^ permalink raw reply
* [PATCH 4/4] arm: V2 configs: update pxa910 defconfig for SoC Selection
From: Sergei Shtylyov @ 2011-02-15 22:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5DE28962-5F04-4D34-8D65-DF4020F135CD@marvell.com>
On 16-02-2011 0:55, Philip Rakity wrote:
> V2
> ==
> Use make savedefconfigconfig to produce reduced size defconfig
> per suggestion of Nico Pitre.
> V1
> ==
The log of the patch changes should go under the --- tear line.
> took old pxa910_defconfig --
> did make menuconfig
> changed to CPU_PXA910
> Signed-off-by: Philip Rakity<prakity@marvell.com>
> ---
> arch/arm/configs/pxa910_defconfig | 6 +-----
> 1 files changed, 1 insertions(+), 5 deletions(-)
WBR, Sergei
^ permalink raw reply
* [PATCH 1/9] mfd-core: rename platform_data field of mfd_cell to mfd_data
From: Andres Salomon @ 2011-02-15 22:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297808729-21110-1-git-send-email-dilinger@queued.net>
Rename the platform_data variable to imply a distinction between
common platform_data driver usage (typically accessed via
pdev->dev.platform_data) and the way MFD passes data down to
clients (using a wrapper named mfd_get_data).
All clients have already been changed to use the wrapper function,
so this can be a quick single-commit change that only touches things
in drivers/mfd.
Signed-off-by: Andres Salomon <dilinger@queued.net>
---
drivers/mfd/ab3100-core.c | 2 +-
drivers/mfd/ab3550-core.c | 2 +-
drivers/mfd/janz-cmodio.c | 2 +-
drivers/mfd/mc13xxx-core.c | 2 +-
drivers/mfd/timberdale.c | 54 +++++++++++++++++++++---------------------
drivers/mfd/twl4030-codec.c | 4 +-
drivers/mfd/wl1273-core.c | 4 +-
include/linux/mfd/core.h | 8 +++---
8 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index b44c3d9..865251e 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -950,7 +950,7 @@ static int __devinit ab3100_probe(struct i2c_client *client,
/* Set up and register the platform devices. */
for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++)
- ab3100_devs[i].platform_data = ab3100_plf_data;
+ ab3100_devs[i].mfd_data = ab3100_plf_data;
err = mfd_add_devices(&client->dev, 0, ab3100_devs,
ARRAY_SIZE(ab3100_devs), NULL, 0);
diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c
index d849087..f4c12a4 100644
--- a/drivers/mfd/ab3550-core.c
+++ b/drivers/mfd/ab3550-core.c
@@ -1321,7 +1321,7 @@ static int __init ab3550_probe(struct i2c_client *client,
/* Set up and register the platform devices. */
for (i = 0; i < AB3550_NUM_DEVICES; i++)
- ab3550_devs[i].platform_data = ab3550_plf_data->dev_data[i];
+ ab3550_devs[i].mfd_data = ab3550_plf_data->dev_data[i];
err = mfd_add_devices(&client->dev, 0, ab3550_devs,
ARRAY_SIZE(ab3550_devs), NULL,
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c
index 58de1e2..fc41911 100644
--- a/drivers/mfd/janz-cmodio.c
+++ b/drivers/mfd/janz-cmodio.c
@@ -86,7 +86,7 @@ static int __devinit cmodio_setup_subdevice(struct cmodio_device *priv,
/* Add platform data */
pdata->modno = modno;
- cell->platform_data = pdata;
+ cell->mfd_data = pdata;
/* MODULbus registers -- PCI BAR3 is big-endian MODULbus access */
res->flags = IORESOURCE_MEM;
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 00c5490..b19b50a 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -689,7 +689,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
const char *name = mc13xxx_get_chipname(mc13xxx);
struct mfd_cell cell = {
- .platform_data = pdata,
+ .mfd_data = pdata,
};
/* there is no asnprintf in the kernel :-( */
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index 6353921..94c6c8a 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -384,7 +384,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
.resources = timberdale_dma_resources,
- .platform_data = &timb_dma_platform_data,
+ .mfd_data = &timb_dma_platform_data,
},
{
.name = "timb-uart",
@@ -395,37 +395,37 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
.name = "xiic-i2c",
.num_resources = ARRAY_SIZE(timberdale_xiic_resources),
.resources = timberdale_xiic_resources,
- .platform_data = &timberdale_xiic_platform_data,
+ .mfd_data = &timberdale_xiic_platform_data,
},
{
.name = "timb-gpio",
.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
.resources = timberdale_gpio_resources,
- .platform_data = &timberdale_gpio_platform_data,
+ .mfd_data = &timberdale_gpio_platform_data,
},
{
.name = "timb-video",
.num_resources = ARRAY_SIZE(timberdale_video_resources),
.resources = timberdale_video_resources,
- .platform_data = &timberdale_video_platform_data,
+ .mfd_data = &timberdale_video_platform_data,
},
{
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
- .platform_data = &timberdale_radio_platform_data,
+ .mfd_data = &timberdale_radio_platform_data,
},
{
.name = "xilinx_spi",
.num_resources = ARRAY_SIZE(timberdale_spi_resources),
.resources = timberdale_spi_resources,
- .platform_data = &timberdale_xspi_platform_data,
+ .mfd_data = &timberdale_xspi_platform_data,
},
{
.name = "ks8842",
.num_resources = ARRAY_SIZE(timberdale_eth_resources),
.resources = timberdale_eth_resources,
- .platform_data = &timberdale_ks8842_platform_data,
+ .mfd_data = &timberdale_ks8842_platform_data,
},
};
@@ -434,7 +434,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
.resources = timberdale_dma_resources,
- .platform_data = &timb_dma_platform_data,
+ .mfd_data = &timb_dma_platform_data,
},
{
.name = "timb-uart",
@@ -450,13 +450,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
.name = "xiic-i2c",
.num_resources = ARRAY_SIZE(timberdale_xiic_resources),
.resources = timberdale_xiic_resources,
- .platform_data = &timberdale_xiic_platform_data,
+ .mfd_data = &timberdale_xiic_platform_data,
},
{
.name = "timb-gpio",
.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
.resources = timberdale_gpio_resources,
- .platform_data = &timberdale_gpio_platform_data,
+ .mfd_data = &timberdale_gpio_platform_data,
},
{
.name = "timb-mlogicore",
@@ -467,25 +467,25 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
.name = "timb-video",
.num_resources = ARRAY_SIZE(timberdale_video_resources),
.resources = timberdale_video_resources,
- .platform_data = &timberdale_video_platform_data,
+ .mfd_data = &timberdale_video_platform_data,
},
{
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
- .platform_data = &timberdale_radio_platform_data,
+ .mfd_data = &timberdale_radio_platform_data,
},
{
.name = "xilinx_spi",
.num_resources = ARRAY_SIZE(timberdale_spi_resources),
.resources = timberdale_spi_resources,
- .platform_data = &timberdale_xspi_platform_data,
+ .mfd_data = &timberdale_xspi_platform_data,
},
{
.name = "ks8842",
.num_resources = ARRAY_SIZE(timberdale_eth_resources),
.resources = timberdale_eth_resources,
- .platform_data = &timberdale_ks8842_platform_data,
+ .mfd_data = &timberdale_ks8842_platform_data,
},
};
@@ -494,7 +494,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
.resources = timberdale_dma_resources,
- .platform_data = &timb_dma_platform_data,
+ .mfd_data = &timb_dma_platform_data,
},
{
.name = "timb-uart",
@@ -505,31 +505,31 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
.name = "xiic-i2c",
.num_resources = ARRAY_SIZE(timberdale_xiic_resources),
.resources = timberdale_xiic_resources,
- .platform_data = &timberdale_xiic_platform_data,
+ .mfd_data = &timberdale_xiic_platform_data,
},
{
.name = "timb-gpio",
.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
.resources = timberdale_gpio_resources,
- .platform_data = &timberdale_gpio_platform_data,
+ .mfd_data = &timberdale_gpio_platform_data,
},
{
.name = "timb-video",
.num_resources = ARRAY_SIZE(timberdale_video_resources),
.resources = timberdale_video_resources,
- .platform_data = &timberdale_video_platform_data,
+ .mfd_data = &timberdale_video_platform_data,
},
{
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
- .platform_data = &timberdale_radio_platform_data,
+ .mfd_data = &timberdale_radio_platform_data,
},
{
.name = "xilinx_spi",
.num_resources = ARRAY_SIZE(timberdale_spi_resources),
.resources = timberdale_spi_resources,
- .platform_data = &timberdale_xspi_platform_data,
+ .mfd_data = &timberdale_xspi_platform_data,
},
};
@@ -538,7 +538,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
.resources = timberdale_dma_resources,
- .platform_data = &timb_dma_platform_data,
+ .mfd_data = &timb_dma_platform_data,
},
{
.name = "timb-uart",
@@ -549,37 +549,37 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
.name = "ocores-i2c",
.num_resources = ARRAY_SIZE(timberdale_ocores_resources),
.resources = timberdale_ocores_resources,
- .platform_data = &timberdale_ocores_platform_data,
+ .mfd_data = &timberdale_ocores_platform_data,
},
{
.name = "timb-gpio",
.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
.resources = timberdale_gpio_resources,
- .platform_data = &timberdale_gpio_platform_data,
+ .mfd_data = &timberdale_gpio_platform_data,
},
{
.name = "timb-video",
.num_resources = ARRAY_SIZE(timberdale_video_resources),
.resources = timberdale_video_resources,
- .platform_data = &timberdale_video_platform_data,
+ .mfd_data = &timberdale_video_platform_data,
},
{
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
- .platform_data = &timberdale_radio_platform_data,
+ .mfd_data = &timberdale_radio_platform_data,
},
{
.name = "xilinx_spi",
.num_resources = ARRAY_SIZE(timberdale_spi_resources),
.resources = timberdale_spi_resources,
- .platform_data = &timberdale_xspi_platform_data,
+ .mfd_data = &timberdale_xspi_platform_data,
},
{
.name = "ks8842",
.num_resources = ARRAY_SIZE(timberdale_eth_resources),
.resources = timberdale_eth_resources,
- .platform_data = &timberdale_ks8842_platform_data,
+ .mfd_data = &timberdale_ks8842_platform_data,
},
};
diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c
index 0f57426..c02fded 100644
--- a/drivers/mfd/twl4030-codec.c
+++ b/drivers/mfd/twl4030-codec.c
@@ -208,13 +208,13 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
if (pdata->audio) {
cell = &codec->cells[childs];
cell->name = "twl4030-codec";
- cell->platform_data = pdata->audio;
+ cell->mfd_data = pdata->audio;
childs++;
}
if (pdata->vibra) {
cell = &codec->cells[childs];
cell->name = "twl4030-vibra";
- cell->platform_data = pdata->vibra;
+ cell->mfd_data = pdata->vibra;
childs++;
}
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c
index 703085e..f49e04e 100644
--- a/drivers/mfd/wl1273-core.c
+++ b/drivers/mfd/wl1273-core.c
@@ -79,7 +79,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,
cell = &core->cells[children];
cell->name = "wl1273_fm_radio";
- cell->platform_data = &core;
+ cell->mfd_data = &core;
children++;
if (pdata->children & WL1273_CODEC_CHILD) {
@@ -87,7 +87,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,
dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
cell->name = "wl1273-codec";
- cell->platform_data = &core;
+ cell->mfd_data = &core;
children++;
}
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index 923ec25..f317fe4 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -33,8 +33,8 @@ struct mfd_cell {
/* driver-specific data for MFD-aware "cell" drivers */
void *driver_data;
- /* platform_data can be used to pass data to "generic" drivers */
- void *platform_data;
+ /* mfd_data can be used to pass data to client drivers */
+ void *mfd_data;
/*
* These resources can be specified relative to the parent device.
@@ -64,11 +64,11 @@ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
/*
* Given a platform device that's been created by mfd_add_devices(), fetch
- * the .platform_data entry from the mfd_cell that created it.
+ * the .mfd_data entry from the mfd_cell that created it.
*/
static inline void *mfd_get_data(struct platform_device *pdev)
{
- return mfd_get_cell(pdev)->platform_data;
+ return mfd_get_cell(pdev)->mfd_data;
}
extern int mfd_add_devices(struct device *parent, int id,
--
1.7.2.3
^ permalink raw reply related
* BUG: ARM: MMP and PXA: nr_irqs > NR_IRQS
From: Thomas Gleixner @ 2011-02-15 22:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D5AF54D.3020208@metafoo.de>
On Tue, 15 Feb 2011, Lars-Peter Clausen wrote:
>
> I stumbled upon this while looking through the existing archs using SPARSE_IRQ.
> Even with SPARSE_IRQ the NR_IRQS is still the upper limit for the number of IRQs.
>
> Both PXA and MMP set NR_IRQS to IRQ_BOARD_START, with IRQ_BOARD_START being the
> number of IRQs used by the core.
> In various machine files the nr_irqs field of the ARM machine defintion struct
> is then set to "IRQ_BOARD_START + NR_BOARD_IRQS".
> As a result "nr_irqs" will greater then NR_IRQS which then again causes the
> "allocated_irqs" bitmap in the core irq code to be accessed beyond its size
> overwriting unrelated data.
>
> So as a fix I suggest setting NR_IRQS to a large a enough value like 1024 or
> something.
Thanks for pointing that out! The core code really misses a check. :(
I just checked and by chance the compiler/linker places data behind
that bitmap which gets initialized later on those two platforms. So
this went silently unnoticed.
So the obvious fix is to add a sanity check in early_irq_init() and
break all affected platforms. Though that check wants to be backported
to stable as well, which will require to fix all known problematic
platforms and probably some more yet not known ones as well. Lots of
churn.
We really should get rid of NR_IRQS as the limiting factor - we should
get rid of !sparse_irq as well, but that's a different problem.
So I came up with a fix which addresses the issue at hand, is small
enough to backport and does not require more backports.
Further it allows us later to extend nr_irqs on demand, by simply
reallocating the bit field under sparse_irq_lock().
Comments ?
Thanks,
tglx
Index: linux-2.6/kernel/irq/irqdesc.c
===================================================================
--- linux-2.6.orig/kernel/irq/irqdesc.c
+++ linux-2.6/kernel/irq/irqdesc.c
@@ -94,10 +94,10 @@ int nr_irqs = NR_IRQS;
EXPORT_SYMBOL_GPL(nr_irqs);
static DEFINE_MUTEX(sparse_irq_lock);
-static DECLARE_BITMAP(allocated_irqs, NR_IRQS);
#ifdef CONFIG_SPARSE_IRQ
+static unsigned long *allocated_irqs;
static RADIX_TREE(irq_desc_tree, GFP_KERNEL);
static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
@@ -217,6 +217,9 @@ int __init early_irq_init(void)
initcnt = arch_probe_nr_irqs();
printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d %d\n", NR_IRQS, nr_irqs, initcnt);
+ allocated_irqs = kzalloc(BITS_TO_LONGS(nr_irqs) * sizeof(unsigned long),
+ GFP_KERNEL);
+
for (i = 0; i < initcnt; i++) {
desc = alloc_desc(i, node);
set_bit(i, allocated_irqs);
@@ -227,6 +230,8 @@ int __init early_irq_init(void)
#else /* !CONFIG_SPARSE_IRQ */
+static DECLARE_BITMAP(allocated_irqs, NR_IRQS);
+
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DEFAULT_INIT_FLAGS,
^ permalink raw reply
* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
From: Shawn Guo @ 2011-02-15 22:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110214165958.GH10709@pengutronix.de>
Hi Wolfram,
On Mon, Feb 14, 2011 at 05:59:58PM +0100, Wolfram Sang wrote:
> On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > The driver calls into mxs-dma via generic dmaengine api for both pio
> > and data transfer.
> >
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>
> While trying, I got this lockdep-warning and BUG. It might be that my setup is
> wrong, causing all these timeouts. But they probably are meant to be handled
> more gracefully? I can continue testing tomorrow, maybe this report already
> helps identifying a problem?
>
Ah, yes. I can also see the problem here after turning on
DEBUG_SPINLOCK. I really should always turn it on in daily
development.
Thanks for catching. I will fix it in v3.
Regards,
Shawn
^ permalink raw reply
* [RFC] ARM: dma-mapping: outer cache is invalidated twice
From: Per Forlin @ 2011-02-15 22:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110215154633.GN4152@n2100.arm.linux.org.uk>
On 15 February 2011 16:46, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Feb 15, 2011 at 04:11:09PM +0100, Per Forlin wrote:
>> True. In my case write back is disable but read back is enable, that's
>> why I didn't consider it.
>
> What do you mean "write back is disable" ? ?You can only prevent
> writebacks by using a write-through cache.
>
I meant "no write allocate"
> Any writeback cache, whether in read-allocate or read-write-allocate
> mode will have writebacks.
>
Yepp, this is where I jumped to conclusions. I thought there would be
no writebacks if using "no write allocate". Now that I look at the
cache documentation again it feels so obvious.
Thanks for explaining this to me,
Per
^ permalink raw reply
* [RFC] MMC: error handling improvements
From: Russell King - ARM Linux @ 2011-02-15 23:03 UTC (permalink / raw)
To: linux-arm-kernel
This patch is for RFC only; it needs splitting up somewhat. However, I
wanted to get it out there for some comment.
The patch basically improves all round the error handling with MMC block
transfers. I've considered several scenarios, from lost or bad CRCs on
the initial commands (both causing no response from the card), lost stop
commands (which I've seen after a FIFO overrun), failed status commands
(also seen after a FIFO overrun), to data FIFO errors.
I've considered the case where the card becomes inaccessible, which
causes us to give up trying fairly quickly - this should avoid problems
with error recovery taking a very long time should the card disappear.
My motivation is primerily dealing with FIFO overruns on data transfers,
to allow the ARM MMCI primecell to run at a higher clock rate, while
allowing it to survive various interrupt loads (which invariably results
in not being able to service the FIFO quickly enough.)
The one obvious solution to this is the old SA_INTERRUPT stuff which used
to work. As this has been ripped out of the kernel, we have no option but
to invent more weird and wacky solutions to work-around other interrupt
handlers taking their time.
With this solution below, I can increase the card clocking rate from
around 512Kbps to 4Mbps, which is about an 8 fold increase in throughput
which can not sanely be ignored.
The comments may not entirely reflect what the code is doing; they may
have aged a little bit since the code was written. The adaptive clock
rate algorithm can probably do with a lot more work to avoid it up-
clocking to a rate which has proven to never work. I'd actually go as
far as to say that the algorithm probably has a lot to be desired - but
it seems to work for my test scenarios.
Last couple of points:
1. it relies on hosts returning the number of bytes equivalent to the
number of blocks _successfully_ transferred and no more. Returning zero
bytes on error is permitted, but untested, and may result in FIFO overruns
causing a faster reduction in clock rate.
2. it relies on MMC host drivers returning the right error codes, which
historically hasn't really mattered. With this code diagnosing the reason
for the failure, it now matters that the correct error codes are used.
drivers/mmc/card/block.c | 402 ++++++++++++++++++------
drivers/mmc/core/core.c | 11 +
drivers/mmc/core/core.h | 1 +
drivers/mmc/core/mmc.c | 2 +-
drivers/mmc/core/sd.c | 2 +-
drivers/mmc/core/sdio.c | 4 +-
drivers/mmc/host/mmci.c | 2 +-
include/linux/mmc/host.h | 1 +
include/linux/mmc/mmc.h | 10 +
9 files changed, 336 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index bfc8a8a..8daf340 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -75,6 +75,9 @@ struct mmc_blk_data {
unsigned int usage;
unsigned int read_only;
+ unsigned int clk_div;
+ unsigned int fifo_ok[10];
+ unsigned int fifo_fail[10];
};
static DEFINE_MUTEX(open_lock);
@@ -245,7 +248,21 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
return result;
}
-static u32 get_card_status(struct mmc_card *card, struct request *req)
+static int send_stop(struct mmc_card *card, u32 *status)
+{
+ struct mmc_command cmd;
+ int err;
+
+ memset(&cmd, 0, sizeof(struct mmc_command));
+ cmd.opcode = MMC_STOP_TRANSMISSION;
+ cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+ err = mmc_wait_for_cmd(card->host, &cmd, 5);
+ if (err == 0)
+ *status = cmd.resp[0];
+ return err;
+}
+
+static int get_card_status(struct mmc_card *card, u32 *status)
{
struct mmc_command cmd;
int err;
@@ -256,10 +273,134 @@ static u32 get_card_status(struct mmc_card *card, struct request *req)
cmd.arg = card->rca << 16;
cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
err = mmc_wait_for_cmd(card->host, &cmd, 0);
+ if (err == 0)
+ *status = cmd.resp[0];
+ return err;
+}
+
+#define ERR_RETRY 2
+#define ERR_ABORT 1
+#define ERR_CONTINUE 0
+
+/*
+ * Initial r/w and stop cmd error recovery.
+ * We don't know whether the card received the r/w cmd or not, so try to
+ * restore things back to a sane state. Essentially, we do this as follows:
+ * - Obtain card status. If the first attempt to obtain card status fails,
+ * the status word will reflect the failed status cmd, not the failed
+ * r/w cmd. If we fail to obtain card status, it suggests we can no
+ * longer communicate with the card.
+ * - Check the card state. If the card received the cmd but there was a
+ * transient problem with the response, it might still be in a data transfer
+ * mode. Try to send it a stop command. If this fails, we can't recover.
+ * - If the r/w cmd failed due to a response CRC error, it was probably
+ * transient, so retry the cmd.
+ * - If the r/w cmd timed out, but we didn't get the r/w cmd status, retry.
+ * - If the r/w cmd timed out, and the r/w cmd failed due to CRC error or
+ * illegal cmd, retry.
+ * Otherwise we don't understand what happened, so abort.
+ */
+static int mmc_blk_cmd_recovery(struct mmc_card *card, struct mmc_blk_request *brq,
+ struct request *req)
+{
+ bool rwcmd_status = true;
+ u32 status, stop_status = 0;
+ int err, retry;
+
+ /*
+ * Try to get card status which indicates both the card state
+ * and why there was no response. If the first attempt fails,
+ * we can't be sure the returned status is for the r/w command.
+ */
+ for (retry = 2; retry >= 0; retry--) {
+ err = get_card_status(card, &status);
+ if (!err)
+ break;
+
+ rwcmd_status = false;
+ pr_err("%s: error %d sending status command, %sing\n",
+ req->rq_disk->disk_name, err, retry ? "retry" : "abort");
+ }
+
+ /* We couldn't get a response from the card. Give up. */
if (err)
- printk(KERN_ERR "%s: error %d sending status command",
- req->rq_disk->disk_name, err);
- return cmd.resp[0];
+ return ERR_ABORT;
+
+ /*
+ * Check the current card state. If it is in some data transfer
+ * mode, tell it to stop (and hopefully transition back to TRAN.)
+ */
+ if (R1_CURRENT_STATE(status) == R1_STATE_DATA ||
+ R1_CURRENT_STATE(status) == R1_STATE_RCV) {
+ err = send_stop(card, &stop_status);
+ if (err)
+ pr_err("%s: error %d sending stop command\n",
+ req->rq_disk->disk_name, err);
+
+ /*
+ * If the stop cmd also timed out, the card is
+ * probably not present, so abort.
+ */
+ if (err == -ETIMEDOUT)
+ return ERR_ABORT;
+ }
+
+ /* Check for initial command errors */
+ switch (brq->cmd.error) {
+ case 0:
+ /* no error */
+ break;
+
+ case -EILSEQ:
+ /* response crc error, retry the r/w cmd */
+ pr_err("%s: %s sending %s command, card status %#x\n",
+ req->rq_disk->disk_name,
+ "response CRC error", "read/write",
+ status);
+ return ERR_RETRY;
+
+ case -ETIMEDOUT:
+ pr_err("%s: %s sending %s command, card status %#x\n",
+ req->rq_disk->disk_name,
+ "timed out", "read/write",
+ status);
+
+ if (!rwcmd_status) {
+ /* Status cmd initially failed, retry the r/w cmd */
+ return ERR_RETRY;
+ }
+ if (status & (R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND)) {
+ /*
+ * if it was a r/w cmd crc error, or illegal command
+ * (eg, issued in wrong state) then retry - we should
+ * have corrected the state problem above.
+ */
+ return ERR_RETRY;
+ }
+
+ default:
+ /* we don't understand the error code the driver gave us */
+ pr_err("%s: unknown error %d sending read/write command, card status %#x\n",
+ req->rq_disk->disk_name, brq->cmd.error, status);
+ return ERR_ABORT;
+ }
+
+ /*
+ * Now for stop errors. These aren't fatal to the transfer.
+ */
+ pr_err("%s: error %d sending stop command, original cmd response %#x, card status %#x\n",
+ req->rq_disk->disk_name, brq->stop.error,
+ brq->cmd.resp[0], status);
+
+ /*
+ * Subsitute in our own stop status as this will give the error
+ * state which happened during the execution of the r/w command.
+ */
+ if (stop_status) {
+ brq->stop.resp[0] = stop_status;
+ brq->stop.error = 0;
+ }
+ return ERR_CONTINUE;
}
static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
@@ -331,18 +472,29 @@ out:
return err ? 0 : 1;
}
+extern void mmc_set_clock(struct mmc_host *host, unsigned int hz);
+
+#define CMD_ERRORS \
+ (R1_OUT_OF_RANGE /* Command argument out of range */ |\
+ R1_ADDRESS_ERROR /* Misaligned address */ |\
+ R1_BLOCK_LEN_ERROR /* Transferred block length incorrect */ |\
+ R1_WP_VIOLATION /* Tried to write to protected block */ |\
+ R1_CC_ERROR /* Card controller error */ |\
+ R1_ERROR /* General/unknown error */ )
+
static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
{
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
+ struct mmc_host *host = card->host;
struct mmc_blk_request brq;
- int ret = 1, disable_multi = 0;
+ int ret = 1, disable_multi = 0, retry = 0;
- mmc_claim_host(card->host);
+ mmc_claim_host(host);
do {
- struct mmc_command cmd;
- u32 readcmd, writecmd, status = 0;
+ u32 readcmd, writecmd;
+ unsigned int bytes_xfered;
memset(&brq, 0, sizeof(struct mmc_blk_request));
brq.mrq.cmd = &brq.cmd;
@@ -426,55 +578,46 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
mmc_queue_bounce_post(mq);
- /*
- * Check for errors here, but don't jump to cmd_err
- * until later as we need to wait for the card to leave
- * programming mode even when things go wrong.
- */
- if (brq.cmd.error || brq.data.error || brq.stop.error) {
- if (brq.data.blocks > 1 && rq_data_dir(req) == READ) {
- /* Redo read one sector at a time */
- printk(KERN_WARNING "%s: retrying using single "
- "block read\n", req->rq_disk->disk_name);
- disable_multi = 1;
- continue;
+ if (brq.cmd.error || brq.stop.error) {
+ /*
+ * cmd.error indicates a problem with the r/w
+ * command. No data will have been transferred.
+ *
+ * stop.error indicates a problem with the stop
+ * command. Data may have been transferred, or
+ * may still be transferring.
+ */
+ switch (mmc_blk_cmd_recovery(card, &brq, req)) {
+ case ERR_RETRY:
+ if (retry++ < 5)
+ goto cmd_err;
+ case ERR_ABORT:
+ goto cmd_err;
+ case ERR_CONTINUE:
+ break;
}
- status = get_card_status(card, req);
}
- if (brq.cmd.error) {
- printk(KERN_ERR "%s: error %d sending read/write "
- "command, response %#x, card status %#x\n",
- req->rq_disk->disk_name, brq.cmd.error,
- brq.cmd.resp[0], status);
- }
-
- if (brq.data.error) {
- if (brq.data.error == -ETIMEDOUT && brq.mrq.stop)
- /* 'Stop' response contains card status */
- status = brq.mrq.stop->resp[0];
- printk(KERN_ERR "%s: error %d transferring data,"
- " sector %u, nr %u, card status %#x\n",
- req->rq_disk->disk_name, brq.data.error,
- (unsigned)blk_rq_pos(req),
- (unsigned)blk_rq_sectors(req), status);
- }
-
- if (brq.stop.error) {
- printk(KERN_ERR "%s: error %d sending stop command, "
- "response %#x, card status %#x\n",
- req->rq_disk->disk_name, brq.stop.error,
- brq.stop.resp[0], status);
- }
+ /*
+ * Check for errors relating to the execution of
+ * the initial command - such as address errors.
+ */
+ if (brq.cmd.resp[0] & CMD_ERRORS) {
+ pr_err("%s: r/w command failed, status = %#x\n",
+ req->rq_disk->disk_name, brq.cmd.resp[0]);
+ goto cmd_err;
+ }
+ /*
+ * Everthing else is either success, or a data error of some
+ * kind. If it was a write, we may have transitioned to
+ * program mode, which we have to wait for it to complete.
+ */
if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
+ u32 status;
do {
- int err;
-
- cmd.opcode = MMC_SEND_STATUS;
- cmd.arg = card->rca << 16;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
- err = mmc_wait_for_cmd(card->host, &cmd, 5);
+ int err = get_card_status(card, &status);
+ /* If -EILSEQ, retry? */
if (err) {
printk(KERN_ERR "%s: error %d requesting status\n",
req->rq_disk->disk_name, err);
@@ -485,20 +628,121 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
* so make sure to check both the busy
* indication and the card state.
*/
- } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
- (R1_CURRENT_STATE(cmd.resp[0]) == 7));
-
-#if 0
- if (cmd.resp[0] & ~0x00000900)
- printk(KERN_ERR "%s: status = %08x\n",
- req->rq_disk->disk_name, cmd.resp[0]);
- if (mmc_decode_status(cmd.resp))
- goto cmd_err;
-#endif
+ } while (!(status & R1_READY_FOR_DATA) ||
+ (R1_CURRENT_STATE(status) == R1_STATE_PRG));
+ }
+
+ /*
+ * If this is an SD card and we're writing, we can first mark
+ * the known good sectors as ok.
+ *
+ * If the card is not SD, we can still ok written sectors as
+ * reported by the controller (which may be less than the real
+ * number of written sectors, but never more).
+ */
+ bytes_xfered = brq.data.bytes_xfered;
+ if (mmc_card_sd(card) && rq_data_dir(req) != READ) {
+ u32 blocks = mmc_sd_num_wr_blocks(card);
+ if (blocks != (u32)-1)
+ bytes_xfered = blocks << 9;
}
- if (brq.cmd.error || brq.stop.error || brq.data.error) {
+ if (bytes_xfered) {
+ /*
+ * Data was transferred. Let the block layer know
+ * how much was successfully transferred, so we
+ * don't retry this. Hosts which can't report the
+ * number of successful bytes better return zero on
+ * error.
+ */
+ spin_lock_irq(&md->lock);
+ ret = __blk_end_request(req, 0, bytes_xfered);
+ spin_unlock_irq(&md->lock);
+ } else {
+ ret = 1;
+ }
+
+ if (brq.data.error)
+ pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n",
+ req->rq_disk->disk_name, brq.data.error,
+ (unsigned)blk_rq_pos(req), (unsigned)blk_rq_sectors(req),
+ brq.cmd.resp[0], brq.stop.resp[0]);
+
+ if (brq.data.error == -EIO) {
+ /* fifo underrun/overrun */
+
+ /* increment error count for this rate */
+ md->fifo_fail[md->clk_div]++;
+
+ /* if we progressed, just retry. */
+ if (bytes_xfered && retry++ < 5)
+ continue;
+
+ /* retry once in case of transients */
+ if (retry++ < 1)
+ continue;
+
+ /* drop the error rate */
+ if (host->ios.clock > host->f_init && md->clk_div < 9) {
+ unsigned int clock;
+
+ md->clk_div++;
+ md->fifo_fail[md->clk_div] = 0;
+ md->fifo_ok[md->clk_div] = 0;
+
+ pr_err("%s: retrying with slower /%u clock rate\n",
+ req->rq_disk->disk_name,
+ 1 << md->clk_div);
+
+ clock = host->clock_max >> md->clk_div;
+ mmc_set_clock(host, clock);
+ continue;
+ }
+ } else {
+ unsigned this_err_rate, next_err_rate = 100;
+ unsigned idx = md->clk_div;
+
+ md->fifo_ok[idx]++;
+
+ if (md->fifo_ok[idx] + md->fifo_fail[idx] > 100) {
+
+ if (idx > 0) {
+ unsigned total = md->fifo_fail[idx - 1] + md->fifo_ok[idx - 1];
+
+ next_err_rate = total ?
+ md->fifo_fail[idx - 1] / total : 0;
+ }
+
+ this_err_rate = md->fifo_fail[idx] /
+ (md->fifo_fail[idx] + md->fifo_ok[idx]);
+
+ if (this_err_rate < 5 && next_err_rate < 30) {
+ unsigned clock;
+ md->clk_div--;
+
+ md->fifo_ok[md->clk_div] = 0;
+ md->fifo_fail[md->clk_div] = 0;
+
+ pr_err("%s: increasing to /%u clock rate\n",
+ req->rq_disk->disk_name,
+ 1 << md->clk_div);
+
+ clock = host->clock_max >> md->clk_div;
+ mmc_set_clock(host, clock);
+ }
+ }
+ }
+
+ if (brq.data.error) {
if (rq_data_dir(req) == READ) {
+ if (brq.data.blocks > 1) {
+ /* Redo read one sector at a time */
+ pr_warning("%s: retrying using single "
+ "block read\n", req->rq_disk->disk_name);
+ disable_multi = 1;
+ continue;
+ }
+
/*
* After an error, we redo I/O one sector at a
* time, so we only reach here after trying to
@@ -507,17 +751,10 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
spin_lock_irq(&md->lock);
ret = __blk_end_request(req, -EIO, brq.data.blksz);
spin_unlock_irq(&md->lock);
- continue;
+ } else {
+ goto cmd_err;
}
- goto cmd_err;
}
-
- /*
- * A block was successfully transferred.
- */
- spin_lock_irq(&md->lock);
- ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
- spin_unlock_irq(&md->lock);
} while (ret);
mmc_release_host(card->host);
@@ -525,29 +762,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
return 1;
cmd_err:
- /*
- * If this is an SD card and we're writing, we can first
- * mark the known good sectors as ok.
- *
- * If the card is not SD, we can still ok written sectors
- * as reported by the controller (which might be less than
- * the real number of written sectors, but never more).
- */
- if (mmc_card_sd(card)) {
- u32 blocks;
-
- blocks = mmc_sd_num_wr_blocks(card);
- if (blocks != (u32)-1) {
- spin_lock_irq(&md->lock);
- ret = __blk_end_request(req, 0, blocks << 9);
- spin_unlock_irq(&md->lock);
- }
- } else {
- spin_lock_irq(&md->lock);
- ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
- spin_unlock_irq(&md->lock);
- }
-
mmc_release_host(card->host);
spin_lock_irq(&md->lock);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 6625c05..b3ffd99 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -648,6 +648,17 @@ void mmc_set_clock(struct mmc_host *host, unsigned int hz)
mmc_set_ios(host);
}
+void mmc_set_clock_max(struct mmc_host *host, unsigned int hz)
+{
+ WARN_ON(hz < host->f_min);
+
+ if (hz > host->f_max)
+ hz = host->f_max;
+
+ host->ios.clock = host->clock_max = hz;
+ mmc_set_ios(host);
+}
+
#ifdef CONFIG_MMC_CLKGATE
/*
* This gates the clock by setting it to 0 Hz.
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index ca1fdde..412113c 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -33,6 +33,7 @@ void mmc_init_erase(struct mmc_card *card);
void mmc_set_chip_select(struct mmc_host *host, int mode);
void mmc_set_clock(struct mmc_host *host, unsigned int hz);
+void mmc_set_clock_max(struct mmc_host *host, unsigned int hz);
void mmc_gate_clock(struct mmc_host *host);
void mmc_ungate_clock(struct mmc_host *host);
void mmc_set_ungated(struct mmc_host *host);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 16006ef..4fe515a 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -515,7 +515,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
max_dtr = card->csd.max_dtr;
}
- mmc_set_clock(host, max_dtr);
+ mmc_set_clock_max(host, max_dtr);
/*
* Indicate DDR mode (if supported).
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index d18c32b..576b320 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -621,7 +621,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
/*
* Set bus speed.
*/
- mmc_set_clock(host, mmc_sd_get_max_clock(card));
+ mmc_set_clock_max(host, mmc_sd_get_max_clock(card));
/*
* Switch to wider bus (if supported).
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 5c4a54d..fb41db6 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -425,7 +425,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
* It's host's responsibility to fill cccr and cis
* structures in init_card().
*/
- mmc_set_clock(host, card->cis.max_dtr);
+ mmc_set_clock_max(host, card->cis.max_dtr);
if (card->cccr.high_speed) {
mmc_card_set_highspeed(card);
@@ -491,7 +491,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
/*
* Change to the card's maximum speed.
*/
- mmc_set_clock(host, mmc_sdio_get_max_clock(card));
+ mmc_set_clock_max(host, mmc_sdio_get_max_clock(card));
/*
* Switch to wider bus (if supported).
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8a29c9f..dcbe9c4 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -38,7 +38,7 @@
#define DRIVER_NAME "mmci-pl18x"
-static unsigned int fmax = 515633;
+static unsigned int fmax = 4000000;
/**
* struct variant_data - MMCI variant-specific quirks
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index bcb793e..76df335 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -199,6 +199,7 @@ struct mmc_host {
struct mmc_ios ios; /* current io bus settings */
u32 ocr; /* the current OCR setting */
+ unsigned int clock_max; /* maximum clock rate */
/* group bitfields together to minimize padding */
unsigned int use_spi_crc:1;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 612301f..9d067ee 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -133,6 +133,16 @@
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
#define R1_APP_CMD (1 << 5) /* sr, c */
+#define R1_STATE_IDLE 0
+#define R1_STATE_READY 1
+#define R1_STATE_IDENT 2
+#define R1_STATE_STBY 3
+#define R1_STATE_TRAN 4
+#define R1_STATE_DATA 5
+#define R1_STATE_RCV 6
+#define R1_STATE_PRG 7
+#define R1_STATE_DIS 8
+
/*
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
* R1 is the low order byte; R2 is the next highest byte, when present.
^ permalink raw reply related
* [PATCH 4/8] ARM: etm: Allow range selection
From: Arve Hjønnevåg @ 2011-02-15 23:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110215135054.GD18248@shisha.kicks-ass.net>
On Tue, Feb 15, 2011 at 5:50 AM, Alexander Shishkin <virtuoso@slind.org> wrote:
> On Mon, Feb 14, 2011 at 10:11:12PM -0800, Arve Hj?nnev?g wrote:
>> Trace kernel text segment by default as before, allow tracing of other
>> ranges by writing a range to /sys/devices/etm/trace_range, or to trace
>> everything by writing 0 0.
>
> Since you're adding this, I think it might make sense to add a 3rd optional
> ctx id field, so that userspace tracing is also possible, especially when
> on-chip ETB sizes increase to something more sensible than what they are
> these days.
>
That might be useful, but I think it can be added later. My main
motivation for adding this is so we can turn off the filtering. We
want to use tracing in combination with a hardware watchdog to debug
hard lockups and we don't want any filtering in this case.
--
Arve Hj?nnev?g
^ permalink raw reply
* [PATCH v2 7/7] ARM: mxs/mx28evk: add mmc device
From: Shawn Guo @ 2011-02-15 23:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110214102646.GB30100@pengutronix.de>
On Mon, Feb 14, 2011 at 11:26:46AM +0100, Wolfram Sang wrote:
> Shawn,
>
> > +/* mmc */
> > +static void __init mx28evk_mmc_slot_poweron(int gpio)
> > +{
> > + int ret;
> > +
> > + ret = gpio_request(gpio, "mmc-slot-power");
> > + if (ret) {
> > + pr_err("Failed to request gpio mmc-slot-power: %d\n", ret);
> > + return;
> > + }
> > +
> > + ret = gpio_direction_output(gpio, 0);
> > + if (ret) {
> > + pr_err("Failed to drive gpio mmc-slot-power: %d\n", ret);
> > + return;
> > + }
> > +}
>
> Minor nit: You could use gpio_request_one(), and doing so maybe even get rid of
> this function and simply do it the init-function. The advantage would be, that
> you can name the two GPIOs independently.
>
OK. Will take it.
Thanks,
Shawn
^ permalink raw reply
* [RFC] Inter-processor Mailboxes Drivers
From: Blanchard, Hollis @ 2011-02-15 23:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D5AF712.3080509@mentor.com>
On 02/15/2011 01:58 PM, Meador Inge wrote:
> On 02/14/2011 04:01 AM, Jamie Iles wrote:
>> On Fri, Feb 11, 2011 at 03:19:51PM -0600, Meador Inge wrote:
>>> 1. Hardware specific bits somewhere under '.../arch/*'. Drivers
>>> for the MPIC message registers on Power and OMAP4 mailboxes,
>>> for
>>> example.
>>> 2. A higher level driver under '.../drivers/mailbox/*'. That the
>>> pieces in (1) would register with. This piece would expose the
>>> main kernel API.
>>> 3. Userspace interfaces for accessing the mailboxes. A
>>> '/dev/mailbox1', '/dev/mailbox2', etc... mapping, for example.
>>
>> How about using virtio for all of this and having the mailbox as a
>> notification/message passing driver for the virtio backend? There are
>> already virtio console and network drivers that could be useful for the
>> userspace part of it. drivers/virtio/virtio_ring.c might be a good
>> starting point if you thought there was some mileage in this approach.
>
> To be honest, I am not that familiar with 'virtio', but I will take a
> look. Thanks for the pointer. Maybe Hollis can speak to this idea more.
My opinion is that virtio is (over?) complicated.
I've looked into it in the past, and I'm definitely open to using it if
somebody can demonstrate how easy it is, but adopting it wouldn't have
helped OpenMCAPI with our use cases, and would have incurred extra pain,
so we didn't.
Hollis Blanchard
Mentor Graphics, Embedded Systems Division
^ permalink raw reply
* [RFC] MMC: error handling improvements
From: David Brown @ 2011-02-15 23:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110215230311.GT4152@n2100.arm.linux.org.uk>
On Tue, Feb 15 2011, Russell King - ARM Linux wrote:
> This patch is for RFC only; it needs splitting up somewhat. However, I
> wanted to get it out there for some comment.
Just for kicks, I applied this and ran it on an MSM target (8x50). It
seems to cause lots of:
mmc0: Data timeout
mmc0: Controller has been re-initialized
...
mmc0: Data CRC error
and I can post more if you would find them interesting. Eventually the
MSM mmc driver derefernces a null pointer in the interrupt code.
It's also possible this is finding problems in our SDCC driver.
David
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply
* [PATCH v5 3/5] OMAP4: hwmod data: add mailbox data
From: Ramirez Luna, Omar @ 2011-02-16 0:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D5AF8BA.8080403@ti.com>
Hi,
On Tue, Feb 15, 2011 at 4:05 PM, Cousson, Benoit <b-cousson@ti.com> wrote:
>> It is this way instead of plain platform_get_irq because omap2420 has
>> two interrupt sources to MPU and mailbox driver uses
>> platform_get_irq_byname to get the irq number.
>
> This is what I was thinking, except that on OMAP2420 the names are:
> + ? ? ? { .name = "dsp", .irq = 26, },
> + ? ? ? { .name = "iva", .irq = 34, },
>
> and on OMAP2430 and OMAP3
> + ? ? ? { .name = "dsp", .irq = 26, },
>
> so why is it named "mbox" on OMAP4?
I'm not very familiar with OMAP4 terminology... but IMHO, I guess
naming it dsp, would imply that this is a mailbox for the dsp, when
the interrupt can be generated by either the M3, dsp, I think even the
IVA can write into it.
> If you have to do several platform_get_irq_byname to get this one, I'd
> prefer to get rid of that name for OMAP4. It will make mailbox irq
> consistent with the other hwmods.
I was thinking to standardize the names to be mbox0..mboxN across all
the platforms, reason being that the mailbox also has capabilities to
be used not only by dsp or iva, by using a polling method.
So even if the mailbox in OMAP3 is called "dsp", it has 4 more queues
apart from the 2 used for messaging between arm and dsp, that could be
used even if tidspbridge wasn't there.
Did I get you correctly?
Regards,
Omar
^ permalink raw reply
* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
From: Colin Cross @ 2011-02-16 0:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110215110453.GB11199@n2100.arm.linux.org.uk>
On Tue, Feb 15, 2011 at 3:04 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
>> > +ENDPROC(cpu_resume_turn_mmu_on)
>> > +cpu_resume_after_mmu:
>> > + ? ? ? str ? ? r5, [r2, r4, lsl #2] ? ?@ restore old mapping
>> > +#ifdef MULTI_CACHE
>> > + ? ? ? ldr ? ? r10, =cpu_cache
>> > + ? ? ? ldr ? ? pc, [r10, #CACHE_FLUSH_KERN_ALL]
>> > +#else
>> > + ? ? ? b ? ? ? __cpuc_flush_kern_all
>> > +#endif
>
> I think we can eliminate this cache flush by delaying the cache enable
> as below. ?Could you see whether Tegra 2 survives this please?
> Thanks.
>
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> index bed1876..193be5f 100644
> --- a/arch/arm/kernel/sleep.S
> +++ b/arch/arm/kernel/sleep.S
> @@ -4,6 +4,7 @@
> ?#include <asm/assembler.h>
> ?#include <asm/glue-cache.h>
> ?#include <asm/glue-proc.h>
> +#include <asm/system.h>
> ? ? ? ?.text
>
> ?/*
> @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
> ? ? ? ?str ? ? r3, [r2, r4, lsl #2] ? ?@ setup 1:1 mapping for mmu code
> ? ? ? ?sub ? ? r2, r2, r1
> ? ? ? ?ldr ? ? r3, =cpu_resume_after_mmu
> + ? ? ? bic ? ? r1, r0, #CR_C ? ? ? ? ? @ ensure D-cache is disabled
> ? ? ? ?b ? ? ? cpu_resume_turn_mmu_on
> ?ENDPROC(cpu_resume_mmu)
> ? ? ? ?.ltorg
> ? ? ? ?.align ?5
> ?cpu_resume_turn_mmu_on:
> - ? ? ? mcr ? ? p15, 0, r0, c1, c0, 0 ? @ turn on MMU, caches, etc
> - ? ? ? mrc ? ? p15, 0, r0, c0, c0, 0 ? @ read id reg
> - ? ? ? mov ? ? r0, r0
> - ? ? ? mov ? ? r0, r0
> + ? ? ? mcr ? ? p15, 0, r1, c1, c0, 0 ? @ turn on MMU, I-cache, etc
> + ? ? ? mrc ? ? p15, 0, r1, c0, c0, 0 ? @ read id reg
> + ? ? ? mov ? ? r1, r1
> + ? ? ? mov ? ? r1, r1
> ? ? ? ?mov ? ? pc, r3 ? ? ? ? ? ? ? ? ?@ jump to virtual address
> ?ENDPROC(cpu_resume_turn_mmu_on)
> ?cpu_resume_after_mmu:
> ? ? ? ?str ? ? r5, [r2, r4, lsl #2] ? ?@ restore old mapping
> -#ifdef MULTI_CACHE
> - ? ? ? ldr ? ? r10, =cpu_cache
> - ? ? ? ldr ? ? pc, [r10, #CACHE_FLUSH_KERN_ALL]
> -#else
> - ? ? ? b ? ? ? __cpuc_flush_kern_all
> -#endif
> + ? ? ? mcr ? ? p15, 0, r0, c1, c0, 0 ? @ turn on D-cache
> + ? ? ? mov ? ? pc, lr
>
> ?/*
> ?* Note: Yes, part of the following code is located into the .data section.
>
>
Tested-by: Colin Cross <ccross@android.com>
Works for Tegra 2 cpuidle and suspend.
^ permalink raw reply
* [PATCH 1/3] msm: iommu: Create a Kconfig item for the IOMMU driver
From: Daniel Walker @ 2011-02-16 0:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8yar5b9850l.fsf@huya.qualcomm.com>
On Tue, 2011-02-15 at 11:35 -0800, David Brown wrote:
> On Fri, Feb 11 2011, Daniel Walker wrote:
>
> > On Fri, 2011-02-11 at 12:28 -0800, Stepan Moskovchenko wrote:
> >> +config MSM_IOMMU
> >> + bool "MSM IOMMU Support"
> >> + depends on ARCH_MSM8X60
> >> + select IOMMU_API
> >> + default n
> >> + help
> >> + Support for the IOMMUs found on certain Qualcomm SOCs.
> >> + These IOMMUs allow virtualization of the address space used by most
> >> + cores within the multimedia subsystem.
> >> +
> >> + If unsure, say N here.
> >
> > I think you should just make this a hidden option, unless there is a
> > good reason why any given users might want to turn this off.
>
> In this particular case, the driver is optional, even devices that use
> it will be able to work both with and without it. It makes sense to be
> able to decide whether to have it or not.
This driver doesn't belong under mach-msm.
Daniel
--
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply
* Question about ARM function graph tracing
From: Tim Bird @ 2011-02-16 1:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D4C61A5.4050403@am.sony.com>
On 02/04/2011 12:29 PM, Tim Bird wrote:
>> OMAP is missing a notrace annotation on omap_readl():
>>
>> http://www.mail-archive.com/linux-omap at vger.kernel.org/msg38911.html
>>
>> Part of that patch was merged through rmk's work, but the
>> omap_readl() annotation seems to have been missed.
> Yep. It's missing in 2.6.38-rc3.
>
>> Also, if this is OMAP1 and not latest mainline, I think you
>> will need a notrace on omap_rev() also (called from inside
>> omap_readl() until recently).
>
> I couldn't find that in the sched_clock code paths, but
> I 'notrace'd it anyways.
>
>>
>> I think this is most probably what is wrong, since IIRC I saw
>> crashes like this on BeagleBoard before I added the notrace on
>> omap_readl. Could you please try with these changes?
>
> I have sprinkled 'notrace's liberally throughout the sched_clock
> code (including omap_readl() and omap_rev()), and I'm still
> seeing problems. I put a recursion guard in
> prepare_ftrace_return, and I'm seeing lots of recursion. So
> there's still a notrace missing somewhere.
OK. The notrace was indeed missing fro omap_readl(), but fixing
this did not completely fix the problem. I put the following
(crude) recursion guard in arch/arm/kernel/ftrace.c:prepare_ftrace_return:
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index c0062ad..5872c25 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -209,6 +209,8 @@ int __init ftrace_dyn_arch_init(void *data)
#endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static int already_here = 0;
+
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
unsigned long frame_pointer)
{
@@ -217,8 +219,16 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_a
unsigned long old;
int err;
- if (unlikely(atomic_read(¤t->tracing_graph_pause)))
+ if(unlikely(already_here)) {
return;
+ } else {
+ already_here=1;
+ }
+
+ if (unlikely(atomic_read(¤t->tracing_graph_pause))) {
+ already_here=0;
+ return;
+ }
old = *parent;
*parent = return_hooker;
@@ -227,6 +237,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_ad
frame_pointer);
if (err == -EBUSY) {
*parent = old;
+ already_here=0;
return;
}
@@ -237,6 +248,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_ad
current->curr_ret_stack--;
*parent = old;
}
+ already_here=0;
}
#ifdef CONFIG_DYNAMIC_FTRACE
Without this, the system hangs for long periods of time after starting
the function graph tracer (echo function_graph >/debug/tracing/current_tracer)
Sometimes the system comes back and sometimes it doesn't. With the above
code, the system works, and I can get traces (but obviously I'm dumping
a bunch of tracepoints whenever the tracer nests.)
I put some extra instrumentation in, and MOST of the time, the item
causing nesting is asm_do_IRQ(), which is to be expected. However,
I have seen a recursion from preempt_schedule(), which I didn't really
expect. Does the tracer invoke anything that would cause a schedule
from inside the trace-recording code?
Should I try this with CONFIG_PREEMPT off? (It's currently on.)
Any ideas for debugging this would be appreciated.
-- Tim
=============================
Tim Bird
Architecture Group Chair, CE Linux Forum
Senior Staff Engineer, Sony Network Entertainment
=============================
^ permalink raw reply related
* [PATCH V6 13/63] ST SPEAr: Updating Clock Support
From: stanley.miao @ 2011-02-16 1:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6e9275be36b831894e51a2adf3ebbe9984831d16.1297763160.git.viresh.kumar@st.com>
Viresh Kumar wrote:
> <snip>
> -/*
> - * Set pclk as cclk's parent and add clock sibling node to current parents
> - * children list
> +/**
> + * clk_round_rate - adjust a rate to the exact rate a clock can provide
> + * @clk: clock source
> + * @rate: desired clock rate in Hz
> + *
> + * Returns rounded clock rate in Hz, or negative errno.
> */
> -static void change_parent(struct clk *cclk, struct clk *pclk)
> +long clk_round_rate(struct clk *clk, unsigned long drate)
> {
> - unsigned long flags;
> + long rate = 0;
> + int index;
> +
> + /*
> + * propagate call to parent who supports calc_rate. Similar approach is
> + * used in clk_set_rate.
> + */
> + if (!clk->calc_rate) {
> + u32 mult;
> + if (!clk->pclk)
> + return clk->rate;
> +
> + mult = clk->div_factor ? clk->div_factor : 1;
> + return clk_round_rate(clk->pclk, mult * drate) / mult;
> + }
>
Now it looks OK.
Reviewed-by: Stanley.Miao <stanley.miao@windriver.com>
Stanley.
>
>
>
^ permalink raw reply
* [PATCH 1/3] IPUv3: Add i.MX53 IPU support
From: Chen Jie-B02280 @ 2011-02-16 1:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTikD-=LJB2mmxG5jnBT_YXAcKfV6g5cXEvcWF4pV@mail.gmail.com>
Hi, Fabio,
You need do some cherry-pick from Sascha's ipuv3 branch to for-next.
Jason Chen / Chen Jie
NMG / MAD
Freescale Semiconductor (China) Ltd.
2F, Building B, 177#, Bi Bo Rd
Pu Dong New District Shanghai?201203
Tel:???? 021-28937178?
Fax:???? 021-28937444
E-mail:??Jason.Chen at freescale.com
-----Original Message-----
From: Fabio Estevam [mailto:festevam at gmail.com]
Sent: Wednesday, February 16, 2011 12:12 AM
To: Chen Jie-B02280
Cc: s.hauer at pengutronix.de; linux-arm-kernel at lists.infradead.org; Chen Jie-B02280
Subject: Re: [PATCH 1/3] IPUv3: Add i.MX53 IPU support
Hi Jason,
On Tue, Feb 15, 2011 at 6:56 AM, <jason.chen@freescale.com> wrote:
> From: Jason Chen <b02280@freescale.com>
>
> Signed-off-by: Jason Chen <b02280@freescale.com>
> ---
> ?arch/arm/mach-mx5/board-mx51_babbage.c ? ? ? ? ?| ? ?2 +-
> ?arch/arm/mach-mx5/devices-imx51.h ? ? ? ? ? ? ? | ? ?3 -
> ?arch/arm/plat-mxc/devices/platform-imx_ipuv3.c ?| ? 97
> +++++++++++++++++++++--
> ?arch/arm/plat-mxc/include/mach/devices-common.h | ? ?4 +-
> ?arch/arm/plat-mxc/include/mach/ipu-v3.h ? ? ? ? | ? ?1 +
> ?drivers/mfd/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?6 +-
> ?drivers/mfd/imx-ipu-v3/ipu-common.c ? ? ? ? ? ? | ? 66
> +++------------
> ?drivers/mfd/imx-ipu-v3/ipu-prv.h ? ? ? ? ? ? ? ?| ? 32 ++++----
> ?8 files changed, 126 insertions(+), 85 deletions(-)
Which git tree did you use for these patches?
I can not see a git tree that contains both the MX51 IPU and MX53LOCO board support.
Regards,
Fabio Estevam
^ permalink raw reply
* Question about ARM function graph tracing
From: Steven Rostedt @ 2011-02-16 2:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D5B2AC9.3030502@am.sony.com>
On Tue, 2011-02-15 at 17:39 -0800, Tim Bird wrote:
> On 02/04/2011 12:29 PM, Tim Bird wrote:
> >> OMAP is missing a notrace annotation on omap_readl():
> >>
> >> http://www.mail-archive.com/linux-omap at vger.kernel.org/msg38911.html
> >>
> >> Part of that patch was merged through rmk's work, but the
> >> omap_readl() annotation seems to have been missed.
> > Yep. It's missing in 2.6.38-rc3.
> >
> >> Also, if this is OMAP1 and not latest mainline, I think you
> >> will need a notrace on omap_rev() also (called from inside
> >> omap_readl() until recently).
> >
> > I couldn't find that in the sched_clock code paths, but
> > I 'notrace'd it anyways.
> >
> >>
> >> I think this is most probably what is wrong, since IIRC I saw
> >> crashes like this on BeagleBoard before I added the notrace on
> >> omap_readl. Could you please try with these changes?
> >
> > I have sprinkled 'notrace's liberally throughout the sched_clock
> > code (including omap_readl() and omap_rev()), and I'm still
> > seeing problems. I put a recursion guard in
> > prepare_ftrace_return, and I'm seeing lots of recursion. So
> > there's still a notrace missing somewhere.
Note, if you find that you need to add "notrace" to most functions in a
file, you can simply make the entire file "notrace" from the make file:
CFLAGS_REMOVE_myfile.o = -pg
>
> OK. The notrace was indeed missing fro omap_readl(), but fixing
> this did not completely fix the problem. I put the following
> (crude) recursion guard in arch/arm/kernel/ftrace.c:prepare_ftrace_return:
>
> diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
> index c0062ad..5872c25 100644
> --- a/arch/arm/kernel/ftrace.c
> +++ b/arch/arm/kernel/ftrace.c
> @@ -209,6 +209,8 @@ int __init ftrace_dyn_arch_init(void *data)
> #endif /* CONFIG_DYNAMIC_FTRACE */
>
> #ifdef CONFIG_FUNCTION_GRAPH_TRACER
> +static int already_here = 0;
> +
> void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
> unsigned long frame_pointer)
> {
> @@ -217,8 +219,16 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_a
> unsigned long old;
> int err;
>
> - if (unlikely(atomic_read(¤t->tracing_graph_pause)))
> + if(unlikely(already_here)) {
> return;
> + } else {
> + already_here=1;
> + }
Um, single cpu ?
> +
> + if (unlikely(atomic_read(¤t->tracing_graph_pause))) {
> + already_here=0;
> + return;
> + }
>
> old = *parent;
> *parent = return_hooker;
> @@ -227,6 +237,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_ad
> frame_pointer);
> if (err == -EBUSY) {
> *parent = old;
> + already_here=0;
> return;
> }
>
> @@ -237,6 +248,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_ad
> current->curr_ret_stack--;
> *parent = old;
> }
> + already_here=0;
> }
>
> #ifdef CONFIG_DYNAMIC_FTRACE
>
> Without this, the system hangs for long periods of time after starting
> the function graph tracer (echo function_graph >/debug/tracing/current_tracer)
> Sometimes the system comes back and sometimes it doesn't. With the above
> code, the system works, and I can get traces (but obviously I'm dumping
> a bunch of tracepoints whenever the tracer nests.)
>
> I put some extra instrumentation in, and MOST of the time, the item
> causing nesting is asm_do_IRQ(), which is to be expected. However,
> I have seen a recursion from preempt_schedule(), which I didn't really
> expect. Does the tracer invoke anything that would cause a schedule
> from inside the trace-recording code?
>
> Should I try this with CONFIG_PREEMPT off? (It's currently on.)
>
> Any ideas for debugging this would be appreciated.
I've had to debug things that broke in the function graph tracer like
this before. Is dynamic ftrace available in arm?
Hmm, from arch/arm/Kconfig:
select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL)
I guess so. If you are running something other than this XIP_KERNEL, I
would suggest using the dynamic functions to binary search the issue.
cat available_filter_functions > /tmp/funcs
Then copy half the funcs to /tmp/funcs1 and the other half
to /tmp/funcs2
cat /tmp/funcs1 > set_ftrace_filter
This may take a while, as setting the filter one by one is slow.
then run the function graph tracer. If it locks up, try it again
with /tmp/funcs2. If it locks up, you may have two issues or it could be
something wrong with the function graph tracer itself. But I'm betting
one will work and one wont.
Then just keep chopping these funcs files until you get down to a set of
functions that are causing issues. Then it should point out the problem.
This is the procedure I used to find out why a kvm guest was locking up
with function graph tracer.
See commit:
258af47479980d8238a04568b94a4e55aa1cb537
Something tells me you may have a similar issue ;)
-- Steve
^ permalink raw reply
* platform data and mfd design question
From: Mark Brown @ 2011-02-16 2:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D5AF554.2030208@codeaurora.org>
On Tue, Feb 15, 2011 at 01:51:16PM -0800, Abhijeet Dharmapurikar wrote:
> This code can be found here (sorry for the long url - it is convinient to
> click on it),
I can't actually render this URL on a single line without fiddling with
the font size for my terminal... When pasting gitweb URLs you almost
always want to edit out the head ID and just rely on the branch.
> This gives one the convenience of changing the mfd_cells and their
> platform data in the board file itself. There are boards where the
> platform data of some cells changes and in some cases we dont even
> add a particular cell.
My main question is why you're trying to do this. Even if some features
aren't used on a given board one would strongly expect that the silicon
will be the same anyway - what's the goal in changing the devices?
> This design makes the core driver very light weight. All it does is
> calls mfd_add_devices on the cell array passed from its platform
> data.
The downside is that it then becomes impossible for the MFD to pass in
resources to the devices (IRQs being the most obvious example) and every
single board needs to replicate the definitions of all the subdevices
which gets tedious, especially if you want to change them for some
reason (eg, an IP becomes used in a wider range of chips so a rename is
appropriate).
^ permalink raw reply
* [PATCH] spi/imx: select master mode for all channels
From: Grant Likely @ 2011-02-16 2:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110215204417.GA28005@angua.secretlab.ca>
2011/2/15 Grant Likely <grant.likely@secretlab.ca>:
> On Tue, Feb 08, 2011 at 09:08:59PM +0100, Uwe Kleine-K?nig wrote:
>> From: Sascha Hauer <s.hauer@pengutronix.de>
>>
>> The hardware seems to have a race condition when the inactive
>> channels are in slave mode. We support master mode only, so
>> we can just switch all channels to master mode.
>>
>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>> [ukleinek: add more verbose comment about the race]
>> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
>> ---
>> Hello,
>>
>> maybe one of our friends at Freescale can comment?
>
> Any feedback on this one? ?Or should I just merge it?
I've gone ahead and merged it. I can pull it back out if anyone
complains though.
Thanks,
g.
>
> g.
>
>>
>> Best regards
>> Uwe
>>
>> ?drivers/spi/spi_imx.c | ? 12 +++++++++---
>> ?1 files changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
>> index 1cf9d5f..69d6dba 100644
>> --- a/drivers/spi/spi_imx.c
>> +++ b/drivers/spi/spi_imx.c
>> @@ -174,7 +174,7 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin,
>> ?#define SPI_IMX2_3_CTRL ? ? ? ? ? ? ?0x08
>> ?#define SPI_IMX2_3_CTRL_ENABLE ? ? ? ? ? ? ? (1 << ?0)
>> ?#define SPI_IMX2_3_CTRL_XCH ? ? ? ? ?(1 << ?2)
>> -#define SPI_IMX2_3_CTRL_MODE(cs) ? ? (1 << ((cs) + ?4))
>> +#define SPI_IMX2_3_CTRL_MODE_MASK ? ?(0xf << 4)
>> ?#define SPI_IMX2_3_CTRL_POSTDIV_OFFSET ? ? ? 8
>> ?#define SPI_IMX2_3_CTRL_PREDIV_OFFSET ? ? ? ?12
>> ?#define SPI_IMX2_3_CTRL_CS(cs) ? ? ? ? ? ? ? ((cs) << 18)
>> @@ -253,8 +253,14 @@ static int __maybe_unused spi_imx2_3_config(struct spi_imx_data *spi_imx,
>> ?{
>> ? ? ? u32 ctrl = SPI_IMX2_3_CTRL_ENABLE, cfg = 0;
>>
>> - ? ? /* set master mode */
>> - ? ? ctrl |= SPI_IMX2_3_CTRL_MODE(config->cs);
>> + ? ? /*
>> + ? ? ?* The hardware seems to have a race condition when changing modes. The
>> + ? ? ?* current assumption is that the selection of the channel arrives
>> + ? ? ?* earlier in the hardware than the mode bits when they are written at
>> + ? ? ?* the same time.
>> + ? ? ?* So set master mode for all channels as we do not support slave mode.
>> + ? ? ?*/
>> + ? ? ctrl |= SPI_IMX2_3_CTRL_MODE_MASK;
>>
>> ? ? ? /* set clock speed */
>> ? ? ? ctrl |= spi_imx2_3_clkdiv(spi_imx->spi_clk, config->speed_hz);
>> --
>> 1.7.2.3
>>
>>
>> ------------------------------------------------------------------------------
>> The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
>> Pinpoint memory and threading errors before they happen.
>> Find and fix more than 250 security defects in the development cycle.
>> Locate bottlenecks in serial and parallel code that limit performance.
>> http://p.sf.net/sfu/intel-dev2devfeb
>> _______________________________________________
>> spi-devel-general mailing list
>> spi-devel-general at lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/spi-devel-general
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* compiling 2.6.37 kernel in THUMB2 mode
From: Nicolas Pitre @ 2011-02-16 4:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=bJwvTMk0B9N5AAbkNXEh_Wmvu75qrdHeL2Rrh@mail.gmail.com>
On Tue, 15 Feb 2011, vb at vsbe.com wrote:
> hello all,
>
> I am trying to compile the 2.6.37 kernel in THUMB2 mode and am
> experiencing some compilation problems. Some inline assembly in some
> files uses commands inappropriate for THUMB2 mode.
>
> I wonder if the kernel is expected to compile cleanly when
> CONFIG_THUMB2_KERNEL is enabled (and I am doing something wrong), or
> is it know not to compile/work in Thumb2 node for any reason?
It is known not to compile in mainline right now depending on your
target, but fixes are slowly being merged upstream.
Dave Martin is maintaining a Git tree with all the fixes required for
Thumb2 here (see the Thumb2 related branches):
http://git.linaro.org/gitweb?p=people/dmart/linux-2.6-arm.git;a=summary
Beware that some patches might not be final yet.
Nicolas
^ 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