* [PATCH v3] spi: spi-fsl-dspi: Add DMA support for Vybrid
From: Sanchayan Maity @ 2016-11-10 12:19 UTC (permalink / raw)
To: linux-arm-kernel
Add DMA support for Vybrid.
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
---
Changes since v2:
1. Rebase on top of Shawn's latest for-next branch
2. Make DMA mode the default for Vybrid. We no longer use the EOQ mode.
Since devtype_data has been constantified it's no longer makes sense to
change the trans_mode at run time.
Tested on Toradex Colibri Vybrid VF61 module using spidev and MCP CAN.
v1 Patch:
https://patchwork.kernel.org/patch/9360583/
v2 Patch:
https://patchwork.kernel.org/patch/9361601/
Regards,
Sanchayan.
---
drivers/spi/spi-fsl-dspi.c | 301 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 300 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 35c0dd9..bc64700 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -15,6 +15,8 @@
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
@@ -40,6 +42,7 @@
#define TRAN_STATE_WORD_ODD_NUM 0x04
#define DSPI_FIFO_SIZE 4
+#define DSPI_DMA_BUFSIZE (DSPI_FIFO_SIZE * 1024)
#define SPI_MCR 0x00
#define SPI_MCR_MASTER (1 << 31)
@@ -71,6 +74,11 @@
#define SPI_SR_EOQF 0x10000000
#define SPI_SR_TCFQF 0x80000000
+#define SPI_RSER_TFFFE BIT(25)
+#define SPI_RSER_TFFFD BIT(24)
+#define SPI_RSER_RFDFE BIT(17)
+#define SPI_RSER_RFDFD BIT(16)
+
#define SPI_RSER 0x30
#define SPI_RSER_EOQFE 0x10000000
#define SPI_RSER_TCFQE 0x80000000
@@ -108,6 +116,8 @@
#define SPI_TCR_TCNT_MAX 0x10000
+#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
+
struct chip_data {
u32 mcr_val;
u32 ctar_val;
@@ -117,6 +127,7 @@ struct chip_data {
enum dspi_trans_mode {
DSPI_EOQ_MODE = 0,
DSPI_TCFQ_MODE,
+ DSPI_DMA_MODE,
};
struct fsl_dspi_devtype_data {
@@ -125,7 +136,7 @@ struct fsl_dspi_devtype_data {
};
static const struct fsl_dspi_devtype_data vf610_data = {
- .trans_mode = DSPI_EOQ_MODE,
+ .trans_mode = DSPI_DMA_MODE,
.max_clock_factor = 2,
};
@@ -139,6 +150,22 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
.max_clock_factor = 8,
};
+struct fsl_dspi_dma {
+ u32 curr_xfer_len;
+
+ u32 *tx_dma_buf;
+ struct dma_chan *chan_tx;
+ dma_addr_t tx_dma_phys;
+ struct completion cmd_tx_complete;
+ struct dma_async_tx_descriptor *tx_desc;
+
+ u32 *rx_dma_buf;
+ struct dma_chan *chan_rx;
+ dma_addr_t rx_dma_phys;
+ struct completion cmd_rx_complete;
+ struct dma_async_tx_descriptor *rx_desc;
+};
+
struct fsl_dspi {
struct spi_master *master;
struct platform_device *pdev;
@@ -165,6 +192,7 @@ struct fsl_dspi {
u32 waitflags;
u32 spi_tcnt;
+ struct fsl_dspi_dma *dma;
};
static inline int is_double_byte_mode(struct fsl_dspi *dspi)
@@ -176,6 +204,263 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi)
return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
}
+static void dspi_tx_dma_callback(void *arg)
+{
+ struct fsl_dspi *dspi = arg;
+ struct fsl_dspi_dma *dma = dspi->dma;
+
+ complete(&dma->cmd_tx_complete);
+}
+
+static void dspi_rx_dma_callback(void *arg)
+{
+ struct fsl_dspi *dspi = arg;
+ struct fsl_dspi_dma *dma = dspi->dma;
+ int rx_word;
+ int i, len;
+ u16 d;
+
+ rx_word = is_double_byte_mode(dspi);
+
+ len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+ if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+ for (i = 0; i < len; i++) {
+ d = dspi->dma->rx_dma_buf[i];
+ rx_word ? (*(u16 *)dspi->rx = d) :
+ (*(u8 *)dspi->rx = d);
+ dspi->rx += rx_word + 1;
+ }
+ }
+
+ complete(&dma->cmd_rx_complete);
+}
+
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
+{
+ struct fsl_dspi_dma *dma = dspi->dma;
+ struct device *dev = &dspi->pdev->dev;
+ int time_left;
+ int tx_word;
+ int i, len;
+ u16 val;
+
+ tx_word = is_double_byte_mode(dspi);
+
+ len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
+
+ for (i = 0; i < len - 1; i++) {
+ val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+ dspi->dma->tx_dma_buf[i] =
+ SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
+ SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+ dspi->tx += tx_word + 1;
+ }
+
+ val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+ dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
+ SPI_PUSHR_PCS(dspi->cs) |
+ SPI_PUSHR_CTAS(0);
+ dspi->tx += tx_word + 1;
+
+ dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
+ dma->tx_dma_phys,
+ DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!dma->tx_desc) {
+ dev_err(dev, "Not able to get desc for DMA xfer\n");
+ return -EIO;
+ }
+
+ dma->tx_desc->callback = dspi_tx_dma_callback;
+ dma->tx_desc->callback_param = dspi;
+ if (dma_submit_error(dmaengine_submit(dma->tx_desc))) {
+ dev_err(dev, "DMA submit failed\n");
+ return -EINVAL;
+ }
+
+ dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
+ dma->rx_dma_phys,
+ DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!dma->rx_desc) {
+ dev_err(dev, "Not able to get desc for DMA xfer\n");
+ return -EIO;
+ }
+
+ dma->rx_desc->callback = dspi_rx_dma_callback;
+ dma->rx_desc->callback_param = dspi;
+ if (dma_submit_error(dmaengine_submit(dma->rx_desc))) {
+ dev_err(dev, "DMA submit failed\n");
+ return -EINVAL;
+ }
+
+ reinit_completion(&dspi->dma->cmd_rx_complete);
+ reinit_completion(&dspi->dma->cmd_tx_complete);
+
+ dma_async_issue_pending(dma->chan_rx);
+ dma_async_issue_pending(dma->chan_tx);
+
+ time_left = wait_for_completion_timeout(&dspi->dma->cmd_tx_complete,
+ DMA_COMPLETION_TIMEOUT);
+ if (time_left == 0) {
+ dev_err(dev, "DMA tx timeout\n");
+ dmaengine_terminate_all(dma->chan_tx);
+ dmaengine_terminate_all(dma->chan_rx);
+ return -ETIMEDOUT;
+ }
+
+ time_left = wait_for_completion_timeout(&dspi->dma->cmd_rx_complete,
+ DMA_COMPLETION_TIMEOUT);
+ if (time_left == 0) {
+ dev_err(dev, "DMA rx timeout\n");
+ dmaengine_terminate_all(dma->chan_tx);
+ dmaengine_terminate_all(dma->chan_rx);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int dspi_dma_xfer(struct fsl_dspi *dspi)
+{
+ struct fsl_dspi_dma *dma = dspi->dma;
+ struct device *dev = &dspi->pdev->dev;
+ int curr_remaining_bytes;
+ int bytes_per_buffer;
+ int tx_word;
+ int ret = 0;
+
+ tx_word = is_double_byte_mode(dspi);
+ curr_remaining_bytes = dspi->len;
+ while (curr_remaining_bytes) {
+ /* Check if current transfer fits the DMA buffer */
+ dma->curr_xfer_len = curr_remaining_bytes;
+ bytes_per_buffer = DSPI_DMA_BUFSIZE /
+ (DSPI_FIFO_SIZE / (tx_word ? 2 : 1));
+ if (curr_remaining_bytes > bytes_per_buffer)
+ dma->curr_xfer_len = bytes_per_buffer;
+
+ ret = dspi_next_xfer_dma_submit(dspi);
+ if (ret) {
+ dev_err(dev, "DMA transfer failed\n");
+ goto exit;
+
+ } else {
+ curr_remaining_bytes -= dma->curr_xfer_len;
+ if (curr_remaining_bytes < 0)
+ curr_remaining_bytes = 0;
+ dspi->len = curr_remaining_bytes;
+ }
+ }
+
+exit:
+ return ret;
+}
+
+static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
+{
+ struct fsl_dspi_dma *dma;
+ struct dma_slave_config cfg;
+ struct device *dev = &dspi->pdev->dev;
+ int ret;
+
+ dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
+ if (!dma)
+ return -ENOMEM;
+
+ dma->chan_rx = dma_request_slave_channel(dev, "rx");
+ if (!dma->chan_rx) {
+ dev_err(dev, "rx dma channel not available\n");
+ ret = -ENODEV;
+ return ret;
+ }
+
+ dma->chan_tx = dma_request_slave_channel(dev, "tx");
+ if (!dma->chan_tx) {
+ dev_err(dev, "tx dma channel not available\n");
+ ret = -ENODEV;
+ goto err_tx_channel;
+ }
+
+ dma->tx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
+ &dma->tx_dma_phys, GFP_KERNEL);
+ if (!dma->tx_dma_buf) {
+ ret = -ENOMEM;
+ goto err_tx_dma_buf;
+ }
+
+ dma->rx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
+ &dma->rx_dma_phys, GFP_KERNEL);
+ if (!dma->rx_dma_buf) {
+ ret = -ENOMEM;
+ goto err_rx_dma_buf;
+ }
+
+ cfg.src_addr = phy_addr + SPI_POPR;
+ cfg.dst_addr = phy_addr + SPI_PUSHR;
+ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ cfg.src_maxburst = 1;
+ cfg.dst_maxburst = 1;
+
+ cfg.direction = DMA_DEV_TO_MEM;
+ ret = dmaengine_slave_config(dma->chan_rx, &cfg);
+ if (ret) {
+ dev_err(dev, "can't configure rx dma channel\n");
+ ret = -EINVAL;
+ goto err_slave_config;
+ }
+
+ cfg.direction = DMA_MEM_TO_DEV;
+ ret = dmaengine_slave_config(dma->chan_tx, &cfg);
+ if (ret) {
+ dev_err(dev, "can't configure tx dma channel\n");
+ ret = -EINVAL;
+ goto err_slave_config;
+ }
+
+ dspi->dma = dma;
+ init_completion(&dma->cmd_tx_complete);
+ init_completion(&dma->cmd_rx_complete);
+
+ return 0;
+
+err_slave_config:
+ devm_kfree(dev, dma->rx_dma_buf);
+err_rx_dma_buf:
+ devm_kfree(dev, dma->tx_dma_buf);
+err_tx_dma_buf:
+ dma_release_channel(dma->chan_tx);
+err_tx_channel:
+ dma_release_channel(dma->chan_rx);
+
+ devm_kfree(dev, dma);
+ dspi->dma = NULL;
+
+ return ret;
+}
+
+static void dspi_release_dma(struct fsl_dspi *dspi)
+{
+ struct fsl_dspi_dma *dma = dspi->dma;
+ struct device *dev = &dspi->pdev->dev;
+
+ if (dma) {
+ if (dma->chan_tx) {
+ dma_unmap_single(dev, dma->tx_dma_phys,
+ DSPI_DMA_BUFSIZE, DMA_TO_DEVICE);
+ dma_release_channel(dma->chan_tx);
+ }
+
+ if (dma->chan_rx) {
+ dma_unmap_single(dev, dma->rx_dma_phys,
+ DSPI_DMA_BUFSIZE, DMA_FROM_DEVICE);
+ dma_release_channel(dma->chan_rx);
+ }
+ }
+}
+
static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
unsigned long clkrate)
{
@@ -424,6 +709,12 @@ static int dspi_transfer_one_message(struct spi_master *master,
regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_TCFQE);
dspi_tcfq_write(dspi);
break;
+ case DSPI_DMA_MODE:
+ regmap_write(dspi->regmap, SPI_RSER,
+ SPI_RSER_TFFFE | SPI_RSER_TFFFD |
+ SPI_RSER_RFDFE | SPI_RSER_RFDFD);
+ status = dspi_dma_xfer(dspi);
+ goto out;
default:
dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n",
trans_mode);
@@ -733,6 +1024,13 @@ static int dspi_probe(struct platform_device *pdev)
if (ret)
goto out_master_put;
+ if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
+ if (dspi_request_dma(dspi, res->start)) {
+ dev_err(&pdev->dev, "can't get dma channels\n");
+ goto out_clk_put;
+ }
+ }
+
master->max_speed_hz =
clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor;
@@ -761,6 +1059,7 @@ static int dspi_remove(struct platform_device *pdev)
struct fsl_dspi *dspi = spi_master_get_devdata(master);
/* Disconnect from the SPI framework */
+ dspi_release_dma(dspi);
clk_disable_unprepare(dspi->clk);
spi_unregister_master(dspi->master);
--
2.10.2
^ permalink raw reply related
* [PATCH v2 1/2] iommu/dma: Implement dma_{map,unmap}_resource()
From: Joerg Roedel @ 2016-11-10 12:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4e84146ae49a4edd5f1226d76617be9aa92a58ee.1477503578.git.robin.murphy@arm.com>
On Wed, Oct 26, 2016 at 06:43:56PM +0100, Robin Murphy wrote:
> With the new dma_{map,unmap}_resource() functions added to the DMA API
> for the benefit of cases like slave DMA, add suitable implementations to
> the arsenal of our generic layer. Since cache maintenance should not be
> a concern, these can both be standalone callback implementations without
> the need for arch code wrappers.
>
> CC: Joerg Roedel <joro@8bytes.org>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>
> v2: Use iommu_dma_unmap_page for symmetry, instead of being sneaky.
>
> drivers/iommu/dma-iommu.c | 13 +++++++++++++
> include/linux/dma-iommu.h | 4 ++++
> 2 files changed, 17 insertions(+)
>
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index c5ab8667e6f2..a2fd90a6a782 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -624,6 +624,19 @@ void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
> __iommu_dma_unmap(iommu_get_domain_for_dev(dev), sg_dma_address(sg));
> }
>
> +dma_addr_t iommu_dma_map_resource(struct device *dev, phys_addr_t phys,
> + size_t size, enum dma_data_direction dir, unsigned long attrs)
> +{
> + return iommu_dma_map_page(dev, phys_to_page(phys), offset_in_page(phys),
> + size, dma_direction_to_prot(dir, false) | IOMMU_MMIO);
> +}
Isn't the whole point of map_resource that we can map regions which have
no 'struct page' associated? The use phys_to_page() will certainly not
do the right thing here.
Joerg
^ permalink raw reply
* [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06
From: zhichang.yuan @ 2016-11-10 12:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <17821285.aIcTyCGn5n@wuerfel>
Hi, Arnd,
On 2016/11/10 17:12, Arnd Bergmann wrote:
> On Thursday, November 10, 2016 2:40:26 PM CET zhichang.yuan wrote:
>> On 2016/11/10 5:34, Arnd Bergmann wrote:
>>> On Wednesday, November 9, 2016 12:10:43 PM CET Gabriele Paoloni wrote:
>>>>> On Tuesday, November 8, 2016 11:47:09 AM CET zhichang.yuan wrote:
>>>>>> + /*
>>>>>> + * The first PCIBIOS_MIN_IO is reserved specifically for
>>>>> indirectIO.
>>>>>> + * It will separate indirectIO range from pci host bridge to
>>>>>> + * avoid the possible PIO conflict.
>>>>>> + * Set the indirectIO range directly here.
>>>>>> + */
>>>>>> + lpcdev->io_ops.start = 0;
>>>>>> + lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1;
>>>>>> + lpcdev->io_ops.devpara = lpcdev;
>>>>>> + lpcdev->io_ops.pfin = hisilpc_comm_in;
>>>>>> + lpcdev->io_ops.pfout = hisilpc_comm_out;
>>>>>> + lpcdev->io_ops.pfins = hisilpc_comm_ins;
>>>>>> + lpcdev->io_ops.pfouts = hisilpc_comm_outs;
>>>>>
>>>>> I have to look at patch 2 in more detail again, after missing a few
>>>>> review
>>>>> rounds. I'm still a bit skeptical about hardcoding a logical I/O port
>>>>> range here, and would hope that we can just go through the same
>>>>> assignment of logical port ranges that we have for PCI buses,
>>>>> decoupling
>>>>> the bus addresses from the linux-internal ones.
>>>>
>>>> The point here is that we want to avoid any conflict/overlap between
>>>> the LPC I/O space and the PCI I/O space. With the assignment above
>>>> we make sure that LPC never interfere with PCI I/O space.
>>>
>>> But we already abstract the PCI I/O space using dynamic registration.
>>> There is no need to hardcode the logical address for ISA, though
>>> I think we can hardcode the bus address to start at zero here.
>>
>> Do you means that we can pick up the maximal I/O address from all children's
>> device resources??
>
> The driver should not look at the resources of its children, just
> register a range of addresses dynamically, as I suggested in an
> earlier review.
>
Sorry! I can't catch your idea yet:(
When to register the I/O range? Is it done just after the successfully
of_translate_address() during the children scanning?
If yes, when a child is scanning, there is no range data in arm64_extio_ops. The
addr_is_indirect_io() calling in of_get_isa_indirect_io() don't need. All we can
check is just whether the address to be translated is IO and is under a parent
device which has no 'ranges' property.
>
> Your current version has
>
> if (arm64_extio_ops->pfout) \
> arm64_extio_ops->pfout(arm64_extio_ops->devpara,\
> addr, value, sizeof(type)); \
>
> Instead, just subtract the start of the range from the logical
> port number to transform it back into a bus-local port number:
>
> if (arm64_extio_ops->pfout) \
> arm64_extio_ops->pfout(arm64_extio_ops->devpara,\
> addr - arm64_extio_ops->start, value, sizeof(type)); \
>
I think there is some information needed sync.
In the old patch-set, we don't bypass the pci_address_to_pio() after
successfully of_translate_address(). In this way, we don't need to reserve any
PIO space for our LPC since the logical port are from the same mapping
algorithm. Based on this way, the port number in the device resource is logical
one, then we need to subtract the start of the resource to get back the
bus-local port.
>From V3, we don't apply the mapping based on pci_address_to_pio(), the
of_translate_address() return the bus-local port directly and store into
relevant device resource. So, in the current arm64_extio_ops->pfout(), the
reverse translation don't need anymore. The input "addr" is bus-local port now.
Thanks,
Zhichang
> We know that the ISA/LPC bus can only have up to 65536 ports,
> so you can register all of those, or possibly limit it further to
> 1024 or 4096 ports, whichever matches the bus implementation.
>
> Arnd
>
> .
>
^ permalink raw reply
* [PATCH v3 1/2] ARM: EXYNOS: Remove static mapping of SCU SFR
From: pankaj.dubey @ 2016-11-10 12:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5066943.nydi3GQ3KP@wuerfel>
Hi Arnd,
On Thursday 10 November 2016 05:24 PM, Arnd Bergmann wrote:
> On Wednesday, November 9, 2016 5:45:54 PM CET Pankaj Dubey wrote:
>> Lets remove static mapping of SCU SFR mainly used in CORTEX-A9 SoC based
>> boards. Instead use mapping from device tree node of SCU.
>>
>> NOTE: This patch has dependency on DT file of any such CORTEX-A9 SoC
>> based boards, in the absence of SCU device node in DTS file, only single
>> CPU will boot. So if you are using OUT-OF-TREE DTS file of CORTEX-A9 based
>> Exynos SoC make sure to add SCU device node to DTS file for SMP boot.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
>
> With CONFIG_SMP disabled, I now get this build failure:
>
Sorry, I missed this part and did not check with CONFIG_SMP disabled.
> arch/arm/mach-exynos/pm.o: In function `exynos_enter_aftr':
> pm.c:(.text.exynos_enter_aftr+0xec): undefined reference to `exynos_scu_enable'
> arch/arm/mach-exynos/suspend.o: In function `exynos_pm_resume':
> suspend.c:(.text.exynos_pm_resume+0x78): undefined reference to `exynos_scu_enable'
>
> Please fix. I have applied a patch locally (see below), but don't know
> if that is the best solution. As we seem to duplicate that code across
> several platforms, I wonder why we don't just put it into the core scu
> implementation.
>
When I checked scu_enable declaration it is defined in
arch/arm/include/asm/smp_scu.h as:
#if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU)
void scu_enable(void __iomem *scu_base);
#else
static inline void scu_enable(void __iomem *scu_base) {}
#endif
So if CONFIG_SMP is disable then there is no sense of exynos_scu_enable
as well. So wow about using below patch?
--------------------------------------------------------
Subject: [PATCH] ARM: exynos: fix build fail due to exynos_scu_enable
Build failed if we disable CONFIG_SMP as shown below:
arch/arm/mach-exynos/pm.o: In function `exynos_enter_aftr':
pm.c:(.text.exynos_enter_aftr+0xec): undefined reference to
`exynos_scu_enable'
arch/arm/mach-exynos/suspend.o: In function `exynos_pm_resume':
suspend.c:(.text.exynos_pm_resume+0x78): undefined reference to
`exynos_scu_enable'
Since scu_enable is defined only in case CONFIG_SMP and CONFIG_HAVE_ARM_SCU
lets move exynos_scu_enable also under these two macros.
Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
arch/arm/mach-exynos/common.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index fb12d11..03fdb79 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -156,7 +156,12 @@ extern void exynos_cpu_restore_register(void);
extern void exynos_pm_central_suspend(void);
extern int exynos_pm_central_resume(void);
extern void exynos_enter_aftr(void);
+#if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU)
extern int exynos_scu_enable(void);
+#else
+static inline void exynos_scu_enable(void) {}
+#endif
+
------------------------------------------------------
Of-course your idea to move it in core SCU file is also good that we
lots of duplication in different architecture can be avoided.
In that case I can think of following patch:
[PATCH] ARM: scu: use SCU device node to enable SCU
Many platforms are duplicating code for enabling SCU, lets add
common code to enable SCU using SCU device node so the duplication in
each platform can be avoided.
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
arch/arm/include/asm/smp_scu.h | 2 ++
arch/arm/kernel/smp_scu.c | 17 +++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
index bfe163c..e5e2492 100644
--- a/arch/arm/include/asm/smp_scu.h
+++ b/arch/arm/include/asm/smp_scu.h
@@ -38,8 +38,10 @@ static inline int scu_power_mode(void __iomem
*scu_base, unsigned int mode)
#endif
#if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU)
+int of_scu_enable(void);
void scu_enable(void __iomem *scu_base);
#else
+static inline int of_scu_enable(void) {return 0;}
static inline void scu_enable(void __iomem *scu_base) {}
#endif
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index 72f9241..7c16d16 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -34,6 +34,23 @@ unsigned int __init scu_get_core_count(void __iomem
*scu_base)
return (ncores & 0x03) + 1;
}
+int of_scu_enable(void)
+{
+ struct device_node *np;
+ void __iomem *scu_base;
+
+ np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+ scu_base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!scu_base) {
+ pr_err("%s failed to map scu_base\n", __func__);
+ return -ENOMEM;
+ }
+ scu_enable(scu_base);
+ iounmap(scu_base);
+ return 0;
+}
+
/*
* Enable the SCU
*/
--
Followed by cleanup in various architecture where this piece of code is
duplicated and all of them can call directly of_scu_enable()
Please let me know which one you will prefer for fixing build issue.
@Krzysztof, please let me know if I need to resubmit SCU series again
with fix or you will accept build fix patch on top of already taken patch.
Thanks,
Pankaj Dubey
^ permalink raw reply related
* [RFC v2 4/8] iommu: Add a list of iommu_reserved_region in iommu_domain
From: Robin Murphy @ 2016-11-10 12:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6c2e1c81-e951-a284-b547-733369128e7e@redhat.com>
On 10/11/16 12:14, Auger Eric wrote:
> Hi Robin,
>
> On 10/11/2016 12:54, Robin Murphy wrote:
>> Hi Eric,
>>
>> On 10/11/16 11:22, Auger Eric wrote:
>>> Hi Robin,
>>>
>>> On 04/11/2016 15:00, Robin Murphy wrote:
>>>> Hi Eric,
>>>>
>>>> Thanks for posting this new series - the bottom-up approach is a lot
>>>> easier to reason about :)
>>>>
>>>> On 04/11/16 11:24, Eric Auger wrote:
>>>>> Introduce a new iommu_reserved_region struct. This embodies
>>>>> an IOVA reserved region that cannot be used along with the IOMMU
>>>>> API. The list is protected by a dedicated mutex.
>>>>
>>>> In the light of these patches, I think I'm settling into agreement that
>>>> the iommu_domain is the sweet spot for accessing this information - the
>>>> underlying magic address ranges might be properties of various bits of
>>>> hardware many of which aren't the IOMMU itself, but they only start to
>>>> matter at the point you start wanting to use an IOMMU domain at the
>>>> higher level. Therefore, having a callback in the domain ops to pull
>>>> everything together fits rather neatly.
>>> Using get_dm_regions could have make sense but this approach now is
>>> ruled out by sysfs API approach. If attribute file is bound to be used
>>> before iommu domains are created, we cannot rely on any iommu_domain
>>> based callback. Back to square 1?
>>
>> I think it's still OK. The thing about these reserved regions is that as
>> a property of the underlying hardware they must be common to any domain
>> for a given group, therefore without loss of generality we can simply
>> query group->domain->ops->get_dm_regions(), and can expect the reserved
>> ones will be the same regardless of what domain that points to
>> (identity-mapped IVMD/RMRR/etc.
> Are they really? P2P reserved regions depend on iommu_domain right?
Indeed. To use the SMMU example, reprogramming S2CRs to target a
different context bank (i.e. attaching to a different domain) won't
affect the fact that the transactions aren't even reaching the SMMU in
the first place. That's why we need the exact same information for DMA
domains, thus why getting it for free via the dm_regions mechanism would
be really neat.
The visibility of P2P regions, doorbells, etc. for a given device is
ultimately a property of the hardware topology, and topology happens to
be what the iommu_group already represents*. There looks to be a snag
when we try to consider the addresses of such regions, since addresses
are the business of iommu_domains, not groups, but as there is a 1:1
relationship between a group and its default domain, things end up tying
together quite neatly.
Robin.
*in fact, I've just had an idea that way we check ACS paths to determine
groups might similarly be a finer-grained way to detect what P2P
regions, if any, are actually relevant.
> Now I did not consider default_domain usability, I acknowledge. I will
> send a POC anyway.
>
> regions may not be, but we'd be
>> filtering those out anyway). The default DMA domains need this
>> information too, and since those are allocated at group creation,
>> group->domain should always be non-NULL and interrogable.
>>
>> Plus, the groups are already there in sysfs, and, being representative
>> of device topology, would seem to be an ideal place to expose the
>> addressing limitations relevant to the devices within them. This really
>> feels like it's all falling into place (on the kernel end, at least, I'm
>> sticking to the sidelines on the userspace discussion ;)).
>
> Thanks
>
> Eric
>>
>> Robin.
>>
>>>
>>> Thanks
>>>
>>> Eric
>>>>
>>>>>
>>>>> An iommu domain now owns a list of those.
>>>>>
>>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>>>
>>>>> ---
>>>>> ---
>>>>> drivers/iommu/iommu.c | 2 ++
>>>>> include/linux/iommu.h | 17 +++++++++++++++++
>>>>> 2 files changed, 19 insertions(+)
>>>>>
>>>>> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
>>>>> index 9a2f196..0af07492 100644
>>>>> --- a/drivers/iommu/iommu.c
>>>>> +++ b/drivers/iommu/iommu.c
>>>>> @@ -1061,6 +1061,8 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
>>>>>
>>>>> domain->ops = bus->iommu_ops;
>>>>> domain->type = type;
>>>>> + INIT_LIST_HEAD(&domain->reserved_regions);
>>>>> + mutex_init(&domain->resv_mutex);
>>>>> /* Assume all sizes by default; the driver may override this later */
>>>>> domain->pgsize_bitmap = bus->iommu_ops->pgsize_bitmap;
>>>>>
>>>>> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
>>>>> index 436dc21..0f2eb64 100644
>>>>> --- a/include/linux/iommu.h
>>>>> +++ b/include/linux/iommu.h
>>>>> @@ -84,6 +84,8 @@ struct iommu_domain {
>>>>> void *handler_token;
>>>>> struct iommu_domain_geometry geometry;
>>>>> void *iova_cookie;
>>>>> + struct list_head reserved_regions;
>>>>> + struct mutex resv_mutex; /* protects the reserved region list */
>>>>> };
>>>>>
>>>>> enum iommu_cap {
>>>>> @@ -131,6 +133,21 @@ struct iommu_dm_region {
>>>>> int prot;
>>>>> };
>>>>>
>>>>> +/**
>>>>> + * struct iommu_reserved_region - descriptor for a reserved iova region
>>>>> + * @list: Linked list pointers
>>>>> + * @start: IOVA base address of the region
>>>>> + * @length: Length of the region in bytes
>>>>> + */
>>>>> +struct iommu_reserved_region {
>>>>> + struct list_head list;
>>>>> + dma_addr_t start;
>>>>> + size_t length;
>>>>> +};
>>>>
>>>> Looking at this in context with the dm_region above, though, I come to
>>>> the surprising realisation that these *are* dm_regions, even at the
>>>> fundamental level - on the one hand you've got physical addresses which
>>>> can't be remapped (because something is already using them), while on
>>>> the other you've got physical addresses which can't be remapped (because
>>>> the IOMMU is incapable). In fact for reserved regions *other* than our
>>>> faked-up MSI region there's no harm if the IOMMU were to actually
>>>> identity-map them.
>>>>
>>>> Let's just add this to the existing infrastructure, either with some
>>>> kind of IOMMU_NOMAP flag or simply prot = 0. That way it automatically
>>>> gets shared between the VFIO and DMA cases for free!
>>>>
>>>> Robin.
>>>>
>>>>> +
>>>>> +#define iommu_reserved_region_for_each(resv, d) \
>>>>> + list_for_each_entry(resv, &(d)->reserved_regions, list)
>>>>> +
>>>>> #ifdef CONFIG_IOMMU_API
>>>>>
>>>>> /**
>>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> linux-arm-kernel mailing list
>>>> linux-arm-kernel at lists.infradead.org
>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>>
>>
^ permalink raw reply
* PM regression with LED changes in next-20161109
From: Jacek Anaszewski @ 2016-11-10 12:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f627c778-4378-e5da-09dd-3e0fb2ea4aba@redhat.com>
Hi,
On 11/10/2016 09:49 AM, Hans de Goede wrote:
> Hi,
>
> On 09-11-16 21:45, Jacek Anaszewski wrote:
>> Hi Tony,
>>
>> On 11/09/2016 08:23 PM, Tony Lindgren wrote:
>>> Hi,
>>>
>>> Looks like commit 883d32ce3385 ("leds: core: Add support for poll()ing
>>> the sysfs brightness attr for changes.") breaks runtime PM for me.
>>>
>>> On my omap dm3730 based test system, idle power consumption is over 70
>>> times higher now with this patch! It goes from about 6mW for the core
>>> system to over 440mW during idle meaning there's some busy timer now
>>> active.
>>>
>>> Reverting this patch fixes the issue. Any ideas?
>>
>> Thanks for the report. This is probably caused by sysfs_notify_dirent().
>> I'm afraid that we can't keep this feature in the current shape.
>> Hans, I'm dropping the patch. We probably will have to delegate this
>> call to a workqueue task. Think about use cases when the LED is blinked
>> with high frequency e.g. from ledtrig-disk.c.
>
> sysfs_notify_dirent() already uses a workqueue, here is the actual
> implementation of it (from fs/kernfs/file.c) :
>
> void kernfs_notify(struct kernfs_node *kn)
> {
> static DECLARE_WORK(kernfs_notify_work, kernfs_notify_workfn);
> unsigned long flags;
>
> if (WARN_ON(kernfs_type(kn) != KERNFS_FILE))
> return;
>
> spin_lock_irqsave(&kernfs_notify_lock, flags);
> if (!kn->attr.notify_next) {
> kernfs_get(kn);
> kn->attr.notify_next = kernfs_notify_list;
> kernfs_notify_list = kn;
> schedule_work(&kernfs_notify_work);
> }
> spin_unlock_irqrestore(&kernfs_notify_lock, flags);
> }
Indeed. As a next step of this investigation Tony could disable
particular calls made in kernfs_notify_workfn to check what
exactly causes excessive power consumption.
> So using a workqueue is not going to help. Note that I already
> feared this, which is why my initial implementation only called
> sysfs_notify_dirent() for user initiated changes and not for
> triggers / blinking.
AFAIR there were no calls to led_notify_brightness_change() in
the initial implementation and it was entirely predestined for
being called by LED class drivers on brightness changes made
by firmware.
> I think we may need to reconsider what getting the brightness
> sysfs atrribute actually returns. Currently when a LED is
> blinking it will return 0 resp. the actual brightness depending
> on when in the blink cycle the user reads the brightness
> sysfs atrribute.
>
> So a user can do "echo 128 > brightness && cat brightness" and
> get out 0, or 128, depending purely on timing.
>
> This seems to contradict what Documentation/ABI/testing/sysfs-class-led
> has to say:
>
> What: /sys/class/leds/<led>/brightness
> Date: March 2006
> KernelVersion: 2.6.17
> Contact: Richard Purdie <rpurdie@rpsys.net>
> Description:
> Set the brightness of the LED. Most LEDs don't
> have hardware brightness support, so will just be turned
> on for
> non-zero brightness settings. The value is between 0 and
> /sys/class/leds/<led>/max_brightness.
>
> Writing 0 to this file clears active trigger.
>
> Writing non-zero to this file while trigger is active
> changes the
> top brightness trigger is going to use.
>
> Even though it only talks about writing, the logical thing would be for
> reading to be the exact opposite of writing, so we would get:
>
> Reading from this file while a trigger is active returns
> the
> top brightness trigger is going to use.
>
> The current docs say not about (sw) blinking, but that should be treated
> just
> like a trigger IMHO.
You'r right, we should describe the semantics on reading, but it would
have to be as follows:
Reading from this file returns LED brightness at given moment, i.e.
even though LED class device brightness setting is greater than 0, the
momentary brightness can be 0 if the readout occurred during low phase
of blink cycle.
> If we can get consensus on what the read behavior for the brightness
> attribute
> should be, then I think that a better poll() behavior will automatically
> follow
> from that.
It seems that we should get back to your initial approach. i.e. only
brightness changes caused by hardware should be reported.
--
Best regards,
Jacek Anaszewski
^ permalink raw reply
* PM regression with LED changes in next-20161109
From: Hans de Goede @ 2016-11-10 13:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5bd5333e-0dbb-6333-0a48-ca4d3a990f9c@samsung.com>
Hi,
On 10-11-16 13:56, Jacek Anaszewski wrote:
> Hi,
>
> On 11/10/2016 09:49 AM, Hans de Goede wrote:
>> Hi,
>>
>> On 09-11-16 21:45, Jacek Anaszewski wrote:
>>> Hi Tony,
>>>
>>> On 11/09/2016 08:23 PM, Tony Lindgren wrote:
>>>> Hi,
>>>>
>>>> Looks like commit 883d32ce3385 ("leds: core: Add support for poll()ing
>>>> the sysfs brightness attr for changes.") breaks runtime PM for me.
>>>>
>>>> On my omap dm3730 based test system, idle power consumption is over 70
>>>> times higher now with this patch! It goes from about 6mW for the core
>>>> system to over 440mW during idle meaning there's some busy timer now
>>>> active.
>>>>
>>>> Reverting this patch fixes the issue. Any ideas?
>>>
>>> Thanks for the report. This is probably caused by sysfs_notify_dirent().
>>> I'm afraid that we can't keep this feature in the current shape.
>>> Hans, I'm dropping the patch. We probably will have to delegate this
>>> call to a workqueue task. Think about use cases when the LED is blinked
>>> with high frequency e.g. from ledtrig-disk.c.
>>
>> sysfs_notify_dirent() already uses a workqueue, here is the actual
>> implementation of it (from fs/kernfs/file.c) :
>>
>> void kernfs_notify(struct kernfs_node *kn)
>> {
>> static DECLARE_WORK(kernfs_notify_work, kernfs_notify_workfn);
>> unsigned long flags;
>>
>> if (WARN_ON(kernfs_type(kn) != KERNFS_FILE))
>> return;
>>
>> spin_lock_irqsave(&kernfs_notify_lock, flags);
>> if (!kn->attr.notify_next) {
>> kernfs_get(kn);
>> kn->attr.notify_next = kernfs_notify_list;
>> kernfs_notify_list = kn;
>> schedule_work(&kernfs_notify_work);
>> }
>> spin_unlock_irqrestore(&kernfs_notify_lock, flags);
>> }
>
> Indeed. As a next step of this investigation Tony could disable
> particular calls made in kernfs_notify_workfn to check what
> exactly causes excessive power consumption.
>
>> So using a workqueue is not going to help. Note that I already
>> feared this, which is why my initial implementation only called
>> sysfs_notify_dirent() for user initiated changes and not for
>> triggers / blinking.
>
> AFAIR there were no calls to led_notify_brightness_change() in
> the initial implementation and it was entirely predestined for
> being called by LED class drivers on brightness changes made
> by firmware.
>
>> I think we may need to reconsider what getting the brightness
>> sysfs atrribute actually returns. Currently when a LED is
>> blinking it will return 0 resp. the actual brightness depending
>> on when in the blink cycle the user reads the brightness
>> sysfs atrribute.
>>
>> So a user can do "echo 128 > brightness && cat brightness" and
>> get out 0, or 128, depending purely on timing.
>>
>> This seems to contradict what Documentation/ABI/testing/sysfs-class-led
>> has to say:
>>
>> What: /sys/class/leds/<led>/brightness
>> Date: March 2006
>> KernelVersion: 2.6.17
>> Contact: Richard Purdie <rpurdie@rpsys.net>
>> Description:
>> Set the brightness of the LED. Most LEDs don't
>> have hardware brightness support, so will just be turned
>> on for
>> non-zero brightness settings. The value is between 0 and
>> /sys/class/leds/<led>/max_brightness.
>>
>> Writing 0 to this file clears active trigger.
>>
>> Writing non-zero to this file while trigger is active
>> changes the
>> top brightness trigger is going to use.
>>
>> Even though it only talks about writing, the logical thing would be for
>> reading to be the exact opposite of writing, so we would get:
>>
>> Reading from this file while a trigger is active returns
>> the
>> top brightness trigger is going to use.
>>
>> The current docs say not about (sw) blinking, but that should be treated
>> just
>> like a trigger IMHO.
>
> You'r right, we should describe the semantics on reading, but it would
> have to be as follows:
>
> Reading from this file returns LED brightness at given moment, i.e.
> even though LED class device brightness setting is greater than 0, the
> momentary brightness can be 0 if the readout occurred during low phase
> of blink cycle.
Why would it need to read like this, because this is the current behavior ?
I doubt anyone is relying on this current behavior because it is really
unpredictable which value one can get.
I believe it would be better to change the read semantics to follow
the write semantics, this would be much more consistent.
Making the read behavior match the write behavior should be easy I would
be happy to write a patch for this.
>> If we can get consensus on what the read behavior for the brightness
>> attribute
>> should be, then I think that a better poll() behavior will automatically
>> follow
>> from that.
>
> It seems that we should get back to your initial approach. i.e. only
> brightness changes caused by hardware should be reported.
Ok, if you really want to keep the read behavior as is, I can provide
an updated patch for this.
Regards,
Hans
^ permalink raw reply
* [PATCH 0/2] mmc: allow mmc_alloc_host() and tmio_mmc_host_alloc()
From: Masahiro Yamada @ 2016-11-10 13:24 UTC (permalink / raw)
To: linux-arm-kernel
sdhci_alloc_host() returns an error pointer when it fails.
but mmc_alloc_host() cannot.
This series allow to propagate a proper error code
when host-allocation fails.
Masahiro Yamada (2):
mmc: allow mmc_alloc_host() to return proper error code
mmc: tmio: allow tmio_mmc_host_alloc() to return proper error code
drivers/mmc/core/host.c | 11 ++++++-----
drivers/mmc/host/android-goldfish.c | 4 ++--
drivers/mmc/host/atmel-mci.c | 4 ++--
drivers/mmc/host/au1xmmc.c | 4 ++--
drivers/mmc/host/bfin_sdh.c | 4 ++--
drivers/mmc/host/cb710-mmc.c | 4 ++--
drivers/mmc/host/davinci_mmc.c | 4 ++--
drivers/mmc/host/dw_mmc.c | 4 ++--
drivers/mmc/host/jz4740_mmc.c | 4 ++--
drivers/mmc/host/mmc_spi.c | 9 ++++++---
drivers/mmc/host/mmci.c | 4 ++--
drivers/mmc/host/moxart-mmc.c | 4 ++--
drivers/mmc/host/mtk-sd.c | 4 ++--
drivers/mmc/host/mvsdio.c | 4 ++--
drivers/mmc/host/mxcmmc.c | 4 ++--
drivers/mmc/host/mxs-mmc.c | 4 ++--
drivers/mmc/host/omap.c | 4 ++--
drivers/mmc/host/omap_hsmmc.c | 4 ++--
drivers/mmc/host/pxamci.c | 4 ++--
drivers/mmc/host/rtsx_pci_sdmmc.c | 4 ++--
drivers/mmc/host/rtsx_usb_sdmmc.c | 4 ++--
drivers/mmc/host/s3cmci.c | 4 ++--
drivers/mmc/host/sdhci.c | 4 ++--
drivers/mmc/host/sdricoh_cs.c | 4 ++--
drivers/mmc/host/sh_mmcif.c | 4 ++--
drivers/mmc/host/sh_mobile_sdhi.c | 4 ++--
drivers/mmc/host/sunxi-mmc.c | 4 ++--
drivers/mmc/host/tifm_sd.c | 4 ++--
drivers/mmc/host/tmio_mmc.c | 4 +++-
drivers/mmc/host/tmio_mmc_pio.c | 4 ++--
drivers/mmc/host/toshsd.c | 4 ++--
drivers/mmc/host/usdhi6rol0.c | 4 ++--
drivers/mmc/host/ushc.c | 4 ++--
drivers/mmc/host/via-sdmmc.c | 4 ++--
drivers/mmc/host/vub300.c | 4 ++--
drivers/mmc/host/wbsd.c | 4 ++--
drivers/mmc/host/wmt-sdmmc.c | 4 ++--
drivers/staging/greybus/sdio.c | 4 ++--
38 files changed, 85 insertions(+), 79 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH 1/2] mmc: allow mmc_alloc_host() to return proper error code
From: Masahiro Yamada @ 2016-11-10 13:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478784263-18777-1-git-send-email-yamada.masahiro@socionext.com>
Currently, mmc_alloc_host() returns NULL on error, so its callers
cannot return anything but -ENOMEM when it fails, assuming the most
failure cases are due to memory shortage, but it is not true.
Allow mmc_alloc_host() to return an error pointer, then propagate
the proper error code to its callers.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
drivers/mmc/core/host.c | 11 ++++++-----
drivers/mmc/host/android-goldfish.c | 4 ++--
drivers/mmc/host/atmel-mci.c | 4 ++--
drivers/mmc/host/au1xmmc.c | 4 ++--
drivers/mmc/host/bfin_sdh.c | 4 ++--
drivers/mmc/host/cb710-mmc.c | 4 ++--
drivers/mmc/host/davinci_mmc.c | 4 ++--
drivers/mmc/host/dw_mmc.c | 4 ++--
drivers/mmc/host/jz4740_mmc.c | 4 ++--
drivers/mmc/host/mmc_spi.c | 9 ++++++---
drivers/mmc/host/mmci.c | 4 ++--
drivers/mmc/host/moxart-mmc.c | 4 ++--
drivers/mmc/host/mtk-sd.c | 4 ++--
drivers/mmc/host/mvsdio.c | 4 ++--
drivers/mmc/host/mxcmmc.c | 4 ++--
drivers/mmc/host/mxs-mmc.c | 4 ++--
drivers/mmc/host/omap.c | 4 ++--
drivers/mmc/host/omap_hsmmc.c | 4 ++--
drivers/mmc/host/pxamci.c | 4 ++--
drivers/mmc/host/rtsx_pci_sdmmc.c | 4 ++--
drivers/mmc/host/rtsx_usb_sdmmc.c | 4 ++--
drivers/mmc/host/s3cmci.c | 4 ++--
drivers/mmc/host/sdhci.c | 4 ++--
drivers/mmc/host/sdricoh_cs.c | 4 ++--
drivers/mmc/host/sh_mmcif.c | 4 ++--
drivers/mmc/host/sunxi-mmc.c | 4 ++--
drivers/mmc/host/tifm_sd.c | 4 ++--
drivers/mmc/host/tmio_mmc_pio.c | 2 +-
drivers/mmc/host/toshsd.c | 4 ++--
drivers/mmc/host/usdhi6rol0.c | 4 ++--
drivers/mmc/host/ushc.c | 4 ++--
drivers/mmc/host/via-sdmmc.c | 4 ++--
drivers/mmc/host/vub300.c | 4 ++--
drivers/mmc/host/wbsd.c | 4 ++--
drivers/mmc/host/wmt-sdmmc.c | 4 ++--
drivers/staging/greybus/sdio.c | 4 ++--
36 files changed, 79 insertions(+), 75 deletions(-)
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 98f25ff..b3e13e0 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -349,7 +349,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
if (!host)
- return NULL;
+ return ERR_PTR(-ENOMEM);
/* scanning will be enabled when we're ready */
host->rescan_disable = 1;
@@ -357,7 +357,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
again:
if (!ida_pre_get(&mmc_host_ida, GFP_KERNEL)) {
kfree(host);
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
spin_lock(&mmc_host_lock);
@@ -368,7 +368,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
goto again;
} else if (err) {
kfree(host);
- return NULL;
+ return ERR_PTR(err);
}
dev_set_name(&host->class_dev, "mmc%d", host->index);
@@ -379,9 +379,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
device_initialize(&host->class_dev);
device_enable_async_suspend(&host->class_dev);
- if (mmc_gpio_alloc(host)) {
+ err = mmc_gpio_alloc(host);
+ if (err < 0) {
put_device(&host->class_dev);
- return NULL;
+ return ERR_PTR(err);
}
spin_lock_init(&host->lock);
diff --git a/drivers/mmc/host/android-goldfish.c b/drivers/mmc/host/android-goldfish.c
index dca5518..7363663 100644
--- a/drivers/mmc/host/android-goldfish.c
+++ b/drivers/mmc/host/android-goldfish.c
@@ -467,8 +467,8 @@ static int goldfish_mmc_probe(struct platform_device *pdev)
return -ENXIO;
mmc = mmc_alloc_host(sizeof(struct goldfish_mmc_host), &pdev->dev);
- if (mmc == NULL) {
- ret = -ENOMEM;
+ if (IS_ERR(mmc)) {
+ ret = PTR_ERR(mmc);
goto err_alloc_host_failed;
}
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 0ad8ef5..d0cb112 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -2296,8 +2296,8 @@ static int atmci_init_slot(struct atmel_mci *host,
struct atmel_mci_slot *slot;
mmc = mmc_alloc_host(sizeof(struct atmel_mci_slot), &host->pdev->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
slot = mmc_priv(mmc);
slot->mmc = mmc;
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index ed77fbfa..d97b409 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -951,9 +951,9 @@ static int au1xmmc_probe(struct platform_device *pdev)
int ret, iflag;
mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev);
- if (!mmc) {
+ if (IS_ERR(mmc)) {
dev_err(&pdev->dev, "no memory for mmc_host\n");
- ret = -ENOMEM;
+ ret = PTR_ERR(mmc);
goto out0;
}
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index 526231e..60c52d1 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -532,8 +532,8 @@ static int sdh_probe(struct platform_device *pdev)
}
mmc = mmc_alloc_host(sizeof(struct sdh_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
+ if (IS_ERR(mmc)) {
+ ret = PTR_ERR(mmc);
goto out;
}
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c
index 1087b4c..79ce871 100644
--- a/drivers/mmc/host/cb710-mmc.c
+++ b/drivers/mmc/host/cb710-mmc.c
@@ -692,8 +692,8 @@ static int cb710_mmc_init(struct platform_device *pdev)
u32 val;
mmc = mmc_alloc_host(sizeof(*reader), cb710_slot_dev(slot));
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
platform_set_drvdata(pdev, mmc);
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 8fa478c..225b9a8 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -1229,8 +1229,8 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
return -EBUSY;
mmc = mmc_alloc_host(sizeof(struct mmc_davinci_host), &pdev->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
host = mmc_priv(mmc);
host->mmc = mmc; /* Important */
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 4fcbc40..4f06528 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -2598,8 +2598,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
u32 freq[2];
mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
slot = mmc_priv(mmc);
slot->id = id;
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index 684087d..351dd68 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -998,9 +998,9 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
pdata = pdev->dev.platform_data;
mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev);
- if (!mmc) {
+ if (IS_ERR(mmc)) {
dev_err(&pdev->dev, "Failed to alloc mmc host structure\n");
- return -ENOMEM;
+ return PTR_ERR(mmc);
}
host = mmc_priv(mmc);
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index e77d79c..165f73e 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1333,15 +1333,18 @@ static int mmc_spi_probe(struct spi_device *spi)
* NOTE if many systems use more than one MMC-over-SPI connector
* it'd save some memory to share this. That's evidently rare.
*/
- status = -ENOMEM;
ones = kmalloc(MMC_SPI_BLOCKSIZE, GFP_KERNEL);
- if (!ones)
+ if (!ones) {
+ status = -ENOMEM;
goto nomem;
+ }
memset(ones, 0xff, MMC_SPI_BLOCKSIZE);
mmc = mmc_alloc_host(sizeof(*host), &spi->dev);
- if (!mmc)
+ if (IS_ERR(mmc)) {
+ status = PTR_ERR(mmc);
goto nomem;
+ }
mmc->ops = &mmc_spi_ops;
mmc->max_blk_size = MMC_SPI_BLOCKSIZE;
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index df990bb..5779b57 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1509,8 +1509,8 @@ static int mmci_probe(struct amba_device *dev,
}
mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
ret = mmci_of_parse(np, mmc);
if (ret)
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
index bbad309..f453e55 100644
--- a/drivers/mmc/host/moxart-mmc.c
+++ b/drivers/mmc/host/moxart-mmc.c
@@ -568,9 +568,9 @@ static int moxart_probe(struct platform_device *pdev)
u32 i;
mmc = mmc_alloc_host(sizeof(struct moxart_host), dev);
- if (!mmc) {
+ if (IS_ERR(mmc)) {
dev_err(dev, "mmc_alloc_host failed\n");
- ret = -ENOMEM;
+ ret = PTR_ERR(mmc);
goto out;
}
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 84e9afc..ef28f64 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1494,8 +1494,8 @@ static int msdc_drv_probe(struct platform_device *pdev)
}
/* Allocate MMC host for this device */
mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
host = mmc_priv(mmc);
ret = mmc_of_parse(mmc);
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index 42296e5..5594f58 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -711,8 +711,8 @@ static int mvsd_probe(struct platform_device *pdev)
return -ENXIO;
mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
+ if (IS_ERR(mmc)) {
+ ret = PTR_ERR(mmc);
goto out;
}
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index fb3ca82..5bdc644 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -1018,8 +1018,8 @@ static int mxcmci_probe(struct platform_device *pdev)
return -EINVAL;
mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
host = mmc_priv(mmc);
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index d839147..7f72bb4 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -586,8 +586,8 @@ static int mxs_mmc_probe(struct platform_device *pdev)
return irq_err;
mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
host = mmc_priv(mmc);
ssp = &host->ssp;
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index be3c49f..b1ec63f 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1227,8 +1227,8 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id)
int r;
mmc = mmc_alloc_host(sizeof(struct mmc_omap_slot), host->dev);
- if (mmc == NULL)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
slot = mmc_priv(mmc);
slot->host = host;
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5f2f24a..6154b55 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2024,8 +2024,8 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
return PTR_ERR(base);
mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
+ if (IS_ERR(mmc)) {
+ ret = PTR_ERR(mmc);
goto err;
}
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index c763b40..9e9b02f 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -652,8 +652,8 @@ static int pxamci_probe(struct platform_device *pdev)
return irq;
mmc = mmc_alloc_host(sizeof(struct pxamci_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
+ if (IS_ERR(mmc)) {
+ ret = PTR_ERR(mmc);
goto out;
}
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 3ccaa14..551536e 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1399,8 +1399,8 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
dev_dbg(&(pdev->dev), ": Realtek PCI-E SDMMC controller found\n");
mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
host = mmc_priv(mmc);
host->pcr = pcr;
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
index 6e9c0f8..443679f 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -1363,8 +1363,8 @@ static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
dev_dbg(&(pdev->dev), ": Realtek USB SD/MMC controller found\n");
mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
host = mmc_priv(mmc);
host->ucr = ucr;
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index c531dee..aacc5cf 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1556,8 +1556,8 @@ static int s3cmci_probe(struct platform_device *pdev)
is2440 = platform_get_device_id(pdev)->driver_data;
mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
+ if (IS_ERR(mmc)) {
+ ret = PTR_ERR(mmc);
goto probe_out;
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 71654b9..eb8199e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2946,8 +2946,8 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
WARN_ON(dev == NULL);
mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);
- if (!mmc)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(mmc))
+ return ERR_CAST(mmc);
host = mmc_priv(mmc);
host->mmc = mmc;
diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c
index 5ff26ab..6d2f671 100644
--- a/drivers/mmc/host/sdricoh_cs.c
+++ b/drivers/mmc/host/sdricoh_cs.c
@@ -424,9 +424,9 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev,
/* allocate privdata */
mmc = pcmcia_dev->priv =
mmc_alloc_host(sizeof(struct sdricoh_host), &pcmcia_dev->dev);
- if (!mmc) {
+ if (IS_ERR(mmc)) {
dev_err(dev, "mmc_alloc_host failed\n");
- result = -ENOMEM;
+ result = PTR_ERR(mmc);
goto unmap_io;
}
host = mmc_priv(mmc);
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 9007784..c2affc6 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1432,8 +1432,8 @@ static int sh_mmcif_probe(struct platform_device *pdev)
return PTR_ERR(reg);
mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
ret = mmc_of_parse(mmc);
if (ret < 0)
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index c0a5c67..a3cb388 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -1212,9 +1212,9 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
int ret;
mmc = mmc_alloc_host(sizeof(struct sunxi_mmc_host), &pdev->dev);
- if (!mmc) {
+ if (IS_ERR(mmc)) {
dev_err(&pdev->dev, "mmc alloc host failed\n");
- return -ENOMEM;
+ return PTR_ERR(mmc);
}
host = mmc_priv(mmc);
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 93c4b40..b088cb8 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -958,8 +958,8 @@ static int tifm_sd_probe(struct tifm_dev *sock)
}
mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
host = mmc_priv(mmc);
tifm_set_drvdata(sock, mmc);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 7005676..18106fc 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -1013,7 +1013,7 @@ struct tmio_mmc_host*
struct mmc_host *mmc;
mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &pdev->dev);
- if (!mmc)
+ if (IS_ERR(mmc))
return NULL;
host = mmc_priv(mmc);
diff --git a/drivers/mmc/host/toshsd.c b/drivers/mmc/host/toshsd.c
index 553ef41..7b086ed 100644
--- a/drivers/mmc/host/toshsd.c
+++ b/drivers/mmc/host/toshsd.c
@@ -617,8 +617,8 @@ static int toshsd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return ret;
mmc = mmc_alloc_host(sizeof(struct toshsd_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
+ if (IS_ERR(mmc)) {
+ ret = PTR_ERR(mmc);
goto err;
}
diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c
index 1bd5f1a..e9d0126 100644
--- a/drivers/mmc/host/usdhi6rol0.c
+++ b/drivers/mmc/host/usdhi6rol0.c
@@ -1753,8 +1753,8 @@ static int usdhi6_probe(struct platform_device *pdev)
return -ENODEV;
mmc = mmc_alloc_host(sizeof(struct usdhi6_host), dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
ret = mmc_regulator_get_supply(mmc);
if (ret == -EPROBE_DEFER)
diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c
index d2c386f..6937021 100644
--- a/drivers/mmc/host/ushc.c
+++ b/drivers/mmc/host/ushc.c
@@ -427,8 +427,8 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
int ret;
mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
- if (mmc == NULL)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
ushc = mmc_priv(mmc);
usb_set_intfdata(intf, ushc);
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index 63fac78..010bfdb 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1108,8 +1108,8 @@ static int via_sd_probe(struct pci_dev *pcidev,
pci_write_config_byte(pcidev, VIA_CRDR_PCI_DBG_MODE, 0);
mmc = mmc_alloc_host(sizeof(struct via_crdr_mmc_host), &pcidev->dev);
- if (!mmc) {
- ret = -ENOMEM;
+ if (IS_ERR(mmc)) {
+ ret = PTR_ERR(mmc);
goto release;
}
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index bb3e0d1..d052c23 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -2125,8 +2125,8 @@ static int vub300_probe(struct usb_interface *interface,
}
/* this also allocates memory for our VUB300 mmc host device */
mmc = mmc_alloc_host(sizeof(struct vub300_mmc_host), &udev->dev);
- if (!mmc) {
- retval = -ENOMEM;
+ if (IS_ERR(mmc)) {
+ retval = PTR_ERR(mmc);
dev_err(&udev->dev, "not enough memory for the mmc_host\n");
goto error4;
}
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index c3fd16d..40f8fd6 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -1204,8 +1204,8 @@ static int wbsd_alloc_mmc(struct device *dev)
* Allocate MMC structure.
*/
mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
host = mmc_priv(mmc);
host->mmc = mmc;
diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c
index 5af0055..f37f9a4cd 100644
--- a/drivers/mmc/host/wmt-sdmmc.c
+++ b/drivers/mmc/host/wmt-sdmmc.c
@@ -782,9 +782,9 @@ static int wmt_mci_probe(struct platform_device *pdev)
}
mmc = mmc_alloc_host(sizeof(struct wmt_mci_priv), &pdev->dev);
- if (!mmc) {
+ if (IS_ERR(mmc)) {
dev_err(&pdev->dev, "Failed to allocate mmc_host\n");
- ret = -ENOMEM;
+ ret = PTR_ERR(mmc);
goto fail1;
}
diff --git a/drivers/staging/greybus/sdio.c b/drivers/staging/greybus/sdio.c
index 5649ef1..01c443d 100644
--- a/drivers/staging/greybus/sdio.c
+++ b/drivers/staging/greybus/sdio.c
@@ -768,8 +768,8 @@ static int gb_sdio_probe(struct gbphy_device *gbphy_dev,
int ret = 0;
mmc = mmc_alloc_host(sizeof(*host), &gbphy_dev->dev);
- if (!mmc)
- return -ENOMEM;
+ if (IS_ERR(mmc))
+ return PTR_ERR(mmc);
connection = gb_connection_create(gbphy_dev->bundle,
le16_to_cpu(gbphy_dev->cport_desc->id),
--
1.9.1
^ permalink raw reply related
* [PATCH 0/2] mmc: allow mmc_alloc_host() and tmio_mmc_host_alloc()
From: Greg Kroah-Hartman @ 2016-11-10 13:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478784263-18777-1-git-send-email-yamada.masahiro@socionext.com>
On Thu, Nov 10, 2016 at 10:24:21PM +0900, Masahiro Yamada wrote:
>
> sdhci_alloc_host() returns an error pointer when it fails.
> but mmc_alloc_host() cannot.
>
> This series allow to propagate a proper error code
> when host-allocation fails.
Why? What can we really do about the error except give up? Why does
having a explicit error value make any difference to the caller, they
can't do anything different, right?
I suggest just leaving it as-is, it's simple, and you don't have to mess
with PTR_ERR() anywhere.
thanks,
greg k-h
^ permalink raw reply
* [PATCH] arm64: dts: Add ARM PMU node for exynos7
From: Robin Murphy @ 2016-11-10 13:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478748643-3081-1-git-send-email-alim.akhtar@samsung.com>
Hi Alim,
On 10/11/16 03:30, Alim Akhtar wrote:
> This patch adds ARM Performance Monitor Unit dt node for exynos7.
> PMU provides various statistics on the operation of the CPU and
> memory system at runtime, which are very useful when debugging or
> profiling code. This enables the same.
>
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> ---
> arch/arm64/boot/dts/exynos/exynos7.dtsi | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> index e0d0d01..53ce4be 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> @@ -472,6 +472,14 @@
> status = "disabled";
> };
>
> + arm-pmu {
> + compatible = "arm,cortex-a57-pmu", "arm,armv8-pmuv3";
> + interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
Per Documentation/devicetree/bindings/arm/pmu.txt there should also be
an "interrupt-affinity" property describing which SPI belongs to which core.
Robin.
> + };
> +
> timer {
> compatible = "arm,armv8-timer";
> interrupts = <GIC_PPI 13
>
^ permalink raw reply
* PM regression with LED changes in next-20161109
From: Jacek Anaszewski @ 2016-11-10 13:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d2941e6f-d277-a68d-2837-00b628dd3be7@redhat.com>
Hi,
On 11/10/2016 02:04 PM, Hans de Goede wrote:
> Hi,
>
> On 10-11-16 13:56, Jacek Anaszewski wrote:
>> Hi,
>>
>> On 11/10/2016 09:49 AM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 09-11-16 21:45, Jacek Anaszewski wrote:
>>>> Hi Tony,
>>>>
>>>> On 11/09/2016 08:23 PM, Tony Lindgren wrote:
>>>>> Hi,
>>>>>
>>>>> Looks like commit 883d32ce3385 ("leds: core: Add support for poll()ing
>>>>> the sysfs brightness attr for changes.") breaks runtime PM for me.
>>>>>
>>>>> On my omap dm3730 based test system, idle power consumption is over 70
>>>>> times higher now with this patch! It goes from about 6mW for the core
>>>>> system to over 440mW during idle meaning there's some busy timer now
>>>>> active.
>>>>>
>>>>> Reverting this patch fixes the issue. Any ideas?
>>>>
>>>> Thanks for the report. This is probably caused by
>>>> sysfs_notify_dirent().
>>>> I'm afraid that we can't keep this feature in the current shape.
>>>> Hans, I'm dropping the patch. We probably will have to delegate this
>>>> call to a workqueue task. Think about use cases when the LED is blinked
>>>> with high frequency e.g. from ledtrig-disk.c.
>>>
>>> sysfs_notify_dirent() already uses a workqueue, here is the actual
>>> implementation of it (from fs/kernfs/file.c) :
>>>
>>> void kernfs_notify(struct kernfs_node *kn)
>>> {
>>> static DECLARE_WORK(kernfs_notify_work, kernfs_notify_workfn);
>>> unsigned long flags;
>>>
>>> if (WARN_ON(kernfs_type(kn) != KERNFS_FILE))
>>> return;
>>>
>>> spin_lock_irqsave(&kernfs_notify_lock, flags);
>>> if (!kn->attr.notify_next) {
>>> kernfs_get(kn);
>>> kn->attr.notify_next = kernfs_notify_list;
>>> kernfs_notify_list = kn;
>>> schedule_work(&kernfs_notify_work);
>>> }
>>> spin_unlock_irqrestore(&kernfs_notify_lock, flags);
>>> }
>>
>> Indeed. As a next step of this investigation Tony could disable
>> particular calls made in kernfs_notify_workfn to check what
>> exactly causes excessive power consumption.
>>
>>> So using a workqueue is not going to help. Note that I already
>>> feared this, which is why my initial implementation only called
>>> sysfs_notify_dirent() for user initiated changes and not for
>>> triggers / blinking.
>>
>> AFAIR there were no calls to led_notify_brightness_change() in
>> the initial implementation and it was entirely predestined for
>> being called by LED class drivers on brightness changes made
>> by firmware.
>>
>>> I think we may need to reconsider what getting the brightness
>>> sysfs atrribute actually returns. Currently when a LED is
>>> blinking it will return 0 resp. the actual brightness depending
>>> on when in the blink cycle the user reads the brightness
>>> sysfs atrribute.
>>>
>>> So a user can do "echo 128 > brightness && cat brightness" and
>>> get out 0, or 128, depending purely on timing.
>>>
>>> This seems to contradict what Documentation/ABI/testing/sysfs-class-led
>>> has to say:
>>>
>>> What: /sys/class/leds/<led>/brightness
>>> Date: March 2006
>>> KernelVersion: 2.6.17
>>> Contact: Richard Purdie <rpurdie@rpsys.net>
>>> Description:
>>> Set the brightness of the LED. Most LEDs don't
>>> have hardware brightness support, so will just be turned
>>> on for
>>> non-zero brightness settings. The value is between 0 and
>>> /sys/class/leds/<led>/max_brightness.
>>>
>>> Writing 0 to this file clears active trigger.
>>>
>>> Writing non-zero to this file while trigger is active
>>> changes the
>>> top brightness trigger is going to use.
>>>
>>> Even though it only talks about writing, the logical thing would be for
>>> reading to be the exact opposite of writing, so we would get:
>>>
>>> Reading from this file while a trigger is active returns
>>> the
>>> top brightness trigger is going to use.
>>>
>>> The current docs say not about (sw) blinking, but that should be treated
>>> just
>>> like a trigger IMHO.
>>
>> You'r right, we should describe the semantics on reading, but it would
>> have to be as follows:
>>
>> Reading from this file returns LED brightness at given moment, i.e.
>> even though LED class device brightness setting is greater than 0, the
>> momentary brightness can be 0 if the readout occurred during low phase
>> of blink cycle.
>
> Why would it need to read like this, because this is the current behavior ?
We have led_update_brightness() which was introduced long time ago and
is used in brightness_show(). Note that if LED controller changed
actual LED brightness e.g. due to battery voltage dropping below
certain threshold, we wouldn't be able to find it out otherwise
(except if we added separate sysfs file for that).
>
> I doubt anyone is relying on this current behavior because it is really
> unpredictable which value one can get.
>
> I believe it would be better to change the read semantics to follow
> the write semantics, this would be much more consistent.
>
> Making the read behavior match the write behavior should be easy I would
> be happy to write a patch for this.
Let's better agree on the description of the current semantics.
It has been around for a long time.
>>> If we can get consensus on what the read behavior for the brightness
>>> attribute
>>> should be, then I think that a better poll() behavior will automatically
>>> follow
>>> from that.
>>
>> It seems that we should get back to your initial approach. i.e. only
>> brightness changes caused by hardware should be reported.
>
> Ok, if you really want to keep the read behavior as is, I can provide
> an updated patch for this.
Yes please.
--
Best regards,
Jacek Anaszewski
^ permalink raw reply
* [PATCH v2 1/2] devicetree: Add vendor prefix for CZ.NIC
From: Uwe Kleine-König @ 2016-11-10 13:57 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Uwe Kleine-K?nig <uwe@kleine-koenig.org>
---
Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index f0a48ea78659..ae9fce9fed03 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -67,6 +67,7 @@ creative Creative Technology Ltd
crystalfontz Crystalfontz America, Inc.
cubietech Cubietech, Ltd.
cypress Cypress Semiconductor Corporation
+cznic CZ.NIC, z.s.p.o.
dallas Maxim Integrated Products (formerly Dallas Semiconductor)
davicom DAVICOM Semiconductor, Inc.
delta Delta Electronics, Inc.
--
2.10.2
^ permalink raw reply related
* [PATCH v2 2/2] ARM: dts: add support for Turris Omnia
From: Uwe Kleine-König @ 2016-11-10 13:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161110135721.13098-1-uwe@kleine-koenig.org>
This machine is an open hardware router by cz.nic driven by a
Marvell Armada 385.
Signed-off-by: Uwe Kleine-K?nig <uwe@kleine-koenig.org>
---
Compared to the (implict) v1, the following was changed:
- disable rtc
- change compatible to cznic,turris-omnia
The following components are working:
- WAN port
- eMMC
- UART0
- USB
- mSATA
Wireless fails to probe, didn't debug this up to now.
I already see the DSA devices (with an additional change not included here),
but sending and receiving doesn't work yet.
SFP is missing as I cannot test it. UART1 is untested, but I'd be
surprised if it didn't work.
IMHO it makes sense to add the current state and fix the remaining stuff
incrementally.
Best regards
Uwe
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/armada-385-turris-omnia.dts | 257 ++++++++++++++++++++++++++
2 files changed, 258 insertions(+)
create mode 100644 arch/arm/boot/dts/armada-385-turris-omnia.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index befcd2619902..f1d3b9ff257e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -920,6 +920,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
armada-385-db-ap.dtb \
armada-385-linksys-caiman.dtb \
armada-385-linksys-cobra.dtb \
+ armada-385-turris-omnia.dtb \
armada-388-clearfog.dtb \
armada-388-db.dtb \
armada-388-gp.dtb \
diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
new file mode 100644
index 000000000000..28e45d816120
--- /dev/null
+++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
@@ -0,0 +1,257 @@
+/*
+ * Device Tree file for the Turris Omnia
+ * Schematic available at https://www.turris.cz/doc/_media/rtrom01-schema.pdf
+ *
+ * Copyright (C) 2016 Uwe Kleine-K?nig <uwe@kleine-koenig.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "armada-385.dtsi"
+
+/ {
+ model = "Turris Omnia";
+ compatible = "cznic,turris-omnia", "marvell,armada385", "marvell,armada380";
+
+ chosen {
+ stdout-path = &uart0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1024 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+
+ /* USB part of the eSATA/USB 2.0 port */
+ usb at 58000 {
+ status = "okay";
+ };
+
+ rtc at a3800 {
+ /*
+ * There are several errata for this device
+ * still unimplemented. Without some love it only reports
+ * 2016-12-19 22:00:24. So disable for now.
+ */
+ status = "disabled";
+ };
+
+ sata at a8000 {
+ status = "okay";
+ };
+
+ sdhci at d8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhci_pins>;
+ status = "okay";
+
+ bus-width = <8>;
+ no-1-8-v;
+ non-removable;
+ };
+
+ usb3 at f0000 {
+ status = "okay";
+ };
+
+ usb3 at f8000 {
+ status = "okay";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ pcie at 1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ pcie at 2,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+
+ pcie at 3,0 {
+ /* Port 3, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+};
+
+ð0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ status = "okay";
+ phy-mode = "rgmii-id";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+ð1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ status = "okay";
+ phy-mode = "rgmii-id";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+/* WAN port */
+ð2 {
+ status = "okay";
+ phy-mode = "sgmii";
+ phy = <&phy1>;
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+
+ i2cmux at 70 {
+ compatible = "nxp,pca9547";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+ status = "okay";
+
+ i2c at 0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "okay";
+
+ /* STM32F0 at address 0x2a */
+ /* leds device at address 0x2b */
+
+ eeprom at 54 {
+ /* holds configuration about RAM, evaluated by bootloader */
+ compatible = "at,24c64";
+ reg = <0x54>;
+ };
+ };
+
+ i2c at 5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ /* ATSHA204A at address 0x64 */
+ };
+
+ i2c at 6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+
+ /* exposed on pin header */
+ };
+ };
+};
+
+&mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+ status = "okay";
+
+ phy1: phy at 1 {
+ status = "okay";
+ compatible = "ethernet-phy-id0141.0DD1", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+
+ /* There is a Switch (MV88E7176) at address 0x10 */
+};
+
+&pinctrl {
+ spi0cs1_pins: spi0-pins-0cs1 {
+ marvell,pins = "mpp26";
+ marvell,function = "spi0";
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins &spi0cs1_pins>;
+ status = "okay";
+
+ spi-nor at 0 {
+ compatible = "spansion,s25fl164k", "jedec,spi-nor";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+
+ partition at 0 {
+ reg = <0x0 0x00100000>;
+ label = "U-Boot";
+ };
+
+ partition at 1 {
+ reg = <0x00100000 0x00700000>;
+ label = "Rescue system";
+ };
+ };
+
+ /* @1 is on pin header */
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+};
--
2.10.2
^ permalink raw reply related
* [PATCHv2] PCI: QDF2432 32 bit config space accessors
From: Lorenzo Pieralisi @ 2016-11-10 13:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu9_sdcoN7rjQp-R=2vKY3rECt0BC3eWGpse32o2Q4LHXg@mail.gmail.com>
On Thu, Nov 10, 2016 at 06:25:16PM +0800, Ard Biesheuvel wrote:
> On 10 November 2016 at 06:49, Bjorn Helgaas <helgaas@kernel.org> wrote:
> > On Wed, Nov 09, 2016 at 08:29:23PM +0000, Ard Biesheuvel wrote:
> >> Hi Bjorn,
> >>
> >> On 9 November 2016 at 20:06, Bjorn Helgaas <helgaas@kernel.org> wrote:
> >> > On Wed, Nov 09, 2016 at 02:25:56PM -0500, Christopher Covington wrote:
> >> >> Hi Bjorn,
> >> >>
> >> [...]
> >> >>
> >> >> We're working to add the PNP0C02 resource to future firmware, but it's
> >> >> not in the current firmware. Are dmesg and /proc/iomem from the
> >> >> current firmware interesting or should we wait for the update to file?
> >> >
> >> > Note that the ECAM space is not the only thing that should be
> >> > described via these PNP0C02 devices. *All* non-enumerable resources
> >> > should be described by the _CRS method of some ACPI device. Here's a
> >> > sample from my laptop:
> >> >
> >> > PCI: MMCONFIG for domain 0000 [bus 00-3f] at [mem 0xf8000000-0xfbffffff] (base 0xf8000000)
> >> > system 00:01: [io 0x1800-0x189f] could not be reserved
> >> > system 00:01: [io 0x0800-0x087f] has been reserved
> >> > system 00:01: [io 0x0880-0x08ff] has been reserved
> >> > system 00:01: [io 0x0900-0x097f] has been reserved
> >> > system 00:01: [io 0x0980-0x09ff] has been reserved
> >> > system 00:01: [io 0x0a00-0x0a7f] has been reserved
> >> > system 00:01: [io 0x0a80-0x0aff] has been reserved
> >> > system 00:01: [io 0x0b00-0x0b7f] has been reserved
> >> > system 00:01: [io 0x0b80-0x0bff] has been reserved
> >> > system 00:01: [io 0x15e0-0x15ef] has been reserved
> >> > system 00:01: [io 0x1600-0x167f] has been reserved
> >> > system 00:01: [io 0x1640-0x165f] has been reserved
> >> > system 00:01: [mem 0xf8000000-0xfbffffff] could not be reserved
> >> > system 00:01: [mem 0xfed10000-0xfed13fff] has been reserved
> >> > system 00:01: [mem 0xfed18000-0xfed18fff] has been reserved
> >> > system 00:01: [mem 0xfed19000-0xfed19fff] has been reserved
> >> > system 00:01: [mem 0xfeb00000-0xfebfffff] has been reserved
> >> > system 00:01: [mem 0xfed20000-0xfed3ffff] has been reserved
> >> > system 00:01: [mem 0xfed90000-0xfed93fff] has been reserved
> >> > system 00:01: [mem 0xf7fe0000-0xf7ffffff] has been reserved
> >> > system 00:01: Plug and Play ACPI device, IDs PNP0c02 (active)
> >> >
> >> > Do you have firmware in the field that may not get updated? If so,
> >> > I'd like to see the whole solution for that firmware, including the
> >> > MCFG quirk (which tells the PCI core where the ECAM region is) and
> >> > whatever PNP0C02 quirk you figure out to actually reserve the region.
> >> >
> >> > I proposed a PNP0C02 quirk to Duc along these lines of the below. I
> >> > don't actually know if it's feasible, but it didn't look as bad as I
> >> > expected, so I'd kind of like somebody to try it out. I think you
> >> > would have to call this via a DMI hook (do you have DMI on arm64?),
> >> > maybe from pnp_init() or similar.
> >>
> >> We do have SMBIOS/DMI on arm64, but we have been successful so far not
> >> to rely on it for quirks, and we'd very much like to keep it that way.
> >>
> >> Since this ACPI _CRS method has nothing to do with SMBIOS/DMI, surely
> >> there is a better way to wire up the reservation code to the
> >> information exposed by ACPI?
> >
> > I'm open to other ways, feel free to propose one :)
> >
> > If you do a quirk, you need some way to identify the machine/firmware
> > combination, because you don't want to apply the quirk on every
> > machine. You're trying to work around a firmware issue, so you
> > probably want something tied to the firmware version. On x86, that's
> > typically done with DMI.
> >
>
> I think I misunderstood the purpose of the example: that should only
> be necessary if the _CRS methods are missing from the firmware, right?
> If we update the firmware to cover all non-enumerable resources by
> such a method, we shouldn't need any such quirks at all IIUC
Yes that's correct you need a quirk to fabricate a PNP0c02 motherboard
resource if it is not present in FW.
Lorenzo
^ permalink raw reply
* [PATCH v3 1/2] ARM: EXYNOS: Remove static mapping of SCU SFR
From: Arnd Bergmann @ 2016-11-10 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <a43af947-6002-bc65-f73b-02d57a78d6cb@samsung.com>
On Thursday, November 10, 2016 6:07:54 PM CET pankaj.dubey wrote:
> On Thursday 10 November 2016 05:24 PM, Arnd Bergmann wrote:
> > On Wednesday, November 9, 2016 5:45:54 PM CET Pankaj Dubey wrote:
>
> Sorry, I missed this part and did not check with CONFIG_SMP disabled.
>
> > arch/arm/mach-exynos/pm.o: In function `exynos_enter_aftr':
> > pm.c:(.text.exynos_enter_aftr+0xec): undefined reference to `exynos_scu_enable'
> > arch/arm/mach-exynos/suspend.o: In function `exynos_pm_resume':
> > suspend.c:(.text.exynos_pm_resume+0x78): undefined reference to `exynos_scu_enable'
> >
> > Please fix. I have applied a patch locally (see below), but don't know
> > if that is the best solution. As we seem to duplicate that code across
> > several platforms, I wonder why we don't just put it into the core scu
> > implementation.
> >
>
> When I checked scu_enable declaration it is defined in
> arch/arm/include/asm/smp_scu.h as:
>
> #if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU)
> void scu_enable(void __iomem *scu_base);
> #else
> static inline void scu_enable(void __iomem *scu_base) {}
> #endif
>
> So if CONFIG_SMP is disable then there is no sense of exynos_scu_enable
> as well. So wow about using below patch?
>
> --------------------------------------------------------
>
> Subject: [PATCH] ARM: exynos: fix build fail due to exynos_scu_enable
>
> Build failed if we disable CONFIG_SMP as shown below:
>
> arch/arm/mach-exynos/pm.o: In function `exynos_enter_aftr':
> pm.c:(.text.exynos_enter_aftr+0xec): undefined reference to
> `exynos_scu_enable'
> arch/arm/mach-exynos/suspend.o: In function `exynos_pm_resume':
> suspend.c:(.text.exynos_pm_resume+0x78): undefined reference to
> `exynos_scu_enable'
>
> Since scu_enable is defined only in case CONFIG_SMP and CONFIG_HAVE_ARM_SCU
> lets move exynos_scu_enable also under these two macros.
>
> Reported-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
> arch/arm/mach-exynos/common.h | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
> index fb12d11..03fdb79 100644
> --- a/arch/arm/mach-exynos/common.h
> +++ b/arch/arm/mach-exynos/common.h
> @@ -156,7 +156,12 @@ extern void exynos_cpu_restore_register(void);
> extern void exynos_pm_central_suspend(void);
> extern int exynos_pm_central_resume(void);
> extern void exynos_enter_aftr(void);
> +#if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU)
> extern int exynos_scu_enable(void);
> +#else
> +static inline void exynos_scu_enable(void) {}
> +#endif
Yes, I think that would work, but you can drop the CONFIG_HAVE_ARM_SCU
check because of
menuconfig ARCH_EXYNOS
....
select HAVE_ARM_SCU if SMP
...
> Of-course your idea to move it in core SCU file is also good that we
> lots of duplication in different architecture can be avoided.
>
> In that case I can think of following patch:
>
> [PATCH] ARM: scu: use SCU device node to enable SCU
>
> Many platforms are duplicating code for enabling SCU, lets add
> common code to enable SCU using SCU device node so the duplication in
> each platform can be avoided.
>
> Suggested-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
That looks good too. I also checked the other callers of
scu_enable(), and we have only three classes here:
a) of_iomap: berlin, exynos, mvebu, realview, rockchip, socfpga, sti, ux500, vexpress
b) ioremap(scu_a9_get_base()): bcm63xx, bcm, hisi, zx
c) iotable_init, scu_a9_get_base(): imx, omap4, tegra, zynq
d) ioremap(constant): shmobile, spear13xx
I checked that none of the ones in category c) actually use the address early,
so we can easily change four into b).
I also think that we need to keep both a) and b) because the output of
scu_a9_get_base() might be incorrect in some chips, and not all dtb
files have an SCU in them.
If we make the common SCU setup check DT first and then fall back to
scu_a9_get_base(), that means we have covered almost all cases, unless
I'm missing a problem with that approach. It would be nice to
check spear13xx and the Cortex-A9 based mach-shmobile variants
(emev2, r8a7779, and sh73a0) to see if they could also share
that implementation.
Arnd
^ permalink raw reply
* [PATCH] iommu/dma-iommu: properly respect configured address space size
From: Robin Murphy @ 2016-11-10 14:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6f2f3d37-dc6c-abdb-9692-8dcc9cad36f3@samsung.com>
On 08/11/16 14:53, Marek Szyprowski wrote:
> Hi Robin,
>
>
> On 2016-11-08 15:44, Robin Murphy wrote:
>> On 08/11/16 13:41, Marek Szyprowski wrote:
>>> On 2016-11-08 12:37, Robin Murphy wrote:
>>>> On 07/11/16 13:06, Marek Szyprowski wrote:
>>>>> When one called iommu_dma_init_domain() with size smaller than
>>>>> device's
>>>>> DMA mask, the alloc_iova() will not respect it and always assume that
>>>>> all
>>>>> IOVA addresses will be allocated from the the (base ...
>>>>> dev->dma_mask) range.
>>>> Is that actually a problem for anything?
>>> Yes, I found this issue while working on next version of ARM & ARM64
>>> DMA-mapping/IOMMU integration patchset and adapting Exynos drivers
>>> for the
>>> new IOMMU/DMA-mapping glue.
>>>
>>> Some Exynos devices (codec and camera isp) operate only on the
>>> limited (and
>>> really small: 256M for example) DMA window. They use non-standard way of
>>> addressing memory: an offset from the firmware base. However they still
>>> have
>>> 32bit DMA mask, as the firmware can be located basically everywhere
>>> in the
>>> real DMA address space, but then they can access only next 256M from
>>> that
>>> firmware base.
>> OK, that's good to know, thanks. However, I think in this case it sounds
>> like it's really the DMA mask that's the underlying problem - if those
>> blocks themselves can only drive 28 address bits, then the struct
>> devices representing them should have 28-bit DMA masks, and the
>> "firmware base" of whoever's driving the upper bits modelled with a
>> dma_pfn_offset. Even if they do have full 32-bit interfaces themselves,
>> but are constrained to segment-offset addressing internally, I still
>> think it would be tidier to represent things that way.
>>
>> At some point in dma-iommu development I did have support for DMA
>> offsets upstream of the IOMMU, and am happy to reinstate it if there's a
>> real use case (assuming you can't simply always set the firmware base to
>> 0 when using the IOMMU).
>
> That would indeed look a bit simpler, but I've already tried such approach
> and the firmware crashes when its base in real DMA address space is set to
> zero.
Ah, sadly I'm not too surprised... ;)
Having pondered it a little more, what if the firmware base is instead
set equal to the max offset, then you can have a power-of-two DMA mask
at twice that size (e.g. 512M) such that the top-down IOVA allocations
start in the right place. That would appear to achieve pretty much the
same result as this patch, but more robustly.
Incidentally, how do the init size and DMA mask end up different in the
first place? Is this another case of the "dma-ranges" info from
of_dma_configure() getting clobbered by a driver calling dma_set_mask()
later?
Robin.
>>>>> This patch fixes this issue by taking the configured address space
>>>>> size
>>>>> parameter into account (if it is smaller than the device's dma_mask).
>>>> TBH I've been pondering ripping the size stuff out of dma-iommu, as it
>>>> all stems from me originally failing to understand what
>>>> dma_32bit_pfn is
>>>> actually for. The truth is that iova_domains just don't have a size or
>>>> upper limit; however if devices with both large and small DMA masks
>>>> share a domain, then the top-down nature of the allocator means that
>>>> allocating for the less-capable devices would involve walking through
>>>> every out-of-range entry in the tree every time. Having cached32_node
>>>> based on dma_32bit_pfn just provides an optimised starting point for
>>>> searching within the smaller mask.
>>> Right, this dma_32bit_pfn was really misleading at the first glance,
>>> but then I found that this was something like end_pfn in case of
>>> dma-iommu
>>> code.
>> Yes, that was my incorrect assumption - at the time I interpreted it as
>> a de-facto upper limit which was still possible to allocate above in
>> special circumstances, which turns out to be almost entirely backwards.
>> I'd rather not bake that into the dma-iommu code any further if we can
>> avoid it (I'll try throwing an RFC together to clear up what's there
>> already).
>
> Okay.
>
> Best regards
^ permalink raw reply
* [PATCH v5 6/8] Documentation: bindings: add compatible specific to legacy SCPI protocol
From: Rob Herring @ 2016-11-10 14:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <14e563ae-36c5-4bf9-0d51-3b07830de3db@arm.com>
On Thu, Nov 10, 2016 at 4:26 AM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 10/11/16 01:22, Rob Herring wrote:
>>
>> On Wed, Nov 02, 2016 at 10:52:09PM -0600, Sudeep Holla wrote:
>>>
>>> This patch adds specific compatible to support legacy SCPI protocol.
>>>
>>> Cc: Rob Herring <robh+dt@kernel.org>
>>> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
>>> ---
>>> Documentation/devicetree/bindings/arm/arm,scpi.txt | 4 +++-
>>> 1 file changed, 3 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt
>>> b/Documentation/devicetree/bindings/arm/arm,scpi.txt
>>> index d1882c4540d0..ebd03fc93135 100644
>>> --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt
>>> +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt
>>> @@ -7,7 +7,9 @@ by Linux to initiate various system control and power
>>> operations.
>>>
>>> Required properties:
>>>
>>> -- compatible : should be "arm,scpi"
>>> +- compatible : should be
>>> + * "arm,scpi" : For implementations complying to SCPI v1.0 or
>>> above
>>> + * "arm,legacy-scpi" : For implementations complying pre SCPI v1.0
>>
>>
>> I'd prefer that we explicitly enumerate the old versions. Are there
>> many?
>>
>
> I understand your concern, but this legacy SCPI protocol was not
> officially released. It was just WIP which vendors picked up from very
> early releases. Since they are not numbered, it's hard to have specific
> compatibles with different versions until v1.0. That's one of the reason
> to retain platform specific compatible so that we can add any quirks
> based on them if needed.
>
> I will probably add these information in the commit log so that it's
> clear why we can't do version based compatible.
This is exactly my point. By enumerate, I meant having platform
specific compatibles. Having "arm,legacy-scpi" is pointless because
who knows what version they followed and they may all be different.
Rob
^ permalink raw reply
* [PATCH v2 1/2] devicetree: Add vendor prefix for CZ.NIC
From: Andrew Lunn @ 2016-11-10 14:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161110135721.13098-1-uwe@kleine-koenig.org>
On Thu, Nov 10, 2016 at 02:57:20PM +0100, Uwe Kleine-K?nig wrote:
> Signed-off-by: Uwe Kleine-K?nig <uwe@kleine-koenig.org>
Hi Uwe
It is normal to send vendor-prefixes patches directly to the device
tree maintainers as a separate patch. That avoids merge conflicts on
the file.
Andrew
^ permalink raw reply
* [PATCH 0/5] drm/sun4i: Handle TV overscan
From: Maxime Ripard @ 2016-11-10 14:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107154652.GH1041@n2100.armlinux.org.uk>
On Mon, Nov 07, 2016 at 03:46:52PM +0000, Russell King - ARM Linux wrote:
> On Mon, Nov 07, 2016 at 04:09:09PM +0100, Maxime Ripard wrote:
> > Hi Russell,
> >
> > On Thu, Nov 03, 2016 at 09:54:45AM +0000, Russell King - ARM Linux wrote:
> > > > Yes. And that is an XBMC only solution, that doesn't work with the
> > > > fbdev emulation and is probably doing an additional composition to
> > > > scale down and center their frames through OpenGL.
> > >
> > > Well, it will have to be doing a scaling step anyway. If the video
> > > frame is a different size to the active area, scaling is required
> > > no matter what. A 576p SD image needs to be scaled up, and a 1080p
> > > image would need to be scaled down for a 1080p overscanned display
> > > with a reduced active area to counter the overscanning - no matter
> > > how you do it.
> >
> > Yes, except that scaling is not always an option. In my particular
> > example, there's no scaler after the CRTC, which essentially prevents
> > it from being used in that use case. Which is also why I ended up
> > reducing the mode reported to the user.
>
> I think you completely missed my point. Let me try again.
>
> If you expose a reduced mode to the user, you are reporting that (eg)
> the 1080p-timings mode does not have 1920 pixels horizontally, and
> 1080 lines. You are instead reporting that it has (eg) 1800 pixels
> horizontally and maybe 1000 lines.
>
> So, when you play back a 1080 video, you are going to have to either:
>
> 1. crop the extra 120 pixels horizontally and 80 lines vertically
> or
> 2. scale the image.
>
> However, this is a completely independent issue to how we go about
> setting a video mode that is 1800x1000 in the first place.
>
> What you're suggesting is that we add code to the kernel to report that
> your non-EDID, analogue output transforms the standard 1920x1080 timings
> such that it has a 1800x1000 active area.
>
> I'm suggesting instead that you can do the same thing in userspace by
> specifically adding a mode which has the 1920x1080 standard timings,
> but with the porches increased and the active area reduced - in exactly
> the same way that you'd have to do within the kernel to report your
> active-area-reduced 1800x1000 mode.
Ah, yes, you meant input scaling, not output, sorry.
> > > For graphics, userspace could add mode(s) with increased porches and
> > > reduced active area itself to achieve an underscanned display on a
> > > timing which the display device always overscans - there's no need to
> > > do that in the kernel, all the APIs are there to be able to do it
> > > already.
> > >
> > > That means your framebuffer will be smaller, but that's the case
> > > anyway.
> >
> > Yes, that would be a good idea. But it's not always an option for
> > applications that would rely on the fbdev emulation (like QT's eglfs),
> > which would then have no way to change whatever default there is (and
> > the only one able to know how bad it actually is is the user).
>
> I guess this is the problem with DRM people wanting to deprecate fbdev...
> too much stuff currently relies upon it, but DRM on x86 has always had
> the reduced functionality.
>
> I guess there's two solutions here:
>
> 1. Either DRMs fbdev gains increased functionality, or
> 2. The fbdev-only applications/libraries need to be ported over to
> support DRM natively.
>
> This has been a bar for some time to moving over to DRM, and I've heard
> very little desire on either side to find some sort of compromise on the
> issue, so I guess things are rather stuck where they are.
I guess it really all boils down to this, and whether the userspace
will be able to set a custom mode on its own. "Advanced" stacks like
Xorg and Wayland will, but simpler and / or legacy applications will
depend on the fbdev emulation, either because they've not been
converted through DRM (like you suggested) or because it depends on a
blob that requires it (and then you're stuck).
And since the kernel already deals with overscan through a generic
property, it really feels like it's the place it should be done to
address all needs (and ideally in a generic way).
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161110/a482bcf9/attachment.sig>
^ permalink raw reply
* [PATCH v2 1/2] iommu/dma: Implement dma_{map,unmap}_resource()
From: Robin Murphy @ 2016-11-10 14:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161110122420.GH9996@8bytes.org>
On 10/11/16 12:24, Joerg Roedel wrote:
> On Wed, Oct 26, 2016 at 06:43:56PM +0100, Robin Murphy wrote:
>> With the new dma_{map,unmap}_resource() functions added to the DMA API
>> for the benefit of cases like slave DMA, add suitable implementations to
>> the arsenal of our generic layer. Since cache maintenance should not be
>> a concern, these can both be standalone callback implementations without
>> the need for arch code wrappers.
>>
>> CC: Joerg Roedel <joro@8bytes.org>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>>
>> v2: Use iommu_dma_unmap_page for symmetry, instead of being sneaky.
>>
>> drivers/iommu/dma-iommu.c | 13 +++++++++++++
>> include/linux/dma-iommu.h | 4 ++++
>> 2 files changed, 17 insertions(+)
>>
>> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
>> index c5ab8667e6f2..a2fd90a6a782 100644
>> --- a/drivers/iommu/dma-iommu.c
>> +++ b/drivers/iommu/dma-iommu.c
>> @@ -624,6 +624,19 @@ void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
>> __iommu_dma_unmap(iommu_get_domain_for_dev(dev), sg_dma_address(sg));
>> }
>>
>> +dma_addr_t iommu_dma_map_resource(struct device *dev, phys_addr_t phys,
>> + size_t size, enum dma_data_direction dir, unsigned long attrs)
>> +{
>> + return iommu_dma_map_page(dev, phys_to_page(phys), offset_in_page(phys),
>> + size, dma_direction_to_prot(dir, false) | IOMMU_MMIO);
>> +}
>
> Isn't the whole point of map_resource that we can map regions which have
> no 'struct page' associated? The use phys_to_page() will certainly not
> do the right thing here.
Perhaps it's a bit cheeky, but the struct page pointer is never
dereferenced - the only thing iommu_dma_map_page() does with it is
immediately convert it back again. Is there ever a case where
page_to_phys(phys_to_page(phys)) != phys ?
Robin.
^ permalink raw reply
* [PATCHv3 2/4] misc: Add Altera Arria10 System Resource Control
From: Greg KH @ 2016-11-10 14:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478097178-24341-3-git-send-email-tthayer@opensource.altera.com>
On Wed, Nov 02, 2016 at 09:32:56AM -0500, tthayer at opensource.altera.com wrote:
> From: Thor Thayer <tthayer@opensource.altera.com>
>
> This patch adds the Altera Arria10 control & monitoring
> functions to the Arria10 System Resource chip.
>
> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
> ---
> v2 Change compatible string and filename from -mon to -monitor
> Change CONFIG from module to builtin.
> Make wm_rst register writeable.
> v3 Remove unused ret variable.
> Shorten driver name (remove altr_).
> ---
> MAINTAINERS | 1 +
> drivers/misc/Kconfig | 7 ++
> drivers/misc/Makefile | 1 +
> drivers/misc/altera-a10sr-monitor.c | 175 ++++++++++++++++++++++++++++++++++++
> 4 files changed, 184 insertions(+)
> create mode 100644 drivers/misc/altera-a10sr-monitor.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b180821..baf2404 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -635,6 +635,7 @@ M: Thor Thayer <tthayer@opensource.altera.com>
> S: Maintained
> F: drivers/gpio/gpio-altera-a10sr.c
> F: drivers/mfd/altera-a10sr.c
> +F: drivers/misc/altera-a10sr-monitor.c
> F: include/linux/mfd/altera-a10sr.h
>
> ALTERA TRIPLE SPEED ETHERNET DRIVER
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 64971ba..f42d459 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -766,6 +766,13 @@ config PANEL_BOOT_MESSAGE
> An empty message will only clear the display at driver init time. Any other
> printf()-formatted message is valid with newline and escape codes.
>
> +config ALTERA_A10SR_MONITOR
> + bool "Altera Arria10 System Resource Monitor"
> + depends on MFD_ALTERA_A10SR
> + help
> + This enables the System Resource monitor driver for the Altera
> + Arria10 DevKit.
> +
> source "drivers/misc/c2port/Kconfig"
> source "drivers/misc/eeprom/Kconfig"
> source "drivers/misc/cb710/Kconfig"
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 3198336..9f6e77a 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -43,6 +43,7 @@ obj-y += ti-st/
> obj-y += lis3lv02d/
> obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
> obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
> +obj-$(CONFIG_ALTERA_A10SR_MONITOR) += altera-a10sr-monitor.o
> obj-$(CONFIG_INTEL_MEI) += mei/
> obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
> obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
> diff --git a/drivers/misc/altera-a10sr-monitor.c b/drivers/misc/altera-a10sr-monitor.c
> new file mode 100644
> index 0000000..66338e0
> --- /dev/null
> +++ b/drivers/misc/altera-a10sr-monitor.c
> @@ -0,0 +1,175 @@
> +/*
> + * Altera Arria10 DevKit System Resource Chip Monitor Driver
> + *
> + * Author: Thor Thayer <tthayer@opensource.altera.com>
> + *
> + * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Monitor driver for the Altera Arria10 MAX5 System Resource Chip
> + * Adapted from ics932s401.c
> + */
> +
> +#include <linux/err.h>
> +#include <linux/mfd/altera-a10sr.h>
> +#include <linux/init.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +struct altr_a10sr_regs {
> + struct regmap *regmap;
> + struct attribute_group attr_grp;
> +};
> +
> +static ssize_t a10sr_show(struct device *dev,
> + struct device_attribute *devattr, char *buf);
> +static ssize_t a10sr_store(struct device *dev,
> + struct device_attribute *devattr, const char *buf,
> + size_t count);
> +
> +/* Define FS entries */
> +static DEVICE_ATTR(max5_version, 0444, a10sr_show, NULL);
> +static DEVICE_ATTR(max5_led, 0644, a10sr_show, a10sr_store);
> +static DEVICE_ATTR(max5_button, 0444, a10sr_show, NULL);
> +static DEVICE_ATTR(max5_button_irq, 0644, a10sr_show, a10sr_store);
> +static DEVICE_ATTR(max5_pg1, 0444, a10sr_show, NULL);
> +static DEVICE_ATTR(max5_pg2, 0444, a10sr_show, NULL);
> +static DEVICE_ATTR(max5_pg3, 0444, a10sr_show, NULL);
> +static DEVICE_ATTR(max5_fmcab, 0444, a10sr_show, NULL);
> +static DEVICE_ATTR(max5_hps_resets, 0644, a10sr_show, a10sr_store);
> +static DEVICE_ATTR(max5_per_resets, 0644, a10sr_show, a10sr_store);
> +static DEVICE_ATTR(max5_sfpa, 0644, a10sr_show, a10sr_store);
> +static DEVICE_ATTR(max5_sfpb, 0644, a10sr_show, a10sr_store);
> +static DEVICE_ATTR(max5_i2c_master, 0644, a10sr_show, a10sr_store);
> +static DEVICE_ATTR(max5_wm_rst, 0644, a10sr_show, a10sr_store);
> +static DEVICE_ATTR(max5_wm_rst_key, 0644, a10sr_show, a10sr_store);
> +static DEVICE_ATTR(max5_pmbus, 0644, a10sr_show, a10sr_store);
Please add a Documentation/ABI file to describe all of thes new sysfs
files that you are saying will be present for all of time.
And do you really want userspace access like this to these values?
Shouldn't things like the led and button use the proper led and input
layers instead?
> +static int altr_a10sr_regs_probe(struct platform_device *pdev)
> +{
> + struct altr_a10sr_regs *a10regs;
> + struct altr_a10sr *a10sr = dev_get_drvdata(pdev->dev.parent);
> +
> + a10regs = devm_kzalloc(&pdev->dev, sizeof(*a10regs), GFP_KERNEL);
> + if (!a10regs)
> + return -ENOMEM;
> +
> + a10regs->regmap = a10sr->regmap;
> + a10regs->attr_grp = a10sr_attr_group;
> +
> + platform_set_drvdata(pdev, a10regs);
> +
> + return sysfs_create_group(&pdev->dev.kobj, &a10sr_attr_group);
You just raced userspace and lost :(
Please set the group file properly, and then the driver core should set
this up for you correctly.
thanks,
greg k-h
^ permalink raw reply
* [PATCH v5 6/8] Documentation: bindings: add compatible specific to legacy SCPI protocol
From: Sudeep Holla @ 2016-11-10 14:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAL_JsqLW4JZHb0ncVUEefnKySA231EDgvCkY3xPdaJGf=uMJYg@mail.gmail.com>
On 10/11/16 14:12, Rob Herring wrote:
> On Thu, Nov 10, 2016 at 4:26 AM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>
>>
>> On 10/11/16 01:22, Rob Herring wrote:
>>>
>>> On Wed, Nov 02, 2016 at 10:52:09PM -0600, Sudeep Holla wrote:
>>>>
>>>> This patch adds specific compatible to support legacy SCPI protocol.
>>>>
>>>> Cc: Rob Herring <robh+dt@kernel.org>
>>>> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
>>>> ---
>>>> Documentation/devicetree/bindings/arm/arm,scpi.txt | 4 +++-
>>>> 1 file changed, 3 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt
>>>> b/Documentation/devicetree/bindings/arm/arm,scpi.txt
>>>> index d1882c4540d0..ebd03fc93135 100644
>>>> --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt
>>>> +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt
>>>> @@ -7,7 +7,9 @@ by Linux to initiate various system control and power
>>>> operations.
>>>>
>>>> Required properties:
>>>>
>>>> -- compatible : should be "arm,scpi"
>>>> +- compatible : should be
>>>> + * "arm,scpi" : For implementations complying to SCPI v1.0 or
>>>> above
>>>> + * "arm,legacy-scpi" : For implementations complying pre SCPI v1.0
>>>
>>>
>>> I'd prefer that we explicitly enumerate the old versions. Are there
>>> many?
>>>
>>
>> I understand your concern, but this legacy SCPI protocol was not
>> officially released. It was just WIP which vendors picked up from very
>> early releases. Since they are not numbered, it's hard to have specific
>> compatibles with different versions until v1.0. That's one of the reason
>> to retain platform specific compatible so that we can add any quirks
>> based on them if needed.
>>
>> I will probably add these information in the commit log so that it's
>> clear why we can't do version based compatible.
>
> This is exactly my point. By enumerate, I meant having platform
> specific compatibles. Having "arm,legacy-scpi" is pointless because
> who knows what version they followed and they may all be different.
>
OK, but IIUC Olof's concern wanted a generic one along with the platform
specific compatible which kind of makes sense as so far we have seen
some commonality between Amlogic and Rockchip.
E.g. Amlogic follows most of the legacy protocol though it deviates in
couple of things which we can handle with platform specific compatible
(in the following patch in the series). When another user(Rockchip ?)
make use of this legacy protocol, we can start using those platform
specific compatible for deviations only.
Is that not acceptable ?
--
Regards,
Sudeep
^ permalink raw reply
* Summary of LPC guest MSI discussion in Santa Fe
From: Joerg Roedel @ 2016-11-10 14:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161109130114.3e17bba9@t450s.home>
On Wed, Nov 09, 2016 at 01:01:14PM -0700, Alex Williamson wrote:
> Well, it's not like QEMU or libvirt stumbling through sysfs to figure
> out where holes could be in order to instantiate a VM with matching
> holes, just in case someone might decide to hot-add a device into the
> VM, at some point, and hopefully they don't migrate the VM to another
> host with a different layout first, is all that much less disgusting or
> foolproof. It's just that in order to dynamically remove a page as a
> possible DMA target we require a paravirt channel, such as a balloon
> driver that's able to pluck a specific page. In some ways it's
> actually less disgusting, but it puts some prerequisites on
> enlightening the guest OS. Thanks,
I think it is much simpler if libvirt/qemu just go through all
potentially assignable devices on a system and pre-exclude any addresses
from guest RAM beforehand, rather than doing something like this with
paravirt/ballooning when a device is hot-added. There is no guarantee
that you can take a page away from a linux-guest.
Joerg
^ permalink raw reply
* Summary of LPC guest MSI discussion in Santa Fe
From: Joerg Roedel @ 2016-11-10 14:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <83b6440a-31eb-c1b4-642c-a4c311f37ef2@redhat.com>
On Thu, Nov 10, 2016 at 01:14:42AM +0100, Auger Eric wrote:
> Besides above problematic, I started to prototype the sysfs API. A first
> issue I face is the reserved regions become global to the iommu instead
> of characterizing the iommu_domain, ie. the "reserved_regions" attribute
> file sits below an iommu instance (~
> /sys/class/iommu/dmar0/intel-iommu/reserved_regions ||
> /sys/class/iommu/arm-smmu0/arm-smmu/reserved_regions).
>
> MSI reserved window can be considered global to the IOMMU. However PCIe
> host bridge P2P regions rather are per iommu-domain.
>
> Do you confirm the attribute file should contain both global reserved
> regions and all per iommu_domain reserved regions?
>
> Thoughts?
This information is best attached to the sysfs-representation of
iommu-groups. The file should then contain the superset of all reserved
regions of the devices the group contains. This makes it usable later to
also describe RMRR/Unity-mapped regions on x86 there and make them
assignable to guests as well.
Joerg
^ 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