* [PATCH v8 2/5] i2c: Add STM32F4 I2C driver
From: M'boumba Cedric Madianga @ 2017-01-11 14:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOAejn2eOy2sn1VkE979ne23Sj9L6+kaQDNpL1EUKb2m=6sGXw@mail.gmail.com>
>
>> + */
>> + reg = i2c_dev->base + STM32F4_I2C_CR1;
>> + stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_ACK);
>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_POS);
>
> You could get rid of this, when caching the value of CR1. Would save two
> register reads here. This doesn't work for all registers, but it should
> be possible to apply for most of them, maybe enough to get rid of the
> clr_bits and set_bits function.
I agree at many places I could save registers read by not using
clr_bits and set_bits function when the registers in question has been
already read.
But it is not enough to get rid of the clr_bits and set_bits function.
For example when calling stm32f4_i2c_terminate_xfer(), the CR1
register is never read before so set_bits function is useful.
Another example, when stm32f4_i2c_handle_rx_done(), the CR1 register
is also never read before so clr_bits finction is again useful.
2017-01-11 14:58 GMT+01:00 M'boumba Cedric Madianga <cedric.madianga@gmail.com>:
> Hi Uwe,
>
> 2017-01-11 9:22 GMT+01:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> Hello Cedric,
>>
>> On Thu, Jan 05, 2017 at 10:07:23AM +0100, M'boumba Cedric Madianga wrote:
>>> +/*
>>> + * In standard mode:
>>> + * SCL period = SCL high period = SCL low period = CCR * I2C parent clk period
>>> + *
>>> + * In fast mode:
>>> + * If Duty = 0; SCL high period = 1 * CCR * I2C parent clk period
>>> + * SCL low period = 2 * CCR * I2C parent clk period
>>> + * If Duty = 1; SCL high period = 9 * CCR * I2C parent clk period
>>> + * SCL low period = 16 * CCR * I2C parent clk period
>> s/ \*/ */ several times
>
> Sorry but I don't see where is the issue as the style for multi-line
> comments seems ok.
> Could you please clarify that point if possible ? Thanks in advance
>
>>
>>> + * In order to reach 400 kHz with lower I2C parent clk frequencies we always set
>>> + * Duty = 1
>>> + *
>>> + * For both modes, we have CCR = SCL period * I2C parent clk frequency
>>> + * with scl_period = 5 microseconds in Standard mode and scl_period = 1
>> s/mode/Mode/
>
> ok thanks
>
>>
>>> + * microsecond in Fast Mode in order to satisfy scl_high and scl_low periods
>>> + * constraints defined by i2c bus specification
>>
>> I don't understand scl_period = 1 ?s for Fast Mode. For a bus freqency
>> of 400 kHz we need low + high = 2.5 ?s. Is there a factor 10 missing
>> somewhere?
>
> As CCR = SCL_period * I2C parent clk frequency with minimal freq =
> 2Mhz and SCL_period = 1 we have:
> CCR = 1 * 2Mhz = 2.
> But to compute, scl_low and scl_high in Fast mode, we have to do the
> following thing as Duty=1:
> scl_high = 9 * CCR * I2C parent clk period
> scl_low = 16 * CCR * I2C parent clk period
> In our example:
> scl_high = 9 * 2 * 0,0000005 = 0,000009 sec = 9 ?s
> scl_low = 16 * 2 * 0.0000005 = 0,000016 sec = 16 ?s
> So low + high = 27 ?s > 2,5 ?s
>
>>
>>> + */
>>> +static struct stm32f4_i2c_timings i2c_timings[] = {
>>> [...]
>>> +
>>> +/**
>>> + * stm32f4_i2c_hw_config() - Prepare I2C block
>>> + * @i2c_dev: Controller's private data
>>> + */
>>> +static int stm32f4_i2c_hw_config(struct stm32f4_i2c_dev *i2c_dev)
>>> +{
>>> + void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR1;
>>> + int ret = 0;
>>> +
>>> + /* Disable I2C */
>>> + stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_PE);
>>> +
>>> + ret = stm32f4_i2c_set_periph_clk_freq(i2c_dev);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + stm32f4_i2c_set_rise_time(i2c_dev);
>>> +
>>> + stm32f4_i2c_set_speed_mode(i2c_dev);
>>> +
>>> + stm32f4_i2c_set_filter(i2c_dev);
>>> +
>>> + /* Enable I2C */
>>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_PE);
>>
>> This function is called after a hw reset, so there should be no need to
>> use clr_bits and set_bits because the value read from hw should be
>> known.
>
> ok thanks
>
>>
>>> + return ret;
>>
>> return 0;
>
> ok thanks
>
>>
>>> +}
>>> +
>>> +static int stm32f4_i2c_wait_free_bus(struct stm32f4_i2c_dev *i2c_dev)
>>> +{
>>> + u32 status;
>>> + int ret;
>>> +
>>> + ret = readl_relaxed_poll_timeout(i2c_dev->base + STM32F4_I2C_SR2,
>>> + status,
>>> + !(status & STM32F4_I2C_SR2_BUSY),
>>> + 10, 1000);
>>> + if (ret) {
>>> + dev_dbg(i2c_dev->dev, "bus not free\n");
>>> + ret = -EBUSY;
>>> + }
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +/**
>>> + * stm32f4_i2c_write_ byte() - Write a byte in the data register
>>> + * @i2c_dev: Controller's private data
>>> + * @byte: Data to write in the register
>>> + */
>>> +static void stm32f4_i2c_write_byte(struct stm32f4_i2c_dev *i2c_dev, u8 byte)
>>> +{
>>> + writel_relaxed(byte, i2c_dev->base + STM32F4_I2C_DR);
>>> +}
>>> +
>>> +/**
>>> + * stm32f4_i2c_write_msg() - Fill the data register in write mode
>>> + * @i2c_dev: Controller's private data
>>> + *
>>> + * This function fills the data register with I2C transfer buffer
>>> + */
>>> +static void stm32f4_i2c_write_msg(struct stm32f4_i2c_dev *i2c_dev)
>>> +{
>>> + struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
>>> +
>>> + stm32f4_i2c_write_byte(i2c_dev, *msg->buf++);
>>> + msg->count--;
>>> +}
>>> +
>>> +static void stm32f4_i2c_read_msg(struct stm32f4_i2c_dev *i2c_dev)
>>> +{
>>> + struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
>>> + u32 rbuf;
>>> +
>>> + rbuf = readl_relaxed(i2c_dev->base + STM32F4_I2C_DR);
>>> + *msg->buf++ = rbuf & 0xff;
>>
>> This is unnecessary. buf has an 8 bit wide type so
>>
>> *msg->buf++ = rbuf;
>>
>> has the same effect. (ISTR this is something I already pointed out
>> earlier?)
>
> Yes you are right.
>
>>
>>> + msg->count--;
>>> +}
>>> +
>>> +static void stm32f4_i2c_terminate_xfer(struct stm32f4_i2c_dev *i2c_dev)
>>> +{
>>> + struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
>>> + void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR2;
>>> +
>>> + stm32f4_i2c_disable_irq(i2c_dev);
>>> +
>>> + reg = i2c_dev->base + STM32F4_I2C_CR1;
>>> + if (msg->stop)
>>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_STOP);
>>> + else
>>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
>>> +
>>> + complete(&i2c_dev->complete);
>>> +}
>>> +
>>> +/**
>>> + * stm32f4_i2c_handle_write() - Handle FIFO empty interrupt in case of write
>>> + * @i2c_dev: Controller's private data
>>> + */
>>> +static void stm32f4_i2c_handle_write(struct stm32f4_i2c_dev *i2c_dev)
>>> +{
>>> + struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
>>> + void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR2;
>>> +
>>> + if (msg->count) {
>>> + stm32f4_i2c_write_msg(i2c_dev);
>>> + if (!msg->count) {
>>> + /* Disable buffer interrupts for RXNE/TXE events */
>>> + stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR2_ITBUFEN);
>>> + }
>>> + } else {
>>> + stm32f4_i2c_terminate_xfer(i2c_dev);
>>
>> Is stm32f4_i2c_terminate_xfer also called when arbitration is lost? If
>> yes, is it then right to set STM32F4_I2C_CR1_STOP or
>> STM32F4_I2C_CR1_START?
>
> If arbitration is lost, stm32f4_i2c_terminate_xfer() is not called.
> In that case, we return -EAGAIN and i2c-core will retry by calling
> stm32f4_i2c_xfer()
>
>>
>>> + }
>>> +}
>>> +
>>> +/**
>>> + * stm32f4_i2c_handle_read() - Handle FIFO empty interrupt in case of read
>>> + * @i2c_dev: Controller's private data
>>> + */
>>> +static void stm32f4_i2c_handle_read(struct stm32f4_i2c_dev *i2c_dev)
>>> +{
>>> + struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
>>> + void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR2;
>>> +
>>> + switch (msg->count) {
>>> + case 1:
>>> + stm32f4_i2c_disable_irq(i2c_dev);
>>> + stm32f4_i2c_read_msg(i2c_dev);
>>> + complete(&i2c_dev->complete);
>>> + break;
>>> + /*
>>> + * For 2 or 3-byte reception, we do not have to read the data register
>>> + * when RXNE occurs as we have to wait for byte transferred finished
>>
>> it's hard to understand because if you don't know the hardware the
>> meaning of RXNE is unknown.
>
> Ok I will replace RXNE by RX not empty in that comment
>
>>
>>> + * event before reading data. So, here we just disable buffer
>>> + * interrupt in order to avoid another system preemption due to RXNE
>>> + * event
>>> + */
>>> + case 2:
>>> + case 3:
>>> + stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR2_ITBUFEN);
>>> + break;
>>> + /* For N byte reception with N > 3 we directly read data register */
>>> + default:
>>> + stm32f4_i2c_read_msg(i2c_dev);
>>> + }
>>> +}
>>> +
>>> +/**
>>> + * stm32f4_i2c_handle_rx_btf() - Handle byte transfer finished interrupt
>>> + * in case of read
>>> + * @i2c_dev: Controller's private data
>>> + */
>>> +static void stm32f4_i2c_handle_rx_btf(struct stm32f4_i2c_dev *i2c_dev)
>>> +{
>>
>> btf is a hw-related name. Maybe better use _done which is easier to
>> understand?
>
> OK
>
>>
>>> + struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
>>> + void __iomem *reg;
>>> + u32 mask;
>>> + int i;
>>> +
>>> + switch (msg->count) {
>>> + case 2:
>>> + /*
>>> + * In order to correctly send the Stop or Repeated Start
>>> + * condition on the I2C bus, the STOP/START bit has to be set
>>> + * before reading the last two bytes.
>>> + * After that, we could read the last two bytes, disable
>>> + * remaining interrupts and notify the end of xfer to the
>>> + * client
>>
>> This is surprising. I didn't recheck the manual, but that looks very
>> uncomfortable.
>
> I agree but this exactly the hardware way of working described in the
> reference manual.
>
>>How does this work, when I only want to read a single
>> byte? Same problem for ACK below.
>
> For a single reception, we enable NACK and STOP or Repeatead START
> bits during address match.
> The NACK and STOP/START pulses are sent as soon as the data is
> received in the shift register.
> Please note that in that case, we don't have to wait BTF event to read the data.
> Data is read as soon as RXNE event occurs.
>
>>
>>> + */
>>> + reg = i2c_dev->base + STM32F4_I2C_CR1;
>>> + if (msg->stop)
>>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_STOP);
>>> + else
>>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
>>> +
>>> + for (i = 2; i > 0; i--)
>>> + stm32f4_i2c_read_msg(i2c_dev);
>>> +
>>> + reg = i2c_dev->base + STM32F4_I2C_CR2;
>>> + mask = STM32F4_I2C_CR2_ITEVTEN | STM32F4_I2C_CR2_ITERREN;
>>> + stm32f4_i2c_clr_bits(reg, mask);
>>> +
>>> + complete(&i2c_dev->complete);
>>> + break;
>>> + case 3:
>>> + /*
>>> + * In order to correctly send the ACK on the I2C bus for the
>>> + * last two bytes, we have to set ACK bit before reading the
>>> + * third last data byte
>>> + */
>>> + reg = i2c_dev->base + STM32F4_I2C_CR1;
>>> + stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_ACK);
>>> + stm32f4_i2c_read_msg(i2c_dev);
>>> + break;
>>> + default:
>>> + stm32f4_i2c_read_msg(i2c_dev);
>>> + }
>>> +}
>>> +
>>> +/**
>>> + * stm32f4_i2c_handle_rx_addr() - Handle address matched interrupt in case of
>>> + * master receiver
>>> + * @i2c_dev: Controller's private data
>>> + */
>>> +static void stm32f4_i2c_handle_rx_addr(struct stm32f4_i2c_dev *i2c_dev)
>>> +{
>>> + struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
>>> + void __iomem *reg;
>>> +
>>> + switch (msg->count) {
>>> + case 0:
>>> + stm32f4_i2c_terminate_xfer(i2c_dev);
>>> + /* Clear ADDR flag */
>>> + readl_relaxed(i2c_dev->base + STM32F4_I2C_SR2);
>>> + break;
>>> + case 1:
>>> + /*
>>> + * Single byte reception:
>>
>> This also happens for the last byte of a 5 byte transfer, right?
>
> For a 5 byte transfer the behavior is different:
> We have to read data from DR (data register) as soon as the RXNE (RX
> not empty) event occurs for data1, data2 and data3 (until N-2 data for
> a more generic case)
> The ACK is automatically sent as soon as the data is received in the
> shift register as the I2C controller was configured to do that during
> adress match phase.
>
> For data3 (N-2 data), we wait for BTF (Byte Transfer finished) event
> in order to set NACK before reading DR.
> This event occurs when a new data has been received in shift register
> (in our case data4 or N-1 data) but the prevoius data in DR (in our
> case data3 or N-2 data) has not been read yet.
> In that way, the NACK pulse will be correctly generated after the last
> received data byte.
>
> For data4 and data5, we wait for BTF event (data4 or N-1 data in DR
> and data5 or N data in shift register), set STOP or repeated Start in
> order to correctly sent the right pulse after the last received data
> byte and run 2 consecutives read of DR.
>
>>
>>> + * Enable NACK, clear ADDR flag and generate STOP or RepSTART
>>> + */
>>> + reg = i2c_dev->base + STM32F4_I2C_CR1;
>>> + stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_ACK);
>>> + readl_relaxed(i2c_dev->base + STM32F4_I2C_SR2);
>>> + if (msg->stop)
>>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_STOP);
>>> + else
>>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
>>> + break;
>>> + case 2:
>>> + /*
>>> + * 2-byte reception:
>>> + * Enable NACK and set POS
>>
>> What is POS?
> POS is used to define the position of the (N)ACK pulse
> 0: ACK is generated when the current is being received in the shift register
> 1: ACK is generated when the next byte which will be received in the
> shift register (used for 2-byte reception)
>
>>
>>> + */
>>> + reg = i2c_dev->base + STM32F4_I2C_CR1;
>>> + stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_ACK);
>>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_POS);
>>
>> You could get rid of this, when caching the value of CR1. Would save two
>> register reads here. This doesn't work for all registers, but it should
>> be possible to apply for most of them, maybe enough to get rid of the
>> clr_bits and set_bits function.
>>
>>> + readl_relaxed(i2c_dev->base + STM32F4_I2C_SR2);
>>> + break;
>>> +
>>> + default:
>>> + /* N-byte reception: Enable ACK */
>>> + reg = i2c_dev->base + STM32F4_I2C_CR1;
>>> + stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_ACK);
>>
>> Do you need to set ACK for each byte transferred?
> I need to do that in order to be SMBus compatible and the ACK/NACK
> seems to be used by default in Documentation/i2c/i2c-protocol file.
>
>>
>> I stopp reviewing here because of -ENOTIME on my side but don't want to
>> delay discussion, so sent my comments up to here already now.
>>
>> Best regards
>> Uwe
>>
>> --
>> Pengutronix e.K. | Uwe Kleine-K?nig |
>> Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH] arm64: Add support for DMA_ATTR_SKIP_CPU_SYNC attribute to swiotlb
From: Robin Murphy @ 2017-01-11 14:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484129477-24121-1-git-send-email-geert+renesas@glider.be>
On 11/01/17 10:11, Geert Uytterhoeven wrote:
> From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
>
> This patch adds support for DMA_ATTR_SKIP_CPU_SYNC attribute for
> dma_{un}map_{page,sg} functions family to swiotlb.
>
> DMA_ATTR_SKIP_CPU_SYNC allows platform code to skip synchronization of
> the CPU cache for the given buffer assuming that it has been already
> transferred to 'device' domain.
>
> Ported from IOMMU .{un}map_{sg,page} ops.
>
> Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> v2:
> - Add Acked-by.
>
> Support for DMA_ATTR_SKIP_CPU_SYNC was included when porting the IOMMU
> ops from arm to arm64 in commit 13b8629f651164d7 ("arm64: Add IOMMU
> dma_ops").
>
> Presumably it was an oversight that the existing swiotlb based
> implementation didn't have support for DMA_ATTR_SKIP_CPU_SYNC yet?
Less an oversight, more that nobody's wanted to use it until now ;)
Personally I'd prefer flag tests to be "!(x)" rather than "(x) == 0",
but the latter is already in place, so I'll leave the final word on
style/consistency nitpicks to Catalin and Will.
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> ---
> arch/arm64/mm/dma-mapping.c | 12 ++++++++----
> 1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index e04082700bb16c35..1d7d5d2881db7c19 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -211,7 +211,8 @@ static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
> dma_addr_t dev_addr;
>
> dev_addr = swiotlb_map_page(dev, page, offset, size, dir, attrs);
> - if (!is_device_dma_coherent(dev))
> + if (!is_device_dma_coherent(dev) &&
> + (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
> __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
>
> return dev_addr;
> @@ -222,7 +223,8 @@ static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
> size_t size, enum dma_data_direction dir,
> unsigned long attrs)
> {
> - if (!is_device_dma_coherent(dev))
> + if (!is_device_dma_coherent(dev) &&
> + (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
> __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
> swiotlb_unmap_page(dev, dev_addr, size, dir, attrs);
> }
> @@ -235,7 +237,8 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
> int i, ret;
>
> ret = swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs);
> - if (!is_device_dma_coherent(dev))
> + if (!is_device_dma_coherent(dev) &&
> + (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
> for_each_sg(sgl, sg, ret, i)
> __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
> sg->length, dir);
> @@ -251,7 +254,8 @@ static void __swiotlb_unmap_sg_attrs(struct device *dev,
> struct scatterlist *sg;
> int i;
>
> - if (!is_device_dma_coherent(dev))
> + if (!is_device_dma_coherent(dev) &&
> + (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
> for_each_sg(sgl, sg, nelems, i)
> __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
> sg->length, dir);
>
^ permalink raw reply
* [PATCH 0/3] arm64: dts: A64 board MMC support
From: Andre Przywara @ 2017-01-11 14:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170111135139.ktirdwmzhyv3cn2q@lukather>
Hi,
On 11/01/17 13:51, Maxime Ripard wrote:
> Hi,
>
> On Tue, Jan 10, 2017 at 01:22:30AM +0000, Andre Przywara wrote:
>> These patches here go on top of Maxime's latest A64 MMC series and
>> enable the MMC controllers on the boards using the A64 SoC.
>> As the BananaPi-M64 DT now looks different, lets adds support for
>> that board as well, with one major difference to the Pine64 being the eMMC
>> chip.
>>
>> I could't find commit f9ca9b952ee1 Maxime mentioned in his cover letter,
>> so I applied his patches on top of sunxi/for-next and cherry-picked
>> b4b8664d29 to fix the arm64 build.
>
> I'm fine with all your patches. I've queued them in my MMC series, and
> will continue pushing them and / or merging them if it's ok for you.
Yes, please do!
Many thanks!
Cheers,
Andre.
^ permalink raw reply
* [PATCH 56/62] watchdog: tangox_wdt: Convert to use device managed functions
From: Guenter Roeck @ 2017-01-11 14:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <a45ed205-7c1b-a298-50c0-fc8b80a846c5@sigmadesigns.com>
On 01/11/2017 04:31 AM, Marc Gonzalez wrote:
> On 11/01/2017 11:52, Guenter Roeck wrote:
>
>> On 01/11/2017 01:07 AM, Marc Gonzalez wrote:
>>
>>>> @@ -134,12 +134,15 @@ static int tangox_wdt_probe(struct platform_device *pdev)
>>>> err = clk_prepare_enable(dev->clk);
>>>> if (err)
>>>> return err;
>>>> + err = devm_add_action_or_reset(&pdev->dev,
>>>> + (void(*)(void *))clk_disable_unprepare,
>>>> + dev->clk);
>>>> + if (err)
>>>> + return err;
>>>
>>> Hello Guenter,
>>>
>>> I would rather avoid the function pointer cast.
>>> How about defining an auxiliary function for the cleanup action?
>>>
>>> clk_disable_unprepare() is static inline, so gcc will have to
>>> define an auxiliary function either way. What do you think?
>>
>> Not really. It would just make it more complicated to replace the
>> call with devm_clk_prepare_enable(), should it ever find its way
>> into the light of day.
>
> More complicated, because the cleanup function will have to be deleted later?
> The compiler will warn if someone forgets to do that.
>
> In my opinion, it's not a good idea to rely on the fact that casting
> void(*)(struct clk *clk) to void(*)(void *) is likely to work as expected
> on most platforms. (It has undefined behavior, strictly speaking.)
>
I do hear that you object to this code.
However, I must admit that you completely lost me here. It is a cast from
one function pointer to another, passed as argument to another function,
with a secondary cast of its argument from a typed pointer to a void pointer.
I don't think C permits for "undefined behavior, strictly speaking".
Besides, that same mechanism is already used elsewhere, which is how I
got the idea. Are you claiming that there are situations where it won't
work ?
> Do you really dislike the portable solution I suggested? :-(
>
It is not more portable than the above. It is more expensive and adds more
code.
Thanks,
Guenter
^ permalink raw reply
* [PATCH] firmware: ti_sci: fix strncat length check
From: Nishanth Menon @ 2017-01-11 14:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170111133808.3757036-1-arnd@arndb.de>
On Wed, Jan 11, 2017 at 7:37 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> gcc-7 notices that the length we pass to strncat is wrong:
>
> drivers/firmware/ti_sci.c: In function 'ti_sci_probe':
> drivers/firmware/ti_sci.c:204:32: error: specified bound 50 equals the size of the destination [-Werror=stringop-overflow=]
>
> Instead of the total length, we must pass the length of the
> remaining space here.
>
> Fixes: aa276781a64a ("firmware: Add basic support for TI System Control Interface (TI-SCI) protocol")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> drivers/firmware/ti_sci.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> index 874ff32db366..00cfed3c3e1a 100644
> --- a/drivers/firmware/ti_sci.c
> +++ b/drivers/firmware/ti_sci.c
> @@ -202,7 +202,8 @@ static int ti_sci_debugfs_create(struct platform_device *pdev,
> info->debug_buffer[info->debug_region_size] = 0;
>
> info->d = debugfs_create_file(strncat(debug_name, dev_name(dev),
> - sizeof(debug_name)),
> + sizeof(debug_name) -
> + sizeof("ti_sci_debug@")),
> 0444, NULL, info, &ti_sci_debug_fops);
> if (IS_ERR(info->d))
> return PTR_ERR(info->d);
Aargh.. thanks.... Santosh: if you could pick this up.. using
strlen(debug_name) might be an overkill here.
Acked-by: Nishanth Menon <nm@ti.com>
---
Regards,
Nishanth Menon
^ permalink raw reply
* [PATCH 5/8] efi: Get the secure boot status [ver #6]
From: Matt Fleming @ 2017-01-11 14:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <148120024570.5854.10638278395097394138.stgit@warthog.procyon.org.uk>
On Thu, 08 Dec, at 12:30:45PM, David Howells wrote:
> Get the firmware's secure-boot status in the kernel boot wrapper and stash
> it somewhere that the main kernel image can find.
>
> The efi_get_secureboot() function is extracted from the arm stub and (a)
> generalised so that it can be called from x86 and (b) made to use
> efi_call_runtime() so that it can be run in mixed-mode.
>
> Suggested-by: Lukas Wunner <lukas@wunner.de>
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
>
> Documentation/x86/zero-page.txt | 2 +
> arch/x86/boot/compressed/eboot.c | 2 +
> arch/x86/boot/compressed/head_32.S | 1
> arch/x86/boot/compressed/head_64.S | 1
> arch/x86/include/asm/bootparam_utils.h | 5 +-
> arch/x86/include/uapi/asm/bootparam.h | 3 +
> arch/x86/kernel/asm-offsets.c | 1
> drivers/firmware/efi/libstub/Makefile | 2 -
> drivers/firmware/efi/libstub/arm-stub.c | 63 +++--------------------------
> drivers/firmware/efi/libstub/secureboot.c | 63 +++++++++++++++++++++++++++++
> include/linux/efi.h | 8 ++++
> 11 files changed, 90 insertions(+), 61 deletions(-)
> create mode 100644 drivers/firmware/efi/libstub/secureboot.c
[...]
> diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
> index d85b9625e836..c635f7e32f5c 100644
> --- a/arch/x86/boot/compressed/head_32.S
> +++ b/arch/x86/boot/compressed/head_32.S
> @@ -61,6 +61,7 @@
>
> __HEAD
> ENTRY(startup_32)
> + movb $0, BP_secure_boot(%esi)
> #ifdef CONFIG_EFI_STUB
> jmp preferred_addr
>
> diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
> index beab8322f72a..ccd2c7461b7f 100644
> --- a/arch/x86/boot/compressed/head_64.S
> +++ b/arch/x86/boot/compressed/head_64.S
> @@ -244,6 +244,7 @@ ENTRY(startup_64)
> * that maps our entire kernel(text+data+bss+brk), zero page
> * and command line.
> */
> + movb $0, BP_secure_boot(%rsi)
> #ifdef CONFIG_EFI_STUB
> /*
> * The entry point for the PE/COFF executable is efi_pe_entry, so
Is clearing ::secure_boot really necessary? Any code path that goes
via efi_main() will set it correctly and all other code paths should
get it cleared in sanitize_boot_params(), no?
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index c7904556d7a8..92e23f03045e 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -1477,6 +1477,14 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
> bool efi_runtime_disabled(void);
> extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
>
> +enum efi_secureboot_mode {
> + efi_secureboot_mode_unset,
> + efi_secureboot_mode_unknown,
> + efi_secureboot_mode_disabled,
> + efi_secureboot_mode_enabled,
> +};
> +enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table);
> +
> /*
> * Arch code can implement the following three template macros, avoiding
> * reptition for the void/non-void return cases of {__,}efi_call_virt():
>
What's the distinction between the unset and unknown enums?
^ permalink raw reply
* [PATCH v2 05/12] Document: dt: binding: imx: update pinctrl doc for imx6sll
From: Linus Walleij @ 2017-01-11 14:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AM3PR04MB5304992095753B761E66A9A87640@AM3PR04MB530.eurprd04.prod.outlook.com>
On Mon, Jan 9, 2017 at 3:32 AM, Jacky Bai <ping.bai@nxp.com> wrote:
> I have look into the above commit on using generic binding. But I think the generic pinconf
> is not very easy to add in imx pinctrl Driver. imx pinctrl use a different way to parse the pin configure.
OK atleast I need an indication from one of the i.MX maintainers how they
want to proceed.
> Each fsl,pin entry looks like <PIN_FUNC_ID CONFIG> in dts, the CONFIG is the pad setting value like
> pull-up, open-drain, drive strength etc. The above config bit definition is specific to each SOC in the PAD CTL register.
>
> If we want set the pin config to enable hysteresis, 47KOhm Pull Up, 50Mhz speed, 80Ohm driver strength
> and Fast Slew Rate, then the CONFIG value should be 0x17059( ORs corresponding bit definition).
Hysteresis is an input property and does not make sense on something
that need drive
strength and slew rate configuration which are output properties.
(I guess you mean 80mA drive strength.)
Actually such oxymoronic settings is a good reason to migrate to
generic bindings
because when you describe stuff with generic strings you see better
what is going
on, and we can add sanity checks to cases like this in the generic code where it
would indeed be valid to ask why this combination of settings is being made.
> This value will be set in
> PAD CTL register to config the corresponding pin.
Yes? That is common. It looks like that in DT:
{
input-schmitt-enable;
bias-pull-up = <47000>;
slew-rate = <50000000>;
drive-strength = <80000>;
};
Yours,
Linus Walleij
^ permalink raw reply
* [RFC PATCH net-next v4 1/2] macb: Add 1588 support in Cadence GEM.
From: Andrei.Pistirica at microchip.com @ 2017-01-11 14:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170103111447.GA26488@localhost.localdomain>
> On Tue, Jan 03, 2017 at 10:47:56AM +0000, Rafal Ozieblo wrote:
> > We could use only descriptor approach but there are many Atmel's cores
> on the market which support only event registers.
>
> As I said in my other reply in this thread, the Atmel cores cannot possibly be
> made to work correctly.
>
> Sad, but true.
In conscience, I will make a patch containing only the common code (just to benefit from this effort) and then Rafal can add the driver for the GXL version on top of it.
Everybody agrees with this?
Best regards,
Andrei
>
> Thanks,
> Richard
^ permalink raw reply
* [RFC PATCH v4 0/5] ARM: Fix dma_alloc_coherent() and friends for NOMMU
From: Vladimir Murzin @ 2017-01-11 14:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+M3ks5JP14SzprzE90-ST8b3URJECgpJ=dxw5XKvaxYEF3UCw@mail.gmail.com>
On 11/01/17 13:17, Benjamin Gaignard wrote:
> 2017-01-10 15:18 GMT+01:00 Vladimir Murzin <vladimir.murzin@arm.com>:
>> Hi,
>>
>> It seem that addition of cache support for M-class cpus uncovered
>> latent bug in DMA usage. NOMMU memory model has been treated as being
>> always consistent; however, for R/M classes of cpu memory can be
>> covered by MPU which in turn might configure RAM as Normal
>> i.e. bufferable and cacheable. It breaks dma_alloc_coherent() and
>> friends, since data can stuck in caches now or be buffered.
>>
>> This patch set is trying to address the issue by providing region of
>> memory suitable for consistent DMA operations. It is supposed that
>> such region is marked by MPU as non-cacheable. Robin suggested to
>> advertise such memory as reserved shared-dma-pool, rather then using
>> homebrew command line option, and extend dma-coherent to provide
>> default DMA area in the similar way as it is done for CMA (PATCH
>> 2/5). It allows us to offload all bookkeeping on generic coherent DMA
>> framework, and it is seems that it might be reused by other
>> architectures like c6x and blackfin.
>>
>> Dedicated DMA region is required for cases other than:
>> - MMU/MPU is off
>> - cpu is v7m w/o cache support
>> - device is coherent
>>
>> In case one of the above conditions is true dma operations are forced
>> to be coherent and wired with dma_noop_ops.
>>
>> To make life easier NOMMU dma operations are kept in separate
>> compilation unit.
>>
>> Since the issue was reported in the same time as Benjamin sent his
>> patch [1] to allow mmap for NOMMU, his case is also addressed in this
>> series (PATCH 1/5 and PATCH 3/5).
>>
>> Thanks!
>
> I have tested this v4 on my setup (stm32f4, no cache, no MPU) and unfortunately
> it doesn't work with my drm/kms driver.
I guess the same is for fbmem, but would be better to have confirmation since
amba-clcd I use has not been ported to drm/kms (yet), so I can't test.
> I haven't any errors but nothing is displayed unlike what I have when
> using current dma-mapping
> code.
> I guess the issue is coming from dma-noop where __get_free_pages() is
> used instead of alloc_pages()
> in dma-mapping.
Unless I've missed something bellow is a call stack for both
#1
__alloc_simple_buffer
__dma_alloc_buffer
alloc_pages
split_page
__dma_clear_buffer
memset
page_address
#2
__get_free_pages
alloc_pages
page_address
So the difference is that nommu case in dma-mapping.c memzeros memory, handles
DMA_ATTR_NO_KERNEL_MAPPING and does optimisation of memory usage.
Is something from above critical for your driver?
>
> Since my hardware doesn't have cache or MPU (and so use dma-noop) I
> haven't reserved specific memory region.
> Buffer addresses and vma parameters look correct... What could I have
> miss here ?
No ideas, sorry...
Cheers
Vladimir
>
> Benjamin
>
>>
>> [1] http://www.armlinux.org.uk/developer/patches/viewpatch.php?id=8633/1
>>
>> Vladimir Murzin (5):
>> dma: Add simple dma_noop_mmap
>> drivers: dma-coherent: Introduce default DMA pool
>> ARM: NOMMU: Introduce dma operations for noMMU
>> ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus
>> ARM: dma-mapping: Remove traces of NOMMU code
>>
>> .../bindings/reserved-memory/reserved-memory.txt | 3 +
>> arch/arm/include/asm/dma-mapping.h | 3 +-
>> arch/arm/mm/Kconfig | 2 +-
>> arch/arm/mm/Makefile | 5 +-
>> arch/arm/mm/dma-mapping-nommu.c | 252 +++++++++++++++++++++
>> arch/arm/mm/dma-mapping.c | 26 +--
>> drivers/base/dma-coherent.c | 59 ++++-
>> lib/dma-noop.c | 21 ++
>> 8 files changed, 335 insertions(+), 36 deletions(-)
>> create mode 100644 arch/arm/mm/dma-mapping-nommu.c
>>
>> --
>> 2.0.0
>>
>
>
>
^ permalink raw reply
* [PATCH 56/62] watchdog: tangox_wdt: Convert to use device managed functions
From: Uwe Kleine-König @ 2017-01-11 14:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <a45ed205-7c1b-a298-50c0-fc8b80a846c5@sigmadesigns.com>
On Wed, Jan 11, 2017 at 01:31:47PM +0100, Marc Gonzalez wrote:
> On 11/01/2017 11:52, Guenter Roeck wrote:
>
> > On 01/11/2017 01:07 AM, Marc Gonzalez wrote:
> >
> >>> @@ -134,12 +134,15 @@ static int tangox_wdt_probe(struct platform_device *pdev)
> >>> err = clk_prepare_enable(dev->clk);
> >>> if (err)
> >>> return err;
> >>> + err = devm_add_action_or_reset(&pdev->dev,
> >>> + (void(*)(void *))clk_disable_unprepare,
> >>> + dev->clk);
> >>> + if (err)
> >>> + return err;
This looks wrong. There is no clk_unprepare_disable when
devm_add_action_or_reset fails.
> >>
> >> Hello Guenter,
> >>
> >> I would rather avoid the function pointer cast.
> >> How about defining an auxiliary function for the cleanup action?
> >>
> >> clk_disable_unprepare() is static inline, so gcc will have to
> >> define an auxiliary function either way. What do you think?
> >
> > Not really. It would just make it more complicated to replace the
> > call with devm_clk_prepare_enable(), should it ever find its way
> > into the light of day.
>
> More complicated, because the cleanup function will have to be deleted later?
> The compiler will warn if someone forgets to do that.
>
> In my opinion, it's not a good idea to rely on the fact that casting
> void(*)(struct clk *clk) to void(*)(void *) is likely to work as expected
> on most platforms. (It has undefined behavior, strictly speaking.)
I would expect it to work on all (Linux) platforms. Anyhow, I wonder if
there couldn't be found a better solution.
If in the end it looks like the following that would be good I think:
clk = devm_clk_get(...);
if (IS_ERR(clk))
...
ret = devm_clk_prepare_enable(clk)
if (ret)
return ret;
...
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH v2 9/9] ARM: sunxi: Convert pinctrl nodes to generic bindings
From: Linus Walleij @ 2017-01-11 14:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170109111630.pcsjmc5l4v7vi2rm@lukather>
On Mon, Jan 9, 2017 at 12:16 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Fri, Jan 06, 2017 at 01:17:21AM +0000, Andr? Przywara wrote:
>> > On Wed, Jan 04, 2017 at 02:16:23AM +0000, Andr? Przywara wrote:
>> >> So can I ask that we start taking this seriously and stop doing things
>> >> which prevent Allwinner boards from being supported properly?
>> >> Which would first involve dropping this very patch?
>> >
>> > The driver still supports the old binding.
>>
>> Yes, a _current_ version of the driver supports both bindings, but older
>> versions *require* the older binding and bail out if various
>> allwinner,xxx properties are missing - as in those proposed new DTs:
>>
>> 4.9 kernel with sunxi/for-next .dtb:
>> sun8i-h3-pinctrl 1c20800.pinctrl: missing allwinner,function property in
>> node uart0
>> sun8i-h3-pinctrl 1c20800.pinctrl: missing allwinner,function property in
>> node mmc0
>> sunxi-mmc: probe of 1c0f000.mmc failed with error -22
>
> This is seriously getting out of control. We already come to great
> length (and sometimes a painful amount of hacks) to satisfy a few
> individuals with a theorical interest in backward compatibility (and
> apparently, we're even the only one doing so, even more platforms
> choosing to not support that as we speak), there's seriously no reason
> to support forward compatibility as well. This has *never* been a
> thing, never has been documented nor advertised, I don't know why it
> should be one more thing to carry on our shoulders.
I agree.
We have too much standardization burden to maintain already as it is.
And AFAICT the Allwinner support is a hacker/community/enthusiast
effort without vendor backing.
We should be aware that the strong push toward DT standardization
was due to mess in the vendor trees, and as for the ambition to ship
DTBs with products, that is for people producing products to do,
not for the community. Community support can very well use attached
DTB files on the kernel from my point of view, I don't see why
ArchLinuxARM and others should have to standardize and support
DTB file in flash images, very ambitious if they do but definately
not their problem.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v3 1/5] arm64: Define Falkor v1 CPU
From: Christopher Covington @ 2017-01-11 14:41 UTC (permalink / raw)
To: linux-arm-kernel
From: Shanker Donthineni <shankerd@codeaurora.org>
Define the MIDR implementer and part number field values for the Qualcomm
Datacenter Technologies Falkor processor version 1 in the usual manner.
Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
Signed-off-by: Christopher Covington <cov@codeaurora.org>
---
arch/arm64/include/asm/cputype.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 26a68dd..ee60561 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -71,6 +71,7 @@
#define ARM_CPU_IMP_APM 0x50
#define ARM_CPU_IMP_CAVIUM 0x43
#define ARM_CPU_IMP_BRCM 0x42
+#define ARM_CPU_IMP_QCOM 0x51
#define ARM_CPU_PART_AEM_V8 0xD0F
#define ARM_CPU_PART_FOUNDATION 0xD00
@@ -84,10 +85,13 @@
#define BRCM_CPU_PART_VULCAN 0x516
+#define QCOM_CPU_PART_FALKOR_V1 0x800
+
#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
+#define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1)
#ifndef __ASSEMBLY__
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora
Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH v3 2/5] arm64: Work around Falkor erratum 1003
From: Christopher Covington @ 2017-01-11 14:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170111144118.17062-1-cov@codeaurora.org>
From: Shanker Donthineni <shankerd@codeaurora.org>
On the Qualcomm Datacenter Technologies Falkor v1 CPU, memory accesses may
allocate TLB entries using an incorrect ASID when TTBRx_EL1 is being
updated. Changing the TTBRx_EL1[ASID] and TTBRx_EL1[BADDR] fields
separately using a reserved ASID will ensure that there are no TLB entries
with incorrect ASID after changing the the ASID.
Pseudo code:
write TTBRx_EL1[ASID] to a reserved value
ISB
write TTBRx_EL1[BADDR] to a desired value
ISB
write TTBRx_EL1[ASID] to a desired value
ISB
EL2 and EL3 code changing the EL1&0 ASID is not subject to this erratum
because hardware is prohibited from performing translations from an
out-of-context translation regime.
Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
Signed-off-by: Christopher Covington <cov@codeaurora.org>
---
Documentation/arm64/silicon-errata.txt | 43 +++++++++++++++++-----------------
arch/arm64/Kconfig | 11 +++++++++
arch/arm64/include/asm/cpucaps.h | 3 ++-
arch/arm64/include/asm/mmu_context.h | 8 ++++++-
arch/arm64/kernel/cpu_errata.c | 7 ++++++
arch/arm64/mm/context.c | 10 ++++++++
arch/arm64/mm/proc.S | 13 ++++++++++
7 files changed, 72 insertions(+), 23 deletions(-)
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 405da11..7151aed 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -42,24 +42,25 @@ file acts as a registry of software workarounds in the Linux Kernel and
will be updated when new workarounds are committed and backported to
stable kernels.
-| Implementor | Component | Erratum ID | Kconfig |
-+----------------+-----------------+-----------------+-------------------------+
-| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
-| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
-| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
-| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 |
-| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 |
-| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 |
-| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 |
-| ARM | Cortex-A57 | #852523 | N/A |
-| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
-| ARM | Cortex-A72 | #853709 | N/A |
-| ARM | MMU-500 | #841119,#826419 | N/A |
-| | | | |
-| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
-| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
-| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
-| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
-| Cavium | ThunderX SMMUv2 | #27704 | N/A |
-| | | | |
-| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
+| Implementor | Component | Erratum ID | Kconfig |
++---------------+-----------------+-----------------+--------------------------+
+| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
+| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
+| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
+| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 |
+| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 |
+| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 |
+| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 |
+| ARM | Cortex-A57 | #852523 | N/A |
+| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
+| ARM | Cortex-A72 | #853709 | N/A |
+| ARM | MMU-500 | #841119,#826419 | N/A |
+| | | | |
+| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
+| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
+| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
+| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
+| Cavium | ThunderX SMMUv2 | #27704 | N/A |
+| | | | |
+| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
+| Qualcomm | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1117421..2a80ac9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -479,6 +479,17 @@ config CAVIUM_ERRATUM_27456
If unsure, say Y.
+config QCOM_FALKOR_ERRATUM_1003
+ bool "Falkor E1003: Incorrect translation due to ASID change"
+ default y
+ help
+ An incorrect translation TLBI entry may be created while changing the
+ ASID and translation table address together for TTBR0_EL1. The
+ workaround for this issue is to use a reserved ASID in
+ cpu_do_switch_mm() before switching to the target ASID.
+
+ If unsure, say Y.
+
endmenu
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 4174f09..5aaf7ee 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -35,7 +35,8 @@
#define ARM64_HYP_OFFSET_LOW 14
#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
#define ARM64_HAS_NO_FPSIMD 16
+#define ARM64_WORKAROUND_QCOM_FALKOR_E1003 17
-#define ARM64_NCAPS 17
+#define ARM64_NCAPS 18
#endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 0363fe8..9632b05 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -19,6 +19,10 @@
#ifndef __ASM_MMU_CONTEXT_H
#define __ASM_MMU_CONTEXT_H
+#define FALKOR_RESERVED_ASID 1
+
+#ifndef __ASSEMBLY__
+
#include <linux/compiler.h>
#include <linux/sched.h>
@@ -220,4 +224,6 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
void verify_cpu_asid_bits(void);
-#endif
+#endif /* !__ASSEMBLY__ */
+
+#endif /* !__ASM_MMU_CONTEXT_H */
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index b75e917..787b542 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -130,6 +130,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
.def_scope = SCOPE_LOCAL_CPU,
.enable = cpu_enable_trap_ctr_access,
},
+#ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003
+ {
+ .desc = "Qualcomm Falkor erratum 1003",
+ .capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003,
+ MIDR_RANGE(MIDR_QCOM_FALKOR_V1, 0x00, 0x00),
+ },
+#endif
{
}
};
diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
index 4c63cb1..5a0a82a 100644
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -87,6 +87,11 @@ static void flush_context(unsigned int cpu)
/* Update the list of reserved ASIDs and the ASID bitmap. */
bitmap_clear(asid_map, 0, NUM_USER_ASIDS);
+ /* Reserve ASID for Falkor erratum 1003 */
+ if (IS_ENABLED(CONFIG_QCOM_FALKOR_ERRATUM_1003) &&
+ cpus_have_cap(ARM64_WORKAROUND_QCOM_FALKOR_E1003))
+ __set_bit(FALKOR_RESERVED_ASID, asid_map);
+
/*
* Ensure the generation bump is observed before we xchg the
* active_asids.
@@ -244,6 +249,11 @@ static int asids_init(void)
panic("Failed to allocate bitmap for %lu ASIDs\n",
NUM_USER_ASIDS);
+ /* Reserve ASID for Falkor erratum 1003 */
+ if (IS_ENABLED(CONFIG_QCOM_FALKOR_ERRATUM_1003) &&
+ cpus_have_cap(ARM64_WORKAROUND_QCOM_FALKOR_E1003))
+ __set_bit(FALKOR_RESERVED_ASID, asid_map);
+
pr_info("ASID allocator initialised with %lu entries\n", NUM_USER_ASIDS);
return 0;
}
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 32682be..9ee46df 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -23,6 +23,7 @@
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/hwcap.h>
+#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/pgtable-hwdef.h>
#include <asm/cpufeature.h>
@@ -140,6 +141,18 @@ ENDPROC(cpu_do_resume)
ENTRY(cpu_do_switch_mm)
mmid x1, x1 // get mm->context.id
bfi x0, x1, #48, #16 // set the ASID
+#ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003
+alternative_if ARM64_WORKAROUND_QCOM_FALKOR_E1003
+ mrs x2, ttbr0_el1
+ mov x3, #FALKOR_RESERVED_ASID
+ bfi x2, x3, #48, #16 // reserved ASID + old BADDR
+ msr ttbr0_el1, x2
+ isb
+ bfi x2, x0, #0, #48 // reserved ASID + new BADDR
+ msr ttbr0_el1, x2
+ isb
+alternative_else_nop_endif
+#endif
msr ttbr0_el1, x0 // set TTBR0
isb
post_ttbr0_update_workaround
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora
Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH v3 3/5] arm64: Create and use __tlbi_dsb() macros
From: Christopher Covington @ 2017-01-11 14:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170111144118.17062-1-cov@codeaurora.org>
This refactoring will allow an errata workaround that repeats tlbi dsb
sequences to only change one location. This is not intended to change the
generated assembly and comparison of before and after preprocessor output
of arch/arm64/mm/mmu.c and vmlinux objdump shows no functional changes.
Signed-off-by: Christopher Covington <cov@codeaurora.org>
---
arch/arm64/include/asm/tlbflush.h | 104 +++++++++++++++++++++++++-------------
1 file changed, 69 insertions(+), 35 deletions(-)
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index deab523..f28813c 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -25,22 +25,69 @@
#include <asm/cputype.h>
/*
- * Raw TLBI operations.
+ * Raw TLBI, DSB operations
*
- * Where necessary, use the __tlbi() macro to avoid asm()
- * boilerplate. Drivers and most kernel code should use the TLB
- * management routines in preference to the macro below.
+ * Where necessary, use __tlbi_*dsb() macros to avoid asm() boilerplate.
+ * Drivers and most kernel code should use the TLB management routines in
+ * preference to the macros below.
*
- * The macro can be used as __tlbi(op) or __tlbi(op, arg), depending
- * on whether a particular TLBI operation takes an argument or
- * not. The macros handles invoking the asm with or without the
- * register argument as appropriate.
+ * The __tlbi_dsb() macro handles invoking the asm without any register
+ * argument, with a single register argument, and with start (included)
+ * and end (excluded) range of register arguments. For example:
+ *
+ * __tlbi_dsb(op, attr)
+ *
+ * tlbi op
+ * dsb attr
+ *
+ * __tlbi_dsb(op, attr, addr)
+ *
+ * mov %[addr], =addr
+ * tlbi op, %[addr]
+ * dsb attr
+ *
+ * __tlbi_range_dsb(op, attr, start, end)
+ *
+ * mov %[arg], =start
+ * mov %[end], =end
+ * for:
+ * tlbi op, %[addr]
+ * add %[addr], %[addr], #(1 << (PAGE_SHIFT - 12))
+ * cmp %[addr], %[end]
+ * b.ne for
+ * dsb attr
*/
-#define __TLBI_0(op, arg) asm ("tlbi " #op)
-#define __TLBI_1(op, arg) asm ("tlbi " #op ", %0" : : "r" (arg))
-#define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg)
-#define __tlbi(op, ...) __TLBI_N(op, ##__VA_ARGS__, 1, 0)
+#define __TLBI_FOR_0(ig0, ig1, ig2)
+#define __TLBI_INSTR_0(op, ig1, ig2) "tlbi " #op
+#define __TLBI_IO_0(ig0, ig1, ig2) : :
+
+#define __TLBI_FOR_1(ig0, ig1, ig2)
+#define __TLBI_INSTR_1(op, ig0, ig1) "tlbi " #op ", %0"
+#define __TLBI_IO_1(ig0, arg, ig1) : : "r" (arg)
+
+#define __TLBI_FOR_2(ig0, start, ig1) unsigned long addr; \
+ for (addr = start; addr < end; \
+ addr += 1 << (PAGE_SHIFT - 12))
+#define __TLBI_INSTR_2(op, ig0, ig1) "tlbi " #op ", %0"
+#define __TLBI_IO_2(ig0, ig1, ig2) : : "r" (addr)
+
+#define __TLBI_FOR_N(op, a1, a2, n, ...) __TLBI_FOR_##n(op, a1, a2)
+#define __TLBI_INSTR_N(op, a1, a2, n, ...) __TLBI_INSTR_##n(op, a1, a2)
+#define __TLBI_IO_N(op, a1, a2, n, ...) __TLBI_IO_##n(op, a1, a2)
+
+#define __TLBI_FOR(op, ...) __TLBI_FOR_N(op, ##__VA_ARGS__, 2, 1, 0)
+#define __TLBI_INSTR(op, ...) __TLBI_INSTR_N(op, ##__VA_ARGS__, 2, 1, 0)
+#define __TLBI_IO(op, ...) __TLBI_IO_N(op, ##__VA_ARGS__, 2, 1, 0)
+
+#define __tlbi_asm_dsb(as, op, attr, ...) do { \
+ __TLBI_FOR(op, ##__VA_ARGS__) \
+ asm (__TLBI_INSTR(op, ##__VA_ARGS__) \
+ __TLBI_IO(op, ##__VA_ARGS__)); \
+ asm volatile ( as "\ndsb " #attr "\n" \
+ : : : "memory"); } while (0)
+
+#define __tlbi_dsb(...) __tlbi_asm_dsb("", ##__VA_ARGS__)
/*
* TLB Management
@@ -84,16 +131,14 @@
static inline void local_flush_tlb_all(void)
{
dsb(nshst);
- __tlbi(vmalle1);
- dsb(nsh);
+ __tlbi_dsb(vmalle1, nsh);
isb();
}
static inline void flush_tlb_all(void)
{
dsb(ishst);
- __tlbi(vmalle1is);
- dsb(ish);
+ __tlbi_dsb(vmalle1is, ish);
isb();
}
@@ -102,8 +147,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
unsigned long asid = ASID(mm) << 48;
dsb(ishst);
- __tlbi(aside1is, asid);
- dsb(ish);
+ __tlbi_dsb(aside1is, ish, asid);
}
static inline void flush_tlb_page(struct vm_area_struct *vma,
@@ -112,8 +156,7 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long addr = uaddr >> 12 | (ASID(vma->vm_mm) << 48);
dsb(ishst);
- __tlbi(vale1is, addr);
- dsb(ish);
+ __tlbi_dsb(vale1is, ish, addr);
}
/*
@@ -127,7 +170,6 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
bool last_level)
{
unsigned long asid = ASID(vma->vm_mm) << 48;
- unsigned long addr;
if ((end - start) > MAX_TLB_RANGE) {
flush_tlb_mm(vma->vm_mm);
@@ -138,13 +180,10 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
end = asid | (end >> 12);
dsb(ishst);
- for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12)) {
- if (last_level)
- __tlbi(vale1is, addr);
- else
- __tlbi(vae1is, addr);
- }
- dsb(ish);
+ if (last_level)
+ __tlbi_dsb(vale1is, ish, start, end);
+ else
+ __tlbi_dsb(vae1is, ish, start, end);
}
static inline void flush_tlb_range(struct vm_area_struct *vma,
@@ -155,8 +194,6 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
- unsigned long addr;
-
if ((end - start) > MAX_TLB_RANGE) {
flush_tlb_all();
return;
@@ -166,9 +203,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
end >>= 12;
dsb(ishst);
- for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12))
- __tlbi(vaae1is, addr);
- dsb(ish);
+ __tlbi_dsb(vaae1is, ish, start, end);
isb();
}
@@ -181,8 +216,7 @@ static inline void __flush_tlb_pgtable(struct mm_struct *mm,
{
unsigned long addr = uaddr >> 12 | (ASID(mm) << 48);
- __tlbi(vae1is, addr);
- dsb(ish);
+ __tlbi_dsb(vae1is, ish, addr);
}
#endif
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora
Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH v3 4/5] arm64: Use __tlbi_dsb() macros in KVM code
From: Christopher Covington @ 2017-01-11 14:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170111144118.17062-1-cov@codeaurora.org>
Refactor the KVM code to use the newly introduced __tlbi_dsb macros, which
will allow an errata workaround that repeats tlbi dsb sequences to only
change one location. This is not intended to change the generated assembly
and comparing before and after vmlinux objdump shows no functional changes.
Signed-off-by: Christopher Covington <cov@codeaurora.org>
---
arch/arm64/kvm/hyp/tlb.c | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
index 88e2f2b..9669e4b 100644
--- a/arch/arm64/kvm/hyp/tlb.c
+++ b/arch/arm64/kvm/hyp/tlb.c
@@ -16,6 +16,7 @@
*/
#include <asm/kvm_hyp.h>
+#include <asm/tlbflush.h>
void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
{
@@ -30,19 +31,15 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
* We could do so much better if we had the VA as well.
* Instead, we invalidate Stage-2 for this IPA, and the
* whole of Stage-1. Weep...
+ *
+ * We have to ensure completion of the invalidation at Stage-2 with a
+ * DSB, since a table walk on another CPU could refill a TLB with a
+ * complete (S1 + S2) walk based on the old Stage-2 mapping if the
+ * Stage-1 invalidation happened first.
*/
ipa >>= 12;
- asm volatile("tlbi ipas2e1is, %0" : : "r" (ipa));
-
- /*
- * We have to ensure completion of the invalidation at Stage-2,
- * since a table walk on another CPU could refill a TLB with a
- * complete (S1 + S2) walk based on the old Stage-2 mapping if
- * the Stage-1 invalidation happened first.
- */
- dsb(ish);
- asm volatile("tlbi vmalle1is" : : );
- dsb(ish);
+ __tlbi_dsb(ipas2e1is, ish, ipa);
+ __tlbi_dsb(vmalle1is, ish);
isb();
write_sysreg(0, vttbr_el2);
@@ -57,8 +54,7 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
write_sysreg(kvm->arch.vttbr, vttbr_el2);
isb();
- asm volatile("tlbi vmalls12e1is" : : );
- dsb(ish);
+ __tlbi_dsb(vmalls12e1is, ish);
isb();
write_sysreg(0, vttbr_el2);
@@ -72,8 +68,7 @@ void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
write_sysreg(kvm->arch.vttbr, vttbr_el2);
isb();
- asm volatile("tlbi vmalle1" : : );
- dsb(nsh);
+ __tlbi_dsb(vmalle1, nsh);
isb();
write_sysreg(0, vttbr_el2);
@@ -82,7 +77,5 @@ void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
void __hyp_text __kvm_flush_vm_context(void)
{
dsb(ishst);
- asm volatile("tlbi alle1is \n"
- "ic ialluis ": : );
- dsb(ish);
+ __tlbi_asm_dsb("ic ialluis", alle1is, ish);
}
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora
Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH v3 5/5] arm64: Work around Falkor erratum 1009
From: Christopher Covington @ 2017-01-11 14:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170111144118.17062-1-cov@codeaurora.org>
During a TLB invalidate sequence targeting the inner shareable
domain, Falkor may prematurely complete the DSB before all loads
and stores using the old translation are observed; instruction
fetches are not subject to the conditions of this erratum.
Signed-off-by: Christopher Covington <cov@codeaurora.org>
---
Documentation/arm64/silicon-errata.txt | 1 +
arch/arm64/Kconfig | 10 ++++++++++
arch/arm64/include/asm/cpucaps.h | 3 ++-
arch/arm64/include/asm/tlbflush.h | 5 ++++-
arch/arm64/kernel/cpu_errata.c | 7 +++++++
5 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 7151aed..98bef2a 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -64,3 +64,4 @@ stable kernels.
| | | | |
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
| Qualcomm | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
+| Qualcomm | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 2a80ac9..d13e903 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -490,6 +490,16 @@ config QCOM_FALKOR_ERRATUM_1003
If unsure, say Y.
+config QCOM_FALKOR_ERRATUM_1009
+ bool "Falkor E1009: Prematurely complete a DSB after a TLBI"
+ default y
+ help
+ Falkor CPU may prematurely complete a DSB following a TLBI xxIS
+ invalidate maintenance operations. Repeat the TLBI operation one
+ more time to fix the issue.
+
+ If unsure, say Y.
+
endmenu
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 5aaf7ee..55bcd02 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -36,7 +36,8 @@
#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
#define ARM64_HAS_NO_FPSIMD 16
#define ARM64_WORKAROUND_QCOM_FALKOR_E1003 17
+#define ARM64_WORKAROUND_REPEAT_TLBI 18
-#define ARM64_NCAPS 18
+#define ARM64_NCAPS 19
#endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index f28813c..7313cd3 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -85,7 +85,10 @@
asm (__TLBI_INSTR(op, ##__VA_ARGS__) \
__TLBI_IO(op, ##__VA_ARGS__)); \
asm volatile ( as "\ndsb " #attr "\n" \
- : : : "memory"); } while (0)
+ ALTERNATIVE("nop" "\nnop" "\n", \
+ __TLBI_INSTR(op, ##__VA_ARGS__) "\ndsb " #attr "\n", \
+ ARM64_WORKAROUND_REPEAT_TLBI) \
+ __TLBI_IO(op, ##__VA_ARGS__) : "memory"); } while (0)
#define __tlbi_dsb(...) __tlbi_asm_dsb("", ##__VA_ARGS__)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 787b542..e644364 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -137,6 +137,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_RANGE(MIDR_QCOM_FALKOR_V1, 0x00, 0x00),
},
#endif
+#ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009
+ {
+ .desc = "Qualcomm Falkor erratum 1009",
+ .capability = ARM64_WORKAROUND_REPEAT_TLBI,
+ MIDR_RANGE(MIDR_QCOM_FALKOR_V1, 0x00, 0x00),
+ },
+#endif
{
}
};
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora
Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH 56/62] watchdog: tangox_wdt: Convert to use device managed functions
From: Måns Rullgård @ 2017-01-11 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <a61eb838-4167-3032-bde8-3a8845b780f8@roeck-us.net>
Guenter Roeck <linux@roeck-us.net> writes:
> On 01/11/2017 04:31 AM, Marc Gonzalez wrote:
>> On 11/01/2017 11:52, Guenter Roeck wrote:
>>
>>> On 01/11/2017 01:07 AM, Marc Gonzalez wrote:
>>>
>>>>> @@ -134,12 +134,15 @@ static int tangox_wdt_probe(struct platform_device *pdev)
>>>>> err = clk_prepare_enable(dev->clk);
>>>>> if (err)
>>>>> return err;
>>>>> + err = devm_add_action_or_reset(&pdev->dev,
>>>>> + (void(*)(void *))clk_disable_unprepare,
>>>>> + dev->clk);
>>>>> + if (err)
>>>>> + return err;
>>>>
>>>> Hello Guenter,
>>>>
>>>> I would rather avoid the function pointer cast.
>>>> How about defining an auxiliary function for the cleanup action?
>>>>
>>>> clk_disable_unprepare() is static inline, so gcc will have to
>>>> define an auxiliary function either way. What do you think?
>>>
>>> Not really. It would just make it more complicated to replace the
>>> call with devm_clk_prepare_enable(), should it ever find its way
>>> into the light of day.
>>
>> More complicated, because the cleanup function will have to be deleted later?
>> The compiler will warn if someone forgets to do that.
>>
>> In my opinion, it's not a good idea to rely on the fact that casting
>> void(*)(struct clk *clk) to void(*)(void *) is likely to work as expected
>> on most platforms. (It has undefined behavior, strictly speaking.)
>>
> I do hear that you object to this code.
>
> However, I must admit that you completely lost me here. It is a cast from
> one function pointer to another, passed as argument to another function,
> with a secondary cast of its argument from a typed pointer to a void pointer.
> I don't think C permits for "undefined behavior, strictly speaking".
> Besides, that same mechanism is already used elsewhere, which is how I
> got the idea. Are you claiming that there are situations where it won't
> work ?
A pointer to void is interchangeable with any other pointer type. That
doesn't necessarily imply that pointers to functions taking arguments of
different pointer types (as we have here) are always compatible. I'd
have to read the C standard carefully to see if there's any such
promise, and I have other things to do right now. I am, however, not
aware of any ABI (certainly none used by Linux) where it would pose a
problem.
--
M?ns Rullg?rd
^ permalink raw reply
* [PATCHv3 3/5] pinctrl: mvebu: pinctrl driver for 98DX3236 SoC
From: Linus Walleij @ 2017-01-11 14:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170106041517.9589-4-chris.packham@alliedtelesis.co.nz>
On Fri, Jan 6, 2017 at 5:15 AM, Chris Packham
<chris.packham@alliedtelesis.co.nz> wrote:
> From: Kalyan Kinthada <kalyan.kinthada@alliedtelesis.co.nz>
>
> This pinctrl driver supports the 98DX3236, 98DX3336 and 98DX4251 SoCs
> from Marvell.
>
> Signed-off-by: Kalyan Kinthada <kalyan.kinthada@alliedtelesis.co.nz>
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
I am waiting for an ACK or comment from the maintainers on
this patch. Sebastian?
Yours,
Linus Walleij
^ permalink raw reply
* Unhandled level 2 translation fault (11) at 0x000000b8, esr 0x92000046, rpi3 (aarch64)
From: Catalin Marinas @ 2017-01-11 14:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170110121423.GF19960@e104818-lin.cambridge.arm.com>
On Tue, Jan 10, 2017 at 12:14:23PM +0000, Catalin Marinas wrote:
> On Mon, Jan 09, 2017 at 07:06:19PM +0100, Bas van Tiel wrote:
> > > I defined STACKSIZE to the kernel's SIGSTKSZ (16384) and it seems to run
> > > fine, though I'll leave it longer/overnight (on a Juno board). With the
> > > 4K signal stack it was crashing shortly after start.
> >
> > I tried the STACKSIZE of 16384 for both the RPI3 and the PINEA64 board
> > and still see the same behaviour of crashing. Sometimes the process
> > is also blocked for a long time before it crashes.
> >
> > Setting the interval to 200 usec [5 Khz] will help to crash it faster.
> >
> > To further isolate the issue I will create a kernel module (based on a
> > hrtimer) that will sent a periodic signal to the registered process
> > and execute the same sighandler logic to check if the problem is still
> > there.
>
> I lowered the interval to 100us (it was 100ms in the original file) and
> I can indeed trigger segfault easily on Juno. But it doesn't fail in the
> same way every time, I sometimes get permission fault, other times bad
> frame.
With 100us interval, it segfaults on x86 fairly quickly as well, so I
don't think it's a kernel issue.
--
Catalin
^ permalink raw reply
* [PATCH] arm64: avoid increasing DMA masks above what hardware supports
From: Robin Murphy @ 2017-01-11 14:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <09cac197-9e57-5d3e-e742-f29c00051813@cogentembedded.com>
On 11/01/17 13:41, Nikita Yushchenko wrote:
>> Yes, I think that ought to work, although the __iommu_setup_dma_ops()
>> call will still want a real size reflecting the default mask
>
> I see iommu_dma_ops do not define set_dma_mask.
>
> So what if setup was done for size reflecting one mask and then driver
> changes mask? Will things still operate correctly?
We've overridden dma_set_mask() at the function level, so it should
always apply regardless. Besides, none of the arm64 ops implement
.set_dma_mask anyway, so we could possibly drop the references to it
altogether.
Conversely, I suppose we could just implement said callback for
swiotlb_dma_ops and iommu_dma_ops with the parent_dma_mask-checking
function and drop the HAVE_ARCH_DMA_SET_MASK override instead. I'm not
sure which approach is preferable - the latter seems arguably cleaner in
isolation, but would also be less consistent with how the coherent mask
has to be handled. Ho hum.
Robin.
^ permalink raw reply
* [PATCH] rtc: armada38x: hide maybe-uninitialized warning
From: Arnd Bergmann @ 2017-01-11 14:50 UTC (permalink / raw)
To: linux-arm-kernel
The function is too complicated for gcc to realize that this variable
does eventually get initialized, causing a harmless warning:
drivers/rtc/rtc-armada38x.c: In function 'read_rtc_register_wa':
drivers/rtc/rtc-armada38x.c:131:25: warning: 'index_max' may be used uninitialized in this function [-Wmaybe-uninitialized]
This adds an explicit initializion at the start of the function.
I generally try to avoid that, but it seems appropriate here,
as we start out with max=0 as well.
Fixes: 61cffa2438e3 ("rtc: armada38x: Follow the new recommendation for errata implementation")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/rtc/rtc-armada38x.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index 6c9a2cbdc1a9..65e16965af7e 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -90,7 +90,7 @@ static void rtc_update_mbus_timing_params(struct armada38x_rtc *rtc)
static u32 read_rtc_register_wa(struct armada38x_rtc *rtc, u8 rtc_reg)
{
- int i, index_max, max = 0;
+ int i, index_max = 0, max = 0;
for (i = 0; i < SAMPLE_NR; i++) {
rtc->val_to_freq[i].value = readl(rtc->regs + rtc_reg);
--
2.9.0
^ permalink raw reply related
* [PATCH 56/62] watchdog: tangox_wdt: Convert to use device managed functions
From: Vladimir Zapolskiy @ 2017-01-11 14:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170111143917.hedhyfu6m5dopag7@pengutronix.de>
Hello Uwe,
On 01/11/2017 04:39 PM, Uwe Kleine-K?nig wrote:
> On Wed, Jan 11, 2017 at 01:31:47PM +0100, Marc Gonzalez wrote:
>> On 11/01/2017 11:52, Guenter Roeck wrote:
>>
>>> On 01/11/2017 01:07 AM, Marc Gonzalez wrote:
>>>
>>>>> @@ -134,12 +134,15 @@ static int tangox_wdt_probe(struct platform_device *pdev)
>>>>> err = clk_prepare_enable(dev->clk);
>>>>> if (err)
>>>>> return err;
>>>>> + err = devm_add_action_or_reset(&pdev->dev,
>>>>> + (void(*)(void *))clk_disable_unprepare,
>>>>> + dev->clk);
>>>>> + if (err)
>>>>> + return err;
>
> This looks wrong. There is no clk_unprepare_disable when
> devm_add_action_or_reset fails.
actually there is a call to clk_disable_unprepare() on error path, you may
take a look at devm_add_action_or_reset() implementation.
Your comment is valid for devm_add_action() function though, but it's not
the case here.
--
With best wishes,
Vladimir
^ permalink raw reply
* [PATCH 8/8] efi: Add EFI_SECURE_BOOT bit [ver #6]
From: Matt Fleming @ 2017-01-11 14:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <148120026820.5854.13036556358308461345.stgit@warthog.procyon.org.uk>
On Thu, 08 Dec, at 12:31:08PM, David Howells wrote:
> From: Josh Boyer <jwboyer@fedoraproject.org>
>
> UEFI machines can be booted in Secure Boot mode. Add a EFI_SECURE_BOOT bit
> that can be passed to efi_enabled() to find out whether secure boot is
> enabled.
>
> This will be used by the SysRq+x handler, registered by the x86 arch, to find
> out whether secure boot mode is enabled so that it can be disabled.
>
> Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
>
> arch/x86/kernel/setup.c | 15 +++++++++++++++
> include/linux/efi.h | 1 +
> 2 files changed, 16 insertions(+)
Before we add more efi.flags bits I'd like this series to include the
patch that makes use of EFI_SECURE_BOOT. Alternatively, you move this
last patch to a new series.
^ permalink raw reply
* [PATCH] arm64: assembler: make adr_l work in modules under KASLR
From: Ard Biesheuvel @ 2017-01-11 14:54 UTC (permalink / raw)
To: linux-arm-kernel
When CONFIG_RANDOMIZE_MODULE_REGION_FULL=y, the offset between loaded
modules and the core kernel may exceed 4 GB, putting symbols exported
by the core kernel out of the reach of the ordinary adrp/add instruction
pairs used to generate relative symbol references. So make the adr_l
macro emit a movz/movk sequence instead when executing in module context.
While at it, remove the pointless special case for the stack pointer.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/include/asm/assembler.h | 36 +++++++++++++++-----
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 446f6c46d4b1..3a4301163e04 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -164,22 +164,25 @@ lr .req x30 // link register
/*
* Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where
- * <symbol> is within the range +/- 4 GB of the PC.
+ * <symbol> is within the range +/- 4 GB of the PC when running
+ * in core kernel context. In module context, a movz/movk sequence
+ * is used, since modules may be loaded far away from the kernel
+ * when KASLR is in effect.
*/
/*
* @dst: destination register (64 bit wide)
* @sym: name of the symbol
- * @tmp: optional scratch register to be used if <dst> == sp, which
- * is not allowed in an adrp instruction
*/
- .macro adr_l, dst, sym, tmp=
- .ifb \tmp
+ .macro adr_l, dst, sym
+#ifndef MODULE
adrp \dst, \sym
add \dst, \dst, :lo12:\sym
- .else
- adrp \tmp, \sym
- add \dst, \tmp, :lo12:\sym
- .endif
+#else
+ movz \dst, #:abs_g3:\sym
+ movk \dst, #:abs_g2_nc:\sym
+ movk \dst, #:abs_g1_nc:\sym
+ movk \dst, #:abs_g0_nc:\sym
+#endif
.endm
/*
@@ -190,6 +193,7 @@ lr .req x30 // link register
* the address
*/
.macro ldr_l, dst, sym, tmp=
+#ifndef MODULE
.ifb \tmp
adrp \dst, \sym
ldr \dst, [\dst, :lo12:\sym]
@@ -197,6 +201,15 @@ lr .req x30 // link register
adrp \tmp, \sym
ldr \dst, [\tmp, :lo12:\sym]
.endif
+#else
+ .ifb \tmp
+ adr_l \dst, \sym
+ ldr \dst, [\dst]
+ .else
+ adr_l \tmp, \sym
+ ldr \dst, [\tmp]
+ .endif
+#endif
.endm
/*
@@ -206,8 +219,13 @@ lr .req x30 // link register
* while <src> needs to be preserved.
*/
.macro str_l, src, sym, tmp
+#ifndef MODULE
adrp \tmp, \sym
str \src, [\tmp, :lo12:\sym]
+#else
+ adr_l \tmp, \sym
+ str \src, [\tmp]
+#endif
.endm
/*
--
2.7.4
^ permalink raw reply related
* [PATCH 0/8] efi: Pass secure boot mode to kernel [ver #6]
From: Matt Fleming @ 2017-01-11 15:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <148120020832.5854.5448601415491330495.stgit@warthog.procyon.org.uk>
On Thu, 08 Dec, at 12:30:08PM, David Howells wrote:
>
> Here's a set of patches that can determine the secure boot state of the
> UEFI BIOS and pass that along to the main kernel image. This involves
> generalising ARM's efi_get_secureboot() function and making it mixed-mode
> safe.
This version looks OK to me apart from the couple of comments I made.
Ard, did you take a look? In particular some boot testing on ARM/arm64
would be useful. x86 boots fine in both regular and mixed mode but
I've only tested without Secure Boot enabled.
^ 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