Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/4] ARM: tegra: nyan: Use external control for bq24735 charger
From: Paul Kocialkowski @ 2016-09-21  7:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <90828c8d-e46d-0956-d6b3-e88fc90f3049@nvidia.com>

Le mercredi 21 septembre 2016 ? 08:30 +0100, Jon Hunter a ?crit?:
> On 20/09/16 19:02, Paul Kocialkowski wrote:
> > 
> > * PGP Signed by an unknown key
> > 
> > Le mardi 20 septembre 2016 ? 18:40 +0100, Jon Hunter a ?crit :
> > > 
> > > On 28/08/16 18:32, Paul Kocialkowski wrote:
> > > > 
> > > > ?
> > > > Nyan boards come with an embedded controller that controls when to
> > > > enable and disable the charge. Thus, it should not be left up to the
> > > > kernel to handle that.
> > > > ?
> > > > Using the ti,external-control property allows specifying this use-case.
> > > ?
> > > So the bq24735 is populated under the EC's 'i2c-tunnel' property which
> > > is there to specifically interface it's child devices to the host. So I
> > > am a bit confused why this is expose to the host if it should not be used?
> > 
> > Well, it needs to access the information in the read-only registers provided
> > by
> > the chip, which is allowed by the setup in place that you described.
> 
> Is this to expose the current state to the kernel so we can monitor the
> battery state?

Yes, that is correct.

> > However, the EC has its internal state machine that decides when to start
> > charging, etc and so should be the only one to write registers, to avoid
> > conflicts.
> > 
> > > 
> > > Again you may right and I did find the original series [0] for this
> > > which specifically references the Acer Chromebook that needs this.
> > > However, I am not sure why this was never populated? Is there any other
> > > history here?
> > 
> > I am also confused about why it wasn't applied earlier. However, the cros
> > kernel
> > is using the very same scheme.
> 
> Do you have a reference?

Sure thing, there's a similar commit for the dts[0] and one for the driver[1]
(which was already merged in mainline).

> > > What is the actual problem you see without making this change?
> > 
> > There is a risk of conflict (even though it's probably not that
> > significant),
> > given the low variety of possible cases here. The idea is simply to say that
> > the
> > EC is in charge and to let it do its job without interfering.
> > 
> > > 
> > > The original series states ...
> > > ?
> > > "On Acer Chromebook 13 (CB5-311) this module fails to load if the
> > > charger is not inserted, and will error when it is removed."
> > 
> > I'm confused about that comment. At this point (and with this patch), it
> > works
> > normally.
> 
> Ok, I think Thierry prefers to only apply fixes for problems that can be
> reproduced. Is there a simple way to check the battery status and
> charging status via say the sysfs? If I can test that this has no
> negative impact may be it is ok.

Sure, this is exported at: /sys/class/power_supply/bq24735 at 5-0009
Also, note that the power-supply next branch[2] has some more fixes for the
bq24735 driver.

Cheers,

[0]:?https://chromium.googlesource.com/chromiumos/third_party/kernel/+/e25a91f87af41e29012a4e2dd7a9ab725efd308e
[1]: https://chromium.googlesource.com/chromiumos/third_party/kernel/+/6b34e53d506b44f911d0fd246ccdc8b4e942e4ae
[2]: https://git.kernel.org/cgit/linux/kernel/git/sre/linux-power-supply.git/log/?h=for-next

-- 
Paul Kocialkowski, developer of low-level free software for embedded devices

Website: https://www.paulk.fr/
Coding blog: https://code.paulk.fr/
Git repositories: https://git.paulk.fr/ https://git.code.paulk.fr/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160921/be9788f1/attachment.sig>

^ permalink raw reply

* [PATCH] ARM: tegra: nyan: Enable GPU node and related supply
From: Jon Hunter @ 2016-09-21  7:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474395433.1215.23.camel@paulk.fr>


On 20/09/16 19:17, Paul Kocialkowski wrote:
> * PGP Signed by an unknown key
> 
> Le mardi 20 septembre 2016 ? 13:24 +0100, Jon Hunter a ?crit :
>> On 18/09/16 15:13, Paul Kocialkowski wrote:
>>>
>>> This enables the GPU node for tegra124 nyan boards, which is required to
>>> get graphics acceleration with nouveau on these devices.
>>>
>>> Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
>>> ---
>>>  arch/arm/boot/dts/tegra124-nyan.dtsi | 8 +++++++-
>>>  1 file changed, 7 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/boot/dts/tegra124-nyan.dtsi
>>> b/arch/arm/boot/dts/tegra124-nyan.dtsi
>>> index dab9509..225ca77 100644
>>> --- a/arch/arm/boot/dts/tegra124-nyan.dtsi
>>> +++ b/arch/arm/boot/dts/tegra124-nyan.dtsi
>>> @@ -42,6 +42,12 @@
>>>  		};
>>>  	};
>>>  
>>> +	gpu at 0,57000000 {
>>> +		status = "okay";
>>> +
>>> +		vdd-supply = <&vdd_gpu>;
>>> +	};
>>> +
>>>  	serial at 70006000 {
>>>  		/* Debug connector on the bottom of the board near SD card.
>>> */
>>>  		status = "okay";
>>> @@ -214,7 +220,7 @@
>>>  					regulator-always-on;
>>>  				};
>>>  
>>> -				sd6 {
>>> +				vdd_gpu: sd6 {
>>>  					regulator-name = "+VDD_GPU_AP";
>>>  					regulator-min-microvolt = <650000>;
>>>  					regulator-max-microvolt =
>>> <1200000>;
>>>
>>
>> Looks good to me. I see the following error when booting but looking at the
>> code appears to be benign. Thierry, Alex, is this normal/okay?
> 
> I have the same messages and asked Alexandre about them the other day. He told
> me that it looks normal.

Ok great. Hopefully, Alex can ACK then.

Cheers
Jon

-- 
nvpublic

^ permalink raw reply

* [PATCH v3 1/5] clk: at91: move slow clock controller clocks to sckc.c
From: Alexandre Belloni @ 2016-09-21  8:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160921000211.GH8319@codeaurora.org>

On 20/09/2016 at 17:02:11 -0700, Stephen Boyd wrote :
> On 09/20, Alexandre Belloni wrote:
> > Move all clocks related to the slow clock controller to sckc.c. This avoids
> > extern definitions and allows to remove sckc.h
> > 
> > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> > ---
> 
> Applied to clk-next
> 

Thanks for the fix!

> drivers/clk/at91/sckc.c:146:13:
> warning: symbol 'of_at91sam9x5_clk_slow_osc_setup' was not
> declared. Should it be static?
> drivers/clk/at91/sckc.c:260:13:
> warning: symbol 'of_at91sam9x5_clk_slow_rc_osc_setup' was not
> declared. Should it be static?
> drivers/clk/at91/sckc.c:359:13:
> warning: symbol 'of_at91sam9x5_clk_slow_setup' was not declared.
> Should it be static?
> 
> ----8<----
> diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
> index f6ed711af738..311956abf4aa 100644
> --- a/drivers/clk/at91/sckc.c
> +++ b/drivers/clk/at91/sckc.c
> @@ -143,8 +143,8 @@ at91_clk_register_slow_osc(void __iomem *sckcr,
>  	return hw;
>  }
>  
> -void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
> -					     void __iomem *sckcr)
> +static void __init
> +of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, void __iomem *sckcr)
>  {
>  	struct clk_hw *hw;
>  	const char *parent_name;
> @@ -257,8 +257,8 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr,
>  	return hw;
>  }
>  
> -void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
> -						void __iomem *sckcr)
> +static void __init
> +of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, void __iomem *sckcr)
>  {
>  	struct clk_hw *hw;
>  	u32 frequency = 0;
> @@ -356,8 +356,8 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr,
>  	return hw;
>  }
>  
> -void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
> -					 void __iomem *sckcr)
> +static void __init
> +of_at91sam9x5_clk_slow_setup(struct device_node *np, void __iomem *sckcr)
>  {
>  	struct clk_hw *hw;
>  	const char *parent_names[2];
> 
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH 1/2] phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function
From: Hans de Goede @ 2016-09-21  8:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <57E0BEDF.2020603@ti.com>

Hi,

On 09/20/2016 07:45 AM, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Sunday 18 September 2016 10:20 PM, Hans de Goede wrote:
>> The sunxi musb has a bug where sometimes it will generate a babble
>> error on device disconnect instead of a disconnect irq. When this
>> happens the musb-controller switches from host mode to device mode
>> (it clears MUSB_DEVCTL_SESSION and sets MUSB_DEVCTL_BDEVICE) and
>> gets stuck in this state.
>>
>> Clearing this requires reporting Vbus low for 200 or more ms, but
>> on some devices Vbus is simply always high (host-only mode, no Vbus
>> control). The phy-sun4i-usb code already has code to force a session
>> end for devices without Vbus control.
>>
>> This commit adds a sun4i_usb_phy_force_session_end() function exporting
>> this functionality to the sunxi-musb glue, so that it can force a session
>> end to fixup the stuck state after a babble error.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>  drivers/phy/phy-sun4i-usb.c       | 11 +++++++++++
>>  include/linux/phy/phy-sun4i-usb.h |  7 +++++++
>>  2 files changed, 18 insertions(+)
>>
>> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
>> index 43c0d98..06f4e11a 100644
>> --- a/drivers/phy/phy-sun4i-usb.c
>> +++ b/drivers/phy/phy-sun4i-usb.c
>> @@ -470,6 +470,17 @@ void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
>>  }
>>  EXPORT_SYMBOL_GPL(sun4i_usb_phy_set_squelch_detect);
>>
>> +void sun4i_usb_phy_force_session_end(struct phy *_phy)
>> +{
>> +	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>> +	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>> +
>> +	data->id_det = -1;
>> +	data->force_session_end = true;
>> +	queue_delayed_work(system_wq, &data->detect, 0);
>> +}
>> +EXPORT_SYMBOL_GPL(sun4i_usb_phy_force_session_end);
>
> Er.. one more export symbol :-(

Yes unfortunately we need one more to work around sunxi musb / phy bugs.

>> +
>>  static const struct phy_ops sun4i_usb_phy_ops = {
>>  	.init		= sun4i_usb_phy_init,
>>  	.exit		= sun4i_usb_phy_exit,
>> diff --git a/include/linux/phy/phy-sun4i-usb.h b/include/linux/phy/phy-sun4i-usb.h
>> index 50aed92..3bb773f 100644
>> --- a/include/linux/phy/phy-sun4i-usb.h
>> +++ b/include/linux/phy/phy-sun4i-usb.h
>> @@ -23,4 +23,11 @@
>>   */
>>  void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled);
>>
>> +/**
>> + * sun4i_usb_force_session_end() - Force the current session to end
>> + *				   by reporting VBus low for 200+ ms
>> + * @phy: reference to a sun4i usb phy
>> + */
>> +void sun4i_usb_phy_force_session_end(struct phy *phy);
>
> Should we include a static inline function if sun4i phy is not defined?

No, we're also not doing that for the already exported
sun4i_usb_phy_set_squelch_detect()

And it is not necessary since the only caller is drivers/usb/musb/sunxi.c,
and drivers/usb/musb/Kconfig has:

config USB_MUSB_SUNXI
         tristate "Allwinner (sunxi)"
         depends on PHY_SUN4I_USB

Regards,

Hans

^ permalink raw reply

* [PATCH V6 4/5] PCI: thunder: Enable ACPI PCI controller for ThunderX pass2.x silicon version
From: Tomasz Nowicki @ 2016-09-21  8:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160920130839.GA13855@localhost>

On 20.09.2016 15:08, Bjorn Helgaas wrote:
> On Tue, Sep 20, 2016 at 09:06:23AM +0200, Tomasz Nowicki wrote:
>> On 19.09.2016 17:45, Bjorn Helgaas wrote:
>>> On Fri, Sep 09, 2016 at 09:24:06PM +0200, Tomasz Nowicki wrote:
>>>> ThunderX PCIe controller to off-chip devices (so-called PEM) is not fully
>>>> compliant with ECAM standard. It uses non-standard configuration space
>>>> accessors (see pci_thunder_pem_ops) and custom configuration space granulation
>>>> (see bus_shift = 24). In order to access configuration space and
>>>> probe PEM as ACPI based PCI host controller we need to add MCFG quirk
>>>> infrastructure. This involves:
>>>> 1. Export PEM pci_thunder_pem_ops structure so it is visible to MCFG quirk
>>>>   code.
>>>> 2. New quirk entries for each PEM segment. Each contains platform IDs,
>>>>   mentioned pci_thunder_pem_ops and CFG resources.
>>>>
>>>> Quirk is considered for ThunderX silicon pass2.x only which is identified
>>>> via MCFG revision 1.
>>>
>>> Is it really the case that silicon pass2.x has MCFG revision 1, and
>>> silicon pass1.x has MCFG revision 2?  That just seems backwards.
>>
>> It is weird but silicon pass2.x is more common and it had MCFG
>> revision 1 from the beginning. Unless it is allowed to use MCFG
>> revision 0 ? Then we could use MCFG revision 0 for pass1.x
>
> There's no reason to avoid revision 0.  The question is really what
> firmware is already in the field.  We need to accommodate that.  We don't
> want a situation where kernel version X only works with firmware version Y,
> but kernel version X+1 only works with firmware version Y+1.

Yes I agree. We have already deployed the firmware where:
pass2.x has MCFG revision 1
pass1.x has MCFG revision 2
so we need to stick to this.

Thanks,
Tomasz

^ permalink raw reply

* [GIT PULL] ARM: mvebu: soc for v4.9 (#1)
From: Arnd Bergmann @ 2016-09-21  8:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87eg4e5xop.fsf@free-electrons.com>

On Tuesday, September 20, 2016 6:43:34 PM CEST Gregory CLEMENT wrote:
> 
> Do you mean board-wnr854t.c?

Yes.
 
> If it is the case then I can just drop the patch adding this file because
> the only things done in this file are about the PCI.

Ah, that's perfect. Just for more background, I think it shouldn't be too
hard to convert the existing orion5x PCI support into a proper host driver,
and I can assist anyone willing to work on this and test it.

I think the steps here would roughly be:

- change PCI (not PCIe) host initialization to call
  pci_scan_root_bus() directly, bypassing the pci_common_init
  logic
- move PCI code into a separate file
- change PCI code into a driver by adding platform_device based
  probing
- add DT support for that driver.

For the PCIe code, the obvious strategy is to replace it with
the existing pcie-mvebu driver, adding any missing parts
in the process.

	Arnd

^ permalink raw reply

* [PATCH] spi: atmel: use managed resource for gpio chip select
From: Geert Uytterhoeven @ 2016-09-21  8:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160921075528.14452-1-nicolas.ferre@atmel.com>

Hi Nicolas,

On Wed, Sep 21, 2016 at 9:55 AM, Nicolas Ferre <nicolas.ferre@atmel.com> wrote:
> Use the managed gpio CS pin request so that we avoid having trouble
> in the cleanup code.
> In fact, if module was configured with DT, cleanup code released
> invalid pin.  Since resource wasn't freed, module cannot be reinserted.
>
> Reported-by: Alexander Morozov <linux@meltdown.ru>
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
>  drivers/spi/spi-atmel.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
> index 8feac599e9ab..4e3f2345844a 100644
> --- a/drivers/spi/spi-atmel.c
> +++ b/drivers/spi/spi-atmel.c
> @@ -1248,7 +1248,8 @@ static int atmel_spi_setup(struct spi_device *spi)
>                         return -ENOMEM;
>
>                 if (as->use_cs_gpios) {
> -                       ret = gpio_request(npcs_pin, dev_name(&spi->dev));
> +                       ret = devm_gpio_request(&spi->dev,
> +                                               npcs_pin, dev_name(&spi->dev));

Note that spi_master.setup() can be called multiple times during the lifetime
of the spi_device.

>                         if (ret) {
>                                 kfree(asd);
>                                 return ret;
> @@ -1471,13 +1472,11 @@ static int atmel_spi_transfer_one_message(struct spi_master *master,
>  static void atmel_spi_cleanup(struct spi_device *spi)
>  {
>         struct atmel_spi_device *asd = spi->controller_state;
> -       unsigned                gpio = (unsigned long) spi->controller_data;
>
>         if (!asd)
>                 return;
>
>         spi->controller_state = NULL;
> -       gpio_free(gpio);
>         kfree(asd);
>  }

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [PATCH V7 0/6] thermal: bcm2835: add thermal driver
From: kernel at martin.sperl.org @ 2016-09-21  8:23 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Add a thermal driver for the TSENSE device of the bcm2835/6/7 SOC.

If the firmware enables the HW, then the configuration is not touched.
In case the firmware has not enabled the device, then we try to set
it up correctly (which unfortunately can not get tested).

It exposes temperature and a critical trip point
(using a hardcoded default of 80C or the temperature configured
in the control register by the firmware, which reads as
407C currently)

The calibrations are (potentially) different for bcm2835, bcm2836
and bcm2837 and can get selected by the compatible property
in the device tree.

The driver also exposes the registers via debugfs.

Possible future enhancements:
* the device has the ability to trigger interrupts on reaching
  the programmed critical temperature.
  I have no knowledge which interrupt could be responsible
  for this on the ARM side, so if we get to know which irq
  it is we can implement that.
  Instead the driver right now implements polling in 1 second intervals
* the device can also reset the HW after the trip point
  has been reached (also with some delay, so that corrective
  actions can get taken) - this is currently not enabled by the
  firmware, but could.
* we could define more trip points for THERMAL_TRIP_HOT
* make the trip point limits modifiable (ops.set_trip_temp)

Note:
  No support for 32-bit arm bcm2837, as there is no
  arch/arm/boot/dts/bcm2836.dtsi upstream as of now.
  64-bit arm support is not tested

Changelog:
 V1 -> V2: renamed dt-binding documentation file
       	   added specific settings depending on compatible
	   added trip point based on register
	   setting up ctrl-register if HW is not enabled by firmware
	     as per recommendation of Eric (untested)
	   check that clock frequency is in range
	     (1.9 - 5MHz - as per comment in clk-bcm2835.c)
 	   added driver to multi_v7_defconfig
 V2 -> V3: made a module in multi_v7_defconfig
           fixed typo in dt-binding document
 V3 -> V4: moved driver back to thermal (not using bcm sub-directory)
       	   set polling interval to 1second (was 0ms, so interrupt driven)
 V4 -> V5: use correct compatiblity for different soc versions in dt
       	   support ARM64 for bcm2837 in devicetree and defconfig
 V5 -> V6: incorporated changes recommended by Stefan Wahren
 V6 -> V7: removed depends on ARCH_BCM2836 || ARCH_BCM2837 in Kconfig

Martin Sperl (6):
  dt: bindings: add thermal device driver for bcm2835
  thermal: bcm2835: add thermal driver for bcm2835 soc
  ARM: bcm2835: dts: add thermal node to device-tree of bcm283x
  ARM64: bcm2835: dts: add thermal node to device-tree of bcm2837
  ARM: bcm2835: add thermal driver to default_config
  ARM64: bcm2835: add thermal driver to default_config

 .../bindings/thermal/brcm,bcm2835-thermal.txt      |  17 ++
 arch/arm/boot/dts/bcm2835.dtsi                     |   6 +
 arch/arm/boot/dts/bcm2836.dtsi                     |   6 +
 arch/arm/boot/dts/bcm283x.dtsi                     |   7 +
 arch/arm/configs/bcm2835_defconfig                 |   2 +
 arch/arm64/boot/dts/broadcom/bcm2837.dtsi          |   6 +
 arch/arm64/configs/defconfig                       |   1 +
 drivers/thermal/Kconfig                            |   8 +
 drivers/thermal/Makefile                           |   1 +
 drivers/thermal/bcm2835_thermal.c                  | 340 +++++++++++++++++++++
 10 files changed, 394 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
 create mode 100644 drivers/thermal/bcm2835_thermal.c

--
2.1.4

^ permalink raw reply

* [PATCH V7 1/6] dt: bindings: add thermal device driver for bcm2835
From: kernel at martin.sperl.org @ 2016-09-21  8:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474446227-1147-1-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel@martin.sperl.org>

Add dt-binding documentation for bcm2835 SOC thermal sensor.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Acked-by: Eric Anholt <eric@anholt.net>
Acked-by: Rob Herring <robh@kernel.org>

Changelog:
 V1 -> V2: renamed file to follow naming conventions
 V2 -> V3: removed 0x in node name

---
 .../bindings/thermal/brcm,bcm2835-thermal.txt           | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt

diff --git a/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
new file mode 100644
index 0000000..474531d
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
@@ -0,0 +1,17 @@
+Binding for Thermal Sensor driver for BCM2835 SoCs.
+
+Required parameters:
+-------------------
+
+compatible: 	should be one of: "brcm,bcm2835-thermal",
+		"brcm,bcm2836-thermal" or "brcm,bcm2837-thermal"
+reg:		Address range of the thermal registers.
+clocks: 	Phandle of the clock used by the thermal sensor.
+
+Example:
+
+thermal: thermal at 7e212000 {
+	compatible = "brcm,bcm2835-thermal";
+	reg = <0x7e212000 0x8>;
+	clocks = <&clocks BCM2835_CLOCK_TSENS>;
+};
-- 
2.1.4

^ permalink raw reply related

* [PATCH V7 2/6] thermal: bcm2835: add thermal driver for bcm2835 soc
From: kernel at martin.sperl.org @ 2016-09-21  8:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474446227-1147-1-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel@martin.sperl.org>

Add basic thermal driver for bcm2835 SOC.

This driver currently relies on the firmware setting up the
tsense HW block and does not set it up itself.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Acked-by: Eric Anholt <eric@anholt.net>
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>

ChangeLog:
 V1 -> V2: added specific settings depending on compatiblity
	   added trip point based on register
	   setting up ctrl-register if HW is not enabled by firmware
	     as per recommendation of Eric (untested)
	   check that clock frequency is in range
	     (1.9 - 5MHz - as per comment in clk-bcm2835.c)
 V2 -> V4: moved back to thermal (not using bcm sub-directory)
       	   set polling interval to 1second (was 0ms, so interrupt driven)
 V5 -> V6: added correct depends in KConfig
	   removed defined default for RESET_DELAY
	   removed obvious comments
	   clarify HW setup comments if not set up by FW already
	   move clk_prepare_enable to an earlier stage and add error handling
	   clarify warning when TS-clock runs out of recommended range
	   clk_disable_unprepare added in bcm2835_thermal_remove
	   added comment on recommended temperature ranges for SOC
 V6 -> V7: removed depends on ARCH_BCM2836 || ARCH_BCM2837 in Kconfig
---
 drivers/thermal/Kconfig           |   8 +
 drivers/thermal/Makefile          |   1 +
 drivers/thermal/bcm2835_thermal.c | 340 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 349 insertions(+)
 create mode 100644 drivers/thermal/bcm2835_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..1bc8b14 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -399,4 +399,12 @@ config GENERIC_ADC_THERMAL
 	  to this driver. This driver reports the temperature by reading ADC
 	  channel and converts it to temperature based on lookup table.
 
+config BCM2835_THERMAL
+	tristate "Thermal sensors on bcm2835 SoC"
+	depends on ARCH_BCM2835 || COMPILE_TEST
+	depends on HAS_IOMEM
+	depends on OF
+	help
+	  Support for thermal sensors on Broadcom bcm2835 SoCs.
+
 endif
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..c26343e 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -51,3 +51,4 @@ obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra/
 obj-$(CONFIG_HISI_THERMAL)     += hisi_thermal.o
 obj-$(CONFIG_MTK_THERMAL)	+= mtk_thermal.o
 obj-$(CONFIG_GENERIC_ADC_THERMAL)	+= thermal-generic-adc.o
+obj-$(CONFIG_BCM2835_THERMAL)	+= bcm2835_thermal.o
diff --git a/drivers/thermal/bcm2835_thermal.c b/drivers/thermal/bcm2835_thermal.c
new file mode 100644
index 0000000..3468c7b
--- /dev/null
+++ b/drivers/thermal/bcm2835_thermal.c
@@ -0,0 +1,340 @@
+/*
+ * Driver for Broadcom BCM2835 soc temperature sensor
+ *
+ * Copyright (C) 2016 Martin Sperl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/thermal.h>
+
+#define BCM2835_TS_TSENSCTL			0x00
+#define BCM2835_TS_TSENSSTAT			0x04
+
+#define BCM2835_TS_TSENSCTL_PRWDW		BIT(0)
+#define BCM2835_TS_TSENSCTL_RSTB		BIT(1)
+#define BCM2835_TS_TSENSCTL_CTRL_BITS		3
+#define BCM2835_TS_TSENSCTL_CTRL_SHIFT		2
+#define BCM2835_TS_TSENSCTL_CTRL_MASK		    \
+	GENMASK(BCM2835_TS_TSENSCTL_CTRL_BITS +     \
+		BCM2835_TS_TSENSCTL_CTRL_SHIFT - 1, \
+		BCM2835_TS_TSENSCTL_CTRL_SHIFT)
+#define BCM2835_TS_TSENSCTL_CTRL_DEFAULT	1
+#define BCM2835_TS_TSENSCTL_EN_INT		BIT(5)
+#define BCM2835_TS_TSENSCTL_DIRECT		BIT(6)
+#define BCM2835_TS_TSENSCTL_CLR_INT		BIT(7)
+#define BCM2835_TS_TSENSCTL_THOLD_SHIFT		8
+#define BCM2835_TS_TSENSCTL_THOLD_BITS		10
+#define BCM2835_TS_TSENSCTL_THOLD_MASK		     \
+	GENMASK(BCM2835_TS_TSENSCTL_THOLD_BITS +     \
+		BCM2835_TS_TSENSCTL_THOLD_SHIFT - 1, \
+		BCM2835_TS_TSENSCTL_THOLD_SHIFT)
+#define BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT	18
+#define BCM2835_TS_TSENSCTL_RSTDELAY_BITS	8
+#define BCM2835_TS_TSENSCTL_REGULEN		BIT(26)
+
+#define BCM2835_TS_TSENSSTAT_DATA_BITS		10
+#define BCM2835_TS_TSENSSTAT_DATA_SHIFT		0
+#define BCM2835_TS_TSENSSTAT_DATA_MASK		     \
+	GENMASK(BCM2835_TS_TSENSSTAT_DATA_BITS +     \
+		BCM2835_TS_TSENSSTAT_DATA_SHIFT - 1, \
+		BCM2835_TS_TSENSSTAT_DATA_SHIFT)
+#define BCM2835_TS_TSENSSTAT_VALID		BIT(10)
+#define BCM2835_TS_TSENSSTAT_INTERRUPT		BIT(11)
+
+struct bcm2835_thermal_info {
+	int offset;
+	int slope;
+	int trip_temp;
+};
+
+struct bcm2835_thermal_data {
+	const struct bcm2835_thermal_info *info;
+	void __iomem *regs;
+	struct clk *clk;
+	struct dentry *debugfsdir;
+};
+
+static int bcm2835_thermal_adc2temp(
+	const struct bcm2835_thermal_info *info, u32 adc)
+{
+	return info->offset + (adc * info->slope);
+}
+
+static int bcm2835_thermal_temp2adc(
+	const struct bcm2835_thermal_info *info, int temp)
+{
+	temp -= info->offset;
+	temp /= info->slope;
+
+	if (temp < 0)
+		temp = 0;
+	if (temp >= BIT(BCM2835_TS_TSENSSTAT_DATA_BITS))
+		temp = BIT(BCM2835_TS_TSENSSTAT_DATA_BITS) - 1;
+
+	return temp;
+}
+
+static int bcm2835_thermal_get_trip_type(
+	struct thermal_zone_device *tz, int trip,
+	enum thermal_trip_type *type)
+{
+	*type = THERMAL_TRIP_CRITICAL;
+	return 0;
+}
+
+static int bcm2835_thermal_get_trip_temp(
+	struct thermal_zone_device *tz, int trip, int *temp)
+{
+	struct bcm2835_thermal_data *data = tz->devdata;
+	u32 val = readl(data->regs + BCM2835_TS_TSENSCTL);
+
+	/* get the THOLD bits */
+	val &= BCM2835_TS_TSENSCTL_THOLD_MASK;
+	val >>= BCM2835_TS_TSENSCTL_THOLD_SHIFT;
+
+	/* if it is zero then use the info value */
+	if (val)
+		*temp = bcm2835_thermal_adc2temp(data->info, val);
+	else
+		*temp = data->info->trip_temp;
+
+	return 0;
+}
+
+static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz,
+				    int *temp)
+{
+	struct bcm2835_thermal_data *data = tz->devdata;
+	u32 val = readl(data->regs + BCM2835_TS_TSENSSTAT);
+
+	if (!(val & BCM2835_TS_TSENSSTAT_VALID))
+		return -EIO;
+
+	val &= BCM2835_TS_TSENSSTAT_DATA_MASK;
+
+	*temp = bcm2835_thermal_adc2temp(data->info, val);
+
+	return 0;
+}
+
+static const struct debugfs_reg32 bcm2835_thermal_regs[] = {
+	{
+		.name = "ctl",
+		.offset = 0
+	},
+	{
+		.name = "stat",
+		.offset = 4
+	}
+};
+
+static void bcm2835_thermal_debugfs(struct platform_device *pdev)
+{
+	struct thermal_zone_device *tz = platform_get_drvdata(pdev);
+	struct bcm2835_thermal_data *data = tz->devdata;
+	struct debugfs_regset32 *regset;
+
+	data->debugfsdir = debugfs_create_dir("bcm2835_thermal", NULL);
+	if (!data->debugfsdir)
+		return;
+
+	regset = devm_kzalloc(&pdev->dev, sizeof(*regset), GFP_KERNEL);
+	if (!regset)
+		return;
+
+	regset->regs = bcm2835_thermal_regs;
+	regset->nregs = ARRAY_SIZE(bcm2835_thermal_regs);
+	regset->base = data->regs;
+
+	debugfs_create_regset32("regset", S_IRUGO,
+				data->debugfsdir, regset);
+}
+
+static struct thermal_zone_device_ops bcm2835_thermal_ops  = {
+	.get_temp = bcm2835_thermal_get_temp,
+	.get_trip_temp = bcm2835_thermal_get_trip_temp,
+	.get_trip_type = bcm2835_thermal_get_trip_type,
+};
+
+static const struct of_device_id bcm2835_thermal_of_match_table[];
+static int bcm2835_thermal_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	struct thermal_zone_device *tz;
+	struct bcm2835_thermal_data *data;
+	struct resource *res;
+	int err;
+	u32 val;
+	unsigned long rate;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	match = of_match_device(bcm2835_thermal_of_match_table,
+				&pdev->dev);
+	if (!match)
+		return -EINVAL;
+	data->info = match->data;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	data->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(data->regs)) {
+		err = PTR_ERR(data->regs);
+		dev_err(&pdev->dev, "Could not get registers: %d\n", err);
+		return err;
+	}
+
+	data->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(data->clk)) {
+		err = PTR_ERR(data->clk);
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Could not get clk: %d\n", err);
+		return err;
+	}
+
+	err = clk_prepare_enable(data->clk);
+	if (err)
+		return err;
+
+	rate = clk_get_rate(data->clk);
+	if ((rate < 1920000) || (rate > 5000000))
+		dev_warn(&pdev->dev,
+			 "Clock %pCn running at %pCr Hz is outside of the recommended range: 1.92 to 5MHz\n",
+			 data->clk, data->clk);
+
+	/*
+	 * right now the FW does set up the HW-block, so we are not
+	 * touching the configuration registers.
+	 * But if the HW is not enabled, then set it up
+	 * using "sane" values used by the firmware right now.
+	 */
+	val = readl(data->regs + BCM2835_TS_TSENSCTL);
+	if (!(val & BCM2835_TS_TSENSCTL_RSTB)) {
+		/* the basic required flags */
+		val = (BCM2835_TS_TSENSCTL_CTRL_DEFAULT <<
+		       BCM2835_TS_TSENSCTL_CTRL_SHIFT) |
+		      BCM2835_TS_TSENSCTL_REGULEN;
+
+		/*
+		 * reset delay using the current firmware value of 14
+		 * - units of time are unknown.
+		 */
+		val |= (14 << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT);
+
+		/*  trip_adc value from info */
+		val |= bcm2835_thermal_temp2adc(data->info,
+						data->info->trip_temp) <<
+			BCM2835_TS_TSENSCTL_THOLD_SHIFT;
+
+		/* write the value back to the register as 2 steps */
+		writel(val, data->regs + BCM2835_TS_TSENSCTL);
+		val |= BCM2835_TS_TSENSCTL_RSTB;
+		writel(val, data->regs + BCM2835_TS_TSENSCTL);
+	}
+
+	/* register thermal zone with 1 trip point an 1s polling */
+	tz = thermal_zone_device_register("bcm2835_thermal",
+					  1, 0, data,
+					  &bcm2835_thermal_ops,
+					  NULL,
+					  0, 1000);
+	if (IS_ERR(tz)) {
+		clk_disable_unprepare(data->clk);
+		err = PTR_ERR(tz);
+		dev_err(&pdev->dev,
+			"Failed to register the thermal device: %d\n",
+			err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, tz);
+
+	bcm2835_thermal_debugfs(pdev);
+
+	return 0;
+}
+
+static int bcm2835_thermal_remove(struct platform_device *pdev)
+{
+	struct thermal_zone_device *tz = platform_get_drvdata(pdev);
+	struct bcm2835_thermal_data *data = tz->devdata;
+
+	debugfs_remove_recursive(data->debugfsdir);
+	thermal_zone_device_unregister(tz);
+	clk_disable_unprepare(data->clk);
+
+	return 0;
+}
+
+/*
+ * Note: as per Raspberry Foundation FAQ
+ * (https://www.raspberrypi.org/help/faqs/#performanceOperatingTemperature)
+ * the recommended temperature range for the SOC -40C to +85C
+ * so the trip limit is set to 80C.
+ * this applies to all the BCM283X SOC
+ */
+
+static const struct of_device_id bcm2835_thermal_of_match_table[] = {
+	{
+		.compatible = "brcm,bcm2835-thermal",
+		.data = &(struct bcm2835_thermal_info) {
+			.offset = 407000,
+			.slope = -538,
+			.trip_temp = 80000
+		}
+	},
+	{
+		.compatible = "brcm,bcm2836-thermal",
+		.data = &(struct bcm2835_thermal_info) {
+			.offset = 407000,
+			.slope = -538,
+			.trip_temp = 80000
+		}
+	},
+	{
+		.compatible = "brcm,bcm2837-thermal",
+		.data = &(struct bcm2835_thermal_info) {
+			/* the bcm2837 needs adjustment of +5C */
+			.offset = 407000 + 5000,
+			.slope = -538,
+			.trip_temp = 80000
+		}
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table);
+
+static struct platform_driver bcm2835_thermal_driver = {
+	.probe = bcm2835_thermal_probe,
+	.remove = bcm2835_thermal_remove,
+	.driver = {
+		.name = "bcm2835_thermal",
+		.of_match_table = bcm2835_thermal_of_match_table,
+	},
+};
+module_platform_driver(bcm2835_thermal_driver);
+
+MODULE_AUTHOR("Martin Sperl");
+MODULE_DESCRIPTION("Thermal driver for bcm2835 chip");
+MODULE_LICENSE("GPL");
-- 
2.1.4

^ permalink raw reply related

* [PATCH V7 3/6] ARM: bcm2835: dts: add thermal node to device-tree of bcm283x
From: kernel at martin.sperl.org @ 2016-09-21  8:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474446227-1147-1-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel@martin.sperl.org>

Add the node for the thermal sensor of the bcm2835-soc
to the device tree.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>

Changelog:
V1 -> V5: generic settings is shared in bcm283x.dtsi, but disabled
	  moved the compatible string to the SOC specific dtsi
            for arm and arm64
V5 -> V6: fix remove 0x prefix from thermal at 0x7e212000

Note: there is no arm/boot/dts/bcm2837.dtsi as of now,
      so the 32-bit rpi3 dt is not modified.
---
 arch/arm/boot/dts/bcm2835.dtsi | 6 ++++++
 arch/arm/boot/dts/bcm2836.dtsi | 6 ++++++
 arch/arm/boot/dts/bcm283x.dtsi | 7 +++++++
 3 files changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index a78759e..0890d97 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -23,3 +23,9 @@
 		};
 	};
 };
+
+/* enable thermal sensor with the correct compatible property set */
+&thermal {
+	compatible = "brcm,bcm2835-thermal";
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
index 9d0651d..519a44f 100644
--- a/arch/arm/boot/dts/bcm2836.dtsi
+++ b/arch/arm/boot/dts/bcm2836.dtsi
@@ -76,3 +76,9 @@
 	interrupt-parent = <&local_intc>;
 	interrupts = <8>;
 };
+
+/* enable thermal sensor with the correct compatible property set */
+&thermal {
+	compatible = "brcm,bcm2836-thermal";
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index b982522..d9acf21 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -186,6 +186,13 @@
 			interrupts = <2 14>; /* pwa1 */
 		};
 
+		thermal: thermal at 7e212000 {
+			compatible = "brcm,bcm2835-thermal";
+			reg = <0x7e212000 0x8>;
+			clocks = <&clocks BCM2835_CLOCK_TSENS>;
+			status = "disabled";
+		};
+
 		aux: aux at 0x7e215000 {
 			compatible = "brcm,bcm2835-aux";
 			#clock-cells = <1>;
-- 
2.1.4

^ permalink raw reply related

* [PATCH V7 4/6] ARM64: bcm2835: dts: add thermal node to device-tree of bcm2837
From: kernel at martin.sperl.org @ 2016-09-21  8:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474446227-1147-1-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel@martin.sperl.org>

Add the node for the thermal sensor of the bcm2837-soc
to the device tree.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 arch/arm64/boot/dts/broadcom/bcm2837.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
index f2a31d0..2b0cfc7 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
@@ -74,3 +74,9 @@
 	interrupt-parent = <&local_intc>;
 	interrupts = <8>;
 };
+
+/* enable thermal sensor with the correct compatible property set */
+&thermal {
+	compatible = "brcm,bcm2837-thermal";
+	status = "okay";
+};
-- 
2.1.4

^ permalink raw reply related

* [PATCH V7 5/6] ARM: bcm2835: add thermal driver to default_config
From: kernel at martin.sperl.org @ 2016-09-21  8:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474446227-1147-1-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel@martin.sperl.org>

Add the thermal driver to list of compiled modules
in the default config for bcm2835.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/configs/bcm2835_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index 79de828..4b89f4e 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -73,6 +73,8 @@ CONFIG_SPI_BCM2835=y
 CONFIG_SPI_BCM2835AUX=y
 CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_BCM2835_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_BCM2835_WDT=y
 CONFIG_DRM=y
-- 
2.1.4

^ permalink raw reply related

* [PATCH V7 6/6] ARM64: bcm2835: add thermal driver to default_config
From: kernel at martin.sperl.org @ 2016-09-21  8:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474446227-1147-1-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel@martin.sperl.org>

Add the thermal driver for bcm2837 to list of compiled modules
in the default config.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index eadf485..372f981 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -252,6 +252,7 @@ CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_ARM_SCPI=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
+CONFIG_BCM2835_THERMAL=y
 CONFIG_EXYNOS_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_RENESAS_WDT=y
-- 
2.1.4

^ permalink raw reply related

* [v12, 7/8] base: soc: introduce soc_device_match() interface
From: Peter Rosin @ 2016-09-21  8:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474444574.270880035@f136.i.mail.ru>

On 2016-09-21 09:56, Alexander Shiyan wrote:
>> ?????, 21 ???????? 2016, 9:57 +03:00 ?? Yangbo Lu <yangbo.lu@nxp.com>:
>>
>> From: Arnd Bergmann < arnd@arndb.de >
>>
>> We keep running into cases where device drivers want to know the exact
>> version of the a SoC they are currently running on. In the past, this has
>> usually been done through a vendor specific API that can be called by a
>> driver, or by directly accessing some kind of version register that is
>> not part of the device itself but that belongs to a global register area
>> of the chip.
> ...
>> +const struct soc_device_attribute *soc_device_match(
>> +const struct soc_device_attribute *matches)
>> +{
>> +int ret = 0;
>> +
>> +if (!matches)
>> +return NULL;
>> +
>> +while (!ret) {
>> +if (!(matches->machine || matches->family ||
>> +      matches->revision || matches->soc_id))
>> +break;
>> +ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches,
>> +       soc_device_match_one);
>> +if (!ret)
>> +matches++;
> 
> So, what happen if next "matches" (after increment) will be NULL?

A crash?

> I think you should use while(matches) at the start of this procedure.

*arrgh*

*If* matches wrap, you indeed have *big* problems. *Elsewhere*

Hint: Please read the review comments on the previous version of this
series [1] before commenting further.

Cheers,
Peter

[1] https://www.mail-archive.com/netdev at vger.kernel.org/msg126617.html

^ permalink raw reply

* [PATCH 1/4] ARM: tegra: nyan: Use proper IRQ type definitions
From: Paul Kocialkowski @ 2016-09-21  8:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <0ca614bf-4d27-9948-03e3-472d059f2153@nvidia.com>

Le mercredi 21 septembre 2016 ? 08:52 +0100, Jon Hunter a ?crit?:
> On 20/09/16 19:14, Paul Kocialkowski wrote:
> > 
> > * PGP Signed by an unknown key
> > 
> > Le mardi 20 septembre 2016 ? 18:15 +0100, Jon Hunter a ?crit :
> > > 
> > > On 28/08/16 18:32, Paul Kocialkowski wrote:
> > > > 
> > > > 
> > > > This switches a few interrupt definitions that were using
> > > > GPIO_ACTIVE_HIGH as IRQ type, which is invalid.
> > > 
> > > May be you are right, but this does not describe why this is invalid.
> > > Can you elaborate?
> > 
> > GPIO_ACTIVE_HIGH is simply not the right kind of define to use in the
> > "interrupts" devicetree property. Values provided there are understood as
> > IRQ_TYPE_ defines.
> 
> Right, but you are changing the type as GPIO_ACTIVE_HIGH = 0 and
> IRQ_TYPE_EDGE_FALLING = 2 and there is no comment about why this has
> been changed. It might be correct, but you need to explain it.

This actually makes the IRQ trigger values consistent with the drivers, that
define them regardless of devicetree anyway. The max98090 driver
has?IRQF_TRIGGER_FALLING and bq24735 has IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING.

This is really more of a cosmetic change, it doesn't impact actual use.

-- 
Paul Kocialkowski, developer of low-level free software for embedded devices

Website: https://www.paulk.fr/
Coding blog: https://code.paulk.fr/
Git repositories: https://git.paulk.fr/ https://git.code.paulk.fr/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160921/989111ff/attachment.sig>

^ permalink raw reply

* [RFC] irqchip/gic-v3: Implement suspend and resume callbacks
From: Lingutla Chandrasekhar @ 2016-09-21  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

Implement suspend and resume syscore_ops to disable and
enable non wake up capable interrupts.

When system enters suspend, enable only wakeup capable
interrupts. While resuming, enable previously enabled interrupts
and show triggered/pending interrupts.

Signed-off-by: Lingutla Chandrasekhar <clingutla@codeaurora.org>

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index ede5672..511a5a1 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -33,6 +33,7 @@
 #include <linux/irqchip/arm-gic-common.h>
 #include <linux/irqchip/arm-gic-v3.h>
 #include <linux/irqchip/irq-partition-percpu.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/cputype.h>
 #include <asm/exception.h>
@@ -57,6 +58,10 @@ struct gic_chip_data {
 	u32			nr_redist_regions;
 	unsigned int		irq_nr;
 	struct partition_desc	*ppi_descs[16];
+#ifdef CONFIG_PM
+	unsigned int wakeup_irqs[32];
+	unsigned int enabled_irqs[32];
+#endif
 };
 
 static struct gic_chip_data gic_data __read_mostly;
@@ -330,6 +335,81 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int gic_suspend(void)
+{
+	unsigned int i;
+	void __iomem *base = gic_data.dist_base;
+
+	for (i = 0; i * 32 < gic->irq_nr; i++) {
+		gic->enabled_irqs[i]
+			= readl_relaxed(base + GICD_ISENABLER + i * 4);
+		/* disable all of them */
+		writel_relaxed(0xffffffff, base + GICD_ICENABLER + i * 4);
+		/* enable the wakeup set */
+		writel_relaxed(gic->wakeup_irqs[i],
+			base + GICD_ISENABLER + i * 4);
+	}
+	return 0;
+}
+
+static void gic_show_pending(void)
+{
+	unsigned int i;
+	u32 enabled;
+	u32 pending[32];
+	void __iomem *base = gic_data.dist_base;
+
+	for (i = 0; i * 32 < gic->irq_nr; i++) {
+		enabled = readl_relaxed(base + GICD_ICENABLER + i * 4);
+		pending[i] = readl_relaxed(base + GICD_ISPENDR + i * 4);
+		pending[i] &= enabled;
+	}
+
+	for_each_set_bit(i, (unsigned long *)pending, gic->irq_nr) {
+		unsigned int irq = irq_find_mapping(gic->domain, i);
+		struct irq_desc *desc = irq_to_desc(irq);
+		const char *name = "null";
+
+		if (desc == NULL)
+			name = "stray irq";
+		else if (desc->action && desc->action->name)
+			name = desc->action->name;
+
+		pr_debug("Pending IRQ: %d [%s]\n", __func__, irq, name);
+	}
+}
+
+static void gic_resume(void)
+{
+	unsigned int i;
+	void __iomem *base = gic_data.dist_base;
+
+	gic_show_pending();
+
+	for (i = 0; i * 32 < gic->irq_nr; i++) {
+		/* disable all of them */
+		writel_relaxed(0xffffffff, base + GICD_ICENABLER + i * 4);
+		/* enable the enabled set */
+		writel_relaxed(gic->enabled_irqs[i],
+			base + GICD_ISENABLER + i * 4);
+	}
+}
+
+static struct syscore_ops gic_syscore_ops = {
+	.suspend = gic_suspend,
+	.resume = gic_resume,
+};
+
+static int __init gic_init_sys(void)
+{
+	register_syscore_ops(&gic_syscore_ops);
+	return 0;
+}
+device_initcall(gic_init_sys);
+
+#endif
+
 static u64 gic_mpidr_to_affinity(unsigned long mpidr)
 {
 	u64 aff;
@@ -666,6 +746,32 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 #define gic_smp_init()		do { } while(0)
 #endif
 
+#ifdef CONFIG_PM
+int gic_set_wake(struct irq_data *d, unsigned int on)
+{
+	int ret = -ENXIO;
+	unsigned int reg_offset, bit_offset;
+	unsigned int gicirq = gic_irq(d);
+	struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
+
+	/* per-cpu interrupts cannot be wakeup interrupts */
+	WARN_ON(gicirq < 32);
+
+	reg_offset = gicirq / 32;
+	bit_offset = gicirq % 32;
+
+	if (on)
+		gic_data->wakeup_irqs[reg_offset] |=  1 << bit_offset;
+	else
+		gic_data->wakeup_irqs[reg_offset] &=  ~(1 << bit_offset);
+
+	return ret;
+}
+
+#else
+#define gic_set_wake	NULL
+#endif
+
 #ifdef CONFIG_CPU_PM
 /* Check whether it's single security state view */
 static bool gic_dist_security_disabled(void)
@@ -707,6 +813,7 @@ static struct irq_chip gic_chip = {
 	.irq_eoi		= gic_eoi_irq,
 	.irq_set_type		= gic_set_type,
 	.irq_set_affinity	= gic_set_affinity,
+	.irq_set_wake           = gic_set_wake,
 	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
 	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
@@ -723,6 +830,7 @@ static struct irq_chip gic_eoimode1_chip = {
 	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
 	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
+	.irq_set_wake		= gic_set_wake,
 };
 
 #define GIC_ID_NR		(1U << gic_data.rdists.id_bits)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
 a Linux Foundation Collaborative Project.

^ permalink raw reply related

* [PATCH v2] arm64: kgdb: handle read-only text / modules
From: Mark Rutland @ 2016-09-21  8:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160921071955.21792-1-takahiro.akashi@linaro.org>

On Wed, Sep 21, 2016 at 04:19:55PM +0900, AKASHI Takahiro wrote:
> Handle read-only cases (CONFIG_DEBUG_RODATA/CONFIG_DEBUG_SET_MODULE_RONX)
> by using aarch64_insn_write() instead of probe_kernel_write().
> See how this works:
>     commit 2f896d586610 ("arm64: use fixmap for text patching")
> 
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Jason Wessel <jason.wessel@windriver.com>
> Cc: <stable@vger.kernel.org> # 3.18-3.19: 2f896d5: arm64: use fixmap
> Cc: <stable@vger.kernel.org> # 4.0-

For v3.18-v3.19, we also need commit f6242cac10427c54 ("arm64: Fix text
patching logic when using fixmap"), so as to not break the
!CONFIG_DEBUG_SET_MODULE_RONX case.

With that:

Reviewed-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

> ---
>  arch/arm64/include/asm/debug-monitors.h |  2 --
>  arch/arm64/kernel/kgdb.c                | 36 ++++++++++++++++++++++-----------
>  2 files changed, 24 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
> index 4b6b3f7..b71420a 100644
> --- a/arch/arm64/include/asm/debug-monitors.h
> +++ b/arch/arm64/include/asm/debug-monitors.h
> @@ -61,8 +61,6 @@
>  
>  #define AARCH64_BREAK_KGDB_DYN_DBG	\
>  	(AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5))
> -#define KGDB_DYN_BRK_INS_BYTE(x)	\
> -	((AARCH64_BREAK_KGDB_DYN_DBG >> (8 * (x))) & 0xff)
>  
>  #define CACHE_FLUSH_IS_SAFE		1
>  
> diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
> index 6732a27..b06a7a2 100644
> --- a/arch/arm64/kernel/kgdb.c
> +++ b/arch/arm64/kernel/kgdb.c
> @@ -19,6 +19,7 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include <linux/bug.h>
>  #include <linux/cpumask.h>
>  #include <linux/irq.h>
>  #include <linux/irq_work.h>
> @@ -26,6 +27,8 @@
>  #include <linux/kgdb.h>
>  #include <linux/kprobes.h>
>  #include <linux/percpu.h>
> +#include <asm/debug-monitors.h>
> +#include <asm/insn.h>
>  #include <asm/ptrace.h>
>  #include <asm/traps.h>
>  
> @@ -370,15 +373,24 @@ void kgdb_arch_exit(void)
>  	unregister_die_notifier(&kgdb_notifier);
>  }
>  
> -/*
> - * ARM instructions are always in LE.
> - * Break instruction is encoded in LE format
> - */
> -struct kgdb_arch arch_kgdb_ops = {
> -	.gdb_bpt_instr = {
> -		KGDB_DYN_BRK_INS_BYTE(0),
> -		KGDB_DYN_BRK_INS_BYTE(1),
> -		KGDB_DYN_BRK_INS_BYTE(2),
> -		KGDB_DYN_BRK_INS_BYTE(3),
> -	}
> -};
> +struct kgdb_arch arch_kgdb_ops;
> +
> +int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
> +{
> +	int err;
> +
> +	BUILD_BUG_ON(AARCH64_INSN_SIZE != BREAK_INSTR_SIZE);
> +
> +	err = aarch64_insn_read((void *)bpt->bpt_addr, (u32 *)bpt->saved_instr);
> +	if (err)
> +		return err;
> +
> +	return aarch64_insn_write((void *)bpt->bpt_addr,
> +			(u32)AARCH64_BREAK_KGDB_DYN_DBG);
> +}
> +
> +int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
> +{
> +	return aarch64_insn_write((void *)bpt->bpt_addr,
> +			*(u32 *)bpt->saved_instr);
> +}
> -- 
> 2.10.0
> 

^ permalink raw reply

* [GIT PULL] Allwinner late DT changes for 4.9
From: Maxime Ripard @ 2016-09-21  8:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd, Olof, Kevin,

This is a late (and last) PR for the Allwinner device trees.

It comes on top of the previous one (so it still has the dependency in
the clock changes).

Let me know if you have any questions,
Maxime

The following changes since commit 7a988a4dd29a8cfcf405a12441533d765d25a6b8:

  ARM: dts: gr8: Add support for the GR8 evaluation board (2016-09-11 22:23:17 +0200)

are available in the git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git tags/sunxi-dt-for-4.9-3

for you to fetch changes up to 90cb4b8c7e3af989c78227954e01455fc7c1e767:

  ARM: dts: sun8i: Add accelerometer to polaroid-mid2407pxe03 (2016-09-21 11:48:09 +0300)

----------------------------------------------------------------
Allwinner DT changes for 4.9, late edition

Here is a bunch of late changes for the 4.9 merge window, mostly:
  - Added a bunch of touchscreens nodes to tablets
  - Added support for the AXP806 PMIC found in the A80 boards
  - Enabled a few pinmux options for the H3

----------------------------------------------------------------
Chen-Yu Tsai (5):
      ARM: dts: sun9i: a80-optimus: Declare AXP809 SW regulator as unused
      ARM: dts: sun9i: cubieboard4: Declare AXP809 SW regulator as unused
      ARM: dts: sun9i: a80-optimus: Add AXP806 PMIC device node and regulators
      ARM: dts: sun9i: cubieboard4: Add AXP806 PMIC device node and regulators
      ARM: dts: sun9i: a80-optimus: Disable EHCI1

Hans de Goede (6):
      ARM: dts: sun8i: Add touchscreen node for sun8i-a23-gt90h
      ARM: dts: sun8i: Add touchscreen node for sun8i-a23-inet86dz
      ARM: dts: sun8i: Add touchscreen node for sun8i-a23-polaroid-mid2407pxe03
      ARM: dts: sun8i: Add touchscreen node for sun8i-a23-polaroid-mid2809pxe04
      ARM: dts: sun8i: Add touchscreen node for sun8i-a33-ga10h
      ARM: dts: sun8i: Add accelerometer to polaroid-mid2407pxe03

Icenowy Zheng (2):
      ARM: dts: sun8i: add pinmux for UART1 at PG
      ARM: dts: sun8i: enable UART1 for iNet D978 Rev2 board

Jorik Jonker (5):
      dts: sun8i-h3: add pinmux definitions for UART2-3
      dts: sun8i-h3: split off RTS/CTS for UART1 in seperate pinmux
      dts: sun8i-h3: associate exposed UARTs on Orange Pi Boards
      dts: sun8i-h3: add pinmux definitions for I2C0-2
      dts: sun8i-h3: add I2C0-2 peripherals to H3 SOC

 arch/arm/boot/dts/sun8i-a23-a33.dtsi               |  10 ++
 arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts           |   9 ++
 arch/arm/boot/dts/sun8i-a23-inet86dz.dts           |   9 ++
 .../boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts   |  26 +++++
 .../boot/dts/sun8i-a23-polaroid-mid2809pxe04.dts   |   9 ++
 arch/arm/boot/dts/sun8i-a33-ga10h-v1.1.dts         |  10 ++
 arch/arm/boot/dts/sun8i-a33-inet-d978-rev2.dts     |  20 ++++
 arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts    |   2 +-
 arch/arm/boot/dts/sun8i-h3-orangepi-2.dts          |  18 +++
 arch/arm/boot/dts/sun8i-h3-orangepi-one.dts        |  18 +++
 arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts         |  18 +++
 arch/arm/boot/dts/sun8i-h3.dtsi                    |  85 +++++++++++++-
 arch/arm/boot/dts/sun9i-a80-cubieboard4.dts        | 116 +++++++++++++++++++
 arch/arm/boot/dts/sun9i-a80-optimus.dts            | 123 ++++++++++++++++++++-
 14 files changed, 468 insertions(+), 5 deletions(-)

-- 
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: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160921/3be903f5/attachment.sig>

^ permalink raw reply

* [PATCH v3 0/3] Armada 7k/8k CP110 system controller fixes
From: Marcin Wojtas @ 2016-09-21  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Here is the third version of the patchset adding fixes to CP110
system controller clock driver. Comparing to v2, the only change
is return value on alloc failures.

Any feedback would be very welcome.

Best regards,
Marcin

Changelog:
v3 -> v2
* return -ENOMEM on alloc failures

v1 -> v2
* replace setting CLK_IS_BASIC flag with clearing init structure fields
  with memset
* minor improvements of allocation and error checking
* add migration to clk_hw


Marcin Wojtas (3):
  clk: mvebu: fix setting unwanted flags in CP110 gate clock
  clk: mvebu: dynamically allocate resources in Armada CP110 system
    controller
  clk: mvebu: migrate CP110 system controller to clk_hw API and
    registration

 drivers/clk/mvebu/cp110-system-controller.c | 155 +++++++++++++++-------------
 1 file changed, 81 insertions(+), 74 deletions(-)

-- 
1.8.3.1

^ permalink raw reply

* [PATCH v3 1/3] clk: mvebu: fix setting unwanted flags in CP110 gate clock
From: Marcin Wojtas @ 2016-09-21  9:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474448759-24482-1-git-send-email-mw@semihalf.com>

Armada CP110 system controller comprises its own routine responsble
for registering gate clocks. Among others 'flags' field in
struct clk_init_data was not set, using a random values, which
may cause an unpredicted behavior.

This patch fixes the problem by resetting all fields of clk_init_data
before assigning values for all gated clocks of Armada 7k/8k SoCs family.

Fixes: d3da3eaef7f4 ("clk: mvebu: new driver for Armada CP110 system ...")
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
CC: <stable@vger.kernel.org>
---
 drivers/clk/mvebu/cp110-system-controller.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index 7fa42d6..59fe76e 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -142,6 +142,8 @@ static struct clk *cp110_register_gate(const char *name,
 	if (!gate)
 		return ERR_PTR(-ENOMEM);
 
+	memset(&init, 0, sizeof(init));
+
 	init.name = name;
 	init.ops = &cp110_gate_ops;
 	init.parent_names = &parent_name;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v3 2/3] clk: mvebu: dynamically allocate resources in Armada CP110 system controller
From: Marcin Wojtas @ 2016-09-21  9:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474448759-24482-1-git-send-email-mw@semihalf.com>

Original commit, which added support for Armada CP110 system controller
used global variables for storing all clock information. It worked
fine for Armada 7k SoC, with single CP110 block. After dual-CP110 Armada 8k
was introduced, the data got overwritten and corrupted.

This patch fixes the issue by allocating resources dynamically in the
driver probe and storing it as platform drvdata.

Fixes: d3da3eaef7f4 ("clk: mvebu: new driver for Armada CP110 system ...")
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
CC: <stable@vger.kernel.org>
---
 drivers/clk/mvebu/cp110-system-controller.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index 59fe76e..f2303da 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -81,13 +81,6 @@ enum {
 #define CP110_GATE_EIP150		25
 #define CP110_GATE_EIP197		26
 
-static struct clk *cp110_clks[CP110_CLK_NUM];
-
-static struct clk_onecell_data cp110_clk_data = {
-	.clks = cp110_clks,
-	.clk_num = CP110_CLK_NUM,
-};
-
 struct cp110_gate_clk {
 	struct clk_hw hw;
 	struct regmap *regmap;
@@ -196,7 +189,8 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
 	struct regmap *regmap;
 	struct device_node *np = pdev->dev.of_node;
 	const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name;
-	struct clk *clk;
+	struct clk_onecell_data *cp110_clk_data;
+	struct clk *clk, **cp110_clks;
 	u32 nand_clk_ctrl;
 	int i, ret;
 
@@ -209,6 +203,20 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	cp110_clks = devm_kcalloc(&pdev->dev, sizeof(struct clk *),
+				  CP110_CLK_NUM, GFP_KERNEL);
+	if (!cp110_clks)
+		return -ENOMEM;
+
+	cp110_clk_data = devm_kzalloc(&pdev->dev,
+				      sizeof(*cp110_clk_data),
+				      GFP_KERNEL);
+	if (!cp110_clk_data)
+		return -ENOMEM;
+
+	cp110_clk_data->clks = cp110_clks;
+	cp110_clk_data->clk_num = CP110_CLK_NUM;
+
 	/* Register the APLL which is the root of the clk tree */
 	of_property_read_string_index(np, "core-clock-output-names",
 				      CP110_CORE_APLL, &apll_name);
@@ -336,10 +344,12 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
 		cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk;
 	}
 
-	ret = of_clk_add_provider(np, cp110_of_clk_get, &cp110_clk_data);
+	ret = of_clk_add_provider(np, cp110_of_clk_get, cp110_clk_data);
 	if (ret)
 		goto fail_clk_add;
 
+	platform_set_drvdata(pdev, cp110_clks);
+
 	return 0;
 
 fail_clk_add:
@@ -366,6 +376,7 @@ fail0:
 
 static int cp110_syscon_clk_remove(struct platform_device *pdev)
 {
+	struct clk **cp110_clks = platform_get_drvdata(pdev);
 	int i;
 
 	of_clk_del_provider(pdev->dev.of_node);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v3 3/3] clk: mvebu: migrate CP110 system controller to clk_hw API and registration
From: Marcin Wojtas @ 2016-09-21  9:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474448759-24482-1-git-send-email-mw@semihalf.com>

Now that we have clk_hw based provider APIs to register clks, we
can get rid of struct clk pointers while registering clks in Armada
CP110 system controller driver. This commit introduces new
API and registration for all clocks in CP110 HW blocks.

Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
 drivers/clk/mvebu/cp110-system-controller.c | 150 +++++++++++++---------------
 1 file changed, 72 insertions(+), 78 deletions(-)

diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index f2303da..842bddd 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -87,7 +87,7 @@ struct cp110_gate_clk {
 	u8 bit_idx;
 };
 
-#define to_cp110_gate_clk(clk) container_of(clk, struct cp110_gate_clk, hw)
+#define to_cp110_gate_clk(hw) container_of(hw, struct cp110_gate_clk, hw)
 
 static int cp110_gate_enable(struct clk_hw *hw)
 {
@@ -123,13 +123,14 @@ static const struct clk_ops cp110_gate_ops = {
 	.is_enabled = cp110_gate_is_enabled,
 };
 
-static struct clk *cp110_register_gate(const char *name,
-				       const char *parent_name,
-				       struct regmap *regmap, u8 bit_idx)
+static struct clk_hw *cp110_register_gate(const char *name,
+					  const char *parent_name,
+					  struct regmap *regmap, u8 bit_idx)
 {
 	struct cp110_gate_clk *gate;
-	struct clk *clk;
+	struct clk_hw *hw;
 	struct clk_init_data init;
+	int ret;
 
 	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
 	if (!gate)
@@ -146,39 +147,37 @@ static struct clk *cp110_register_gate(const char *name,
 	gate->bit_idx = bit_idx;
 	gate->hw.init = &init;
 
-	clk = clk_register(NULL, &gate->hw);
-	if (IS_ERR(clk))
+	hw = &gate->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
 		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
 
-	return clk;
+	return hw;
 }
 
-static void cp110_unregister_gate(struct clk *clk)
+static void cp110_unregister_gate(struct clk_hw *hw)
 {
-	struct clk_hw *hw;
-
-	hw = __clk_get_hw(clk);
-	if (!hw)
-		return;
-
-	clk_unregister(clk);
+	clk_hw_unregister(hw);
 	kfree(to_cp110_gate_clk(hw));
 }
 
-static struct clk *cp110_of_clk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec,
+				       void *data)
 {
-	struct clk_onecell_data *clk_data = data;
+	struct clk_hw_onecell_data *clk_data = data;
 	unsigned int type = clkspec->args[0];
 	unsigned int idx = clkspec->args[1];
 
 	if (type == CP110_CLK_TYPE_CORE) {
 		if (idx > CP110_MAX_CORE_CLOCKS)
 			return ERR_PTR(-EINVAL);
-		return clk_data->clks[idx];
+		return clk_data->hws[idx];
 	} else if (type == CP110_CLK_TYPE_GATABLE) {
 		if (idx > CP110_MAX_GATABLE_CLOCKS)
 			return ERR_PTR(-EINVAL);
-		return clk_data->clks[CP110_MAX_CORE_CLOCKS + idx];
+		return clk_data->hws[CP110_MAX_CORE_CLOCKS + idx];
 	}
 
 	return ERR_PTR(-EINVAL);
@@ -189,8 +188,8 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
 	struct regmap *regmap;
 	struct device_node *np = pdev->dev.of_node;
 	const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name;
-	struct clk_onecell_data *cp110_clk_data;
-	struct clk *clk, **cp110_clks;
+	struct clk_hw_onecell_data *cp110_clk_data;
+	struct clk_hw *hw, **cp110_clks;
 	u32 nand_clk_ctrl;
 	int i, ret;
 
@@ -203,80 +202,75 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	cp110_clks = devm_kcalloc(&pdev->dev, sizeof(struct clk *),
-				  CP110_CLK_NUM, GFP_KERNEL);
-	if (!cp110_clks)
-		return -ENOMEM;
-
-	cp110_clk_data = devm_kzalloc(&pdev->dev,
-				      sizeof(*cp110_clk_data),
+	cp110_clk_data = devm_kcalloc(&pdev->dev, sizeof(*cp110_clk_data),
+				      sizeof(struct clk_hw *) * CP110_CLK_NUM,
 				      GFP_KERNEL);
 	if (!cp110_clk_data)
 		return -ENOMEM;
 
-	cp110_clk_data->clks = cp110_clks;
-	cp110_clk_data->clk_num = CP110_CLK_NUM;
+	cp110_clks = cp110_clk_data->hws;
+	cp110_clk_data->num = CP110_CLK_NUM;
 
-	/* Register the APLL which is the root of the clk tree */
+	/* Register the APLL which is the root of the hw tree */
 	of_property_read_string_index(np, "core-clock-output-names",
 				      CP110_CORE_APLL, &apll_name);
-	clk = clk_register_fixed_rate(NULL, apll_name, NULL, 0,
-				      1000 * 1000 * 1000);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
+	hw = clk_hw_register_fixed_rate(NULL, apll_name, NULL, 0,
+					1000 * 1000 * 1000);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
 		goto fail0;
 	}
 
-	cp110_clks[CP110_CORE_APLL] = clk;
+	cp110_clks[CP110_CORE_APLL] = hw;
 
 	/* PPv2 is APLL/3 */
 	of_property_read_string_index(np, "core-clock-output-names",
 				      CP110_CORE_PPV2, &ppv2_name);
-	clk = clk_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
+	hw = clk_hw_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
 		goto fail1;
 	}
 
-	cp110_clks[CP110_CORE_PPV2] = clk;
+	cp110_clks[CP110_CORE_PPV2] = hw;
 
 	/* EIP clock is APLL/2 */
 	of_property_read_string_index(np, "core-clock-output-names",
 				      CP110_CORE_EIP, &eip_name);
-	clk = clk_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
+	hw = clk_hw_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
 		goto fail2;
 	}
 
-	cp110_clks[CP110_CORE_EIP] = clk;
+	cp110_clks[CP110_CORE_EIP] = hw;
 
 	/* Core clock is EIP/2 */
 	of_property_read_string_index(np, "core-clock-output-names",
 				      CP110_CORE_CORE, &core_name);
-	clk = clk_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
+	hw = clk_hw_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
 		goto fail3;
 	}
 
-	cp110_clks[CP110_CORE_CORE] = clk;
+	cp110_clks[CP110_CORE_CORE] = hw;
 
 	/* NAND can be either APLL/2.5 or core clock */
 	of_property_read_string_index(np, "core-clock-output-names",
 				      CP110_CORE_NAND, &nand_name);
 	if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
-		clk = clk_register_fixed_factor(NULL, nand_name,
-						apll_name, 0, 2, 5);
+		hw = clk_hw_register_fixed_factor(NULL, nand_name,
+						   apll_name, 0, 2, 5);
 	else
-		clk = clk_register_fixed_factor(NULL, nand_name,
-						core_name, 0, 1, 1);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
+		hw = clk_hw_register_fixed_factor(NULL, nand_name,
+						   core_name, 0, 1, 1);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
 		goto fail4;
 	}
 
-	cp110_clks[CP110_CORE_NAND] = clk;
+	cp110_clks[CP110_CORE_NAND] = hw;
 
 	for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) {
 		const char *parent, *name;
@@ -335,16 +329,16 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
 			break;
 		}
 
-		clk = cp110_register_gate(name, parent, regmap, i);
-		if (IS_ERR(clk)) {
-			ret = PTR_ERR(clk);
+		hw = cp110_register_gate(name, parent, regmap, i);
+		if (IS_ERR(hw)) {
+			ret = PTR_ERR(hw);
 			goto fail_gate;
 		}
 
-		cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk;
+		cp110_clks[CP110_MAX_CORE_CLOCKS + i] = hw;
 	}
 
-	ret = of_clk_add_provider(np, cp110_of_clk_get, cp110_clk_data);
+	ret = of_clk_add_hw_provider(np, cp110_of_clk_get, cp110_clk_data);
 	if (ret)
 		goto fail_clk_add;
 
@@ -355,44 +349,44 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
 fail_clk_add:
 fail_gate:
 	for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) {
-		clk = cp110_clks[CP110_MAX_CORE_CLOCKS + i];
+		hw = cp110_clks[CP110_MAX_CORE_CLOCKS + i];
 
-		if (clk)
-			cp110_unregister_gate(clk);
+		if (hw)
+			cp110_unregister_gate(hw);
 	}
 
-	clk_unregister_fixed_factor(cp110_clks[CP110_CORE_NAND]);
+	clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_NAND]);
 fail4:
-	clk_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
+	clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
 fail3:
-	clk_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]);
+	clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]);
 fail2:
-	clk_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
+	clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
 fail1:
-	clk_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]);
+	clk_hw_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]);
 fail0:
 	return ret;
 }
 
 static int cp110_syscon_clk_remove(struct platform_device *pdev)
 {
-	struct clk **cp110_clks = platform_get_drvdata(pdev);
+	struct clk_hw **cp110_clks = platform_get_drvdata(pdev);
 	int i;
 
 	of_clk_del_provider(pdev->dev.of_node);
 
 	for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) {
-		struct clk *clk = cp110_clks[CP110_MAX_CORE_CLOCKS + i];
+		struct clk_hw *hw = cp110_clks[CP110_MAX_CORE_CLOCKS + i];
 
-		if (clk)
-			cp110_unregister_gate(clk);
+		if (hw)
+			cp110_unregister_gate(hw);
 	}
 
-	clk_unregister_fixed_factor(cp110_clks[CP110_CORE_NAND]);
-	clk_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
-	clk_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]);
-	clk_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
-	clk_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]);
+	clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_NAND]);
+	clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
+	clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]);
+	clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
+	clk_hw_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]);
 
 	return 0;
 }
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 1/4] ARM: tegra: nyan: Use proper IRQ type definitions
From: Jon Hunter @ 2016-09-21  9:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474446366.1239.17.camel@paulk.fr>


On 21/09/16 09:26, Paul Kocialkowski wrote:
> * PGP Signed by an unknown key
> 
> Le mercredi 21 septembre 2016 ? 08:52 +0100, Jon Hunter a ?crit :
>> On 20/09/16 19:14, Paul Kocialkowski wrote:
>>>
>>>> Old Signed by an unknown key
>>>
>>> Le mardi 20 septembre 2016 ? 18:15 +0100, Jon Hunter a ?crit :
>>>>
>>>> On 28/08/16 18:32, Paul Kocialkowski wrote:
>>>>>
>>>>>
>>>>> This switches a few interrupt definitions that were using
>>>>> GPIO_ACTIVE_HIGH as IRQ type, which is invalid.
>>>>
>>>> May be you are right, but this does not describe why this is invalid.
>>>> Can you elaborate?
>>>
>>> GPIO_ACTIVE_HIGH is simply not the right kind of define to use in the
>>> "interrupts" devicetree property. Values provided there are understood as
>>> IRQ_TYPE_ defines.
>>
>> Right, but you are changing the type as GPIO_ACTIVE_HIGH = 0 and
>> IRQ_TYPE_EDGE_FALLING = 2 and there is no comment about why this has
>> been changed. It might be correct, but you need to explain it.
> 
> This actually makes the IRQ trigger values consistent with the drivers, that
> define them regardless of devicetree anyway. The max98090 driver
> has IRQF_TRIGGER_FALLING and bq24735 has IRQF_TRIGGER_RISING |
> IRQF_TRIGGER_FALLING.
> 
> This is really more of a cosmetic change, it doesn't impact actual use.

So you are saying that the drivers don't actually use the DT types? May
be that is ok, and yes this is cosmetic, but this should be stated in
the changelog as it is not clear what is going on here.

Cheers
Jon

-- 
nvpublic

^ permalink raw reply

* ftrace function_graph causes system crash
From: Jisheng Zhang @ 2016-09-21  9:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <0e38f79fdc1f4671943da74764c15050@SIWEX5A.sing.micron.com>

Hi Bean,

On Wed, 21 Sep 2016 07:50:58 +0000 "Bean Huo (beanhuo)"  wrote:

> > From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org]
> > On Behalf Of Steven Rostedt
> > Sent: Dienstag, 20. September 2016 16:07
> > To: Bean Huo (beanhuo) <beanhuo@micron.com>
> > Cc: Zoltan Szubbocsev (zszubbocsev) <zszubbocsev@micron.com>;
> > catalin.marinas at arm.com; will.deacon at arm.com; rfi at lists.rocketboards.org;
> > linux-kernel at vger.kernel.org; mingo at redhat.com; linux-arm-
> > kernel at lists.infradead.org
> > Subject: Re: ftrace function_graph causes system crash
> > 
> > On Tue, 20 Sep 2016 13:10:39 +0000
> > "Bean Huo (beanhuo)" <beanhuo@micron.com> wrote:
> >   
> > > Hi, all
> > > I just use ftrace to do some latency study, found that function_graph
> > > can not Work, as long as enable it, will cause kernel panic. I searched this  
> > online.  
> > > Found that there are also some cause the same as mine. I am a newer of  
> > ftrace.  
> > > I want to know who know what root cause? Here is some partial log:
> > >
> > >  
> > 
> > Can you do a function bisect to find what function this is.
> > 
> > This script is used to help find functions that are being traced by function tracer
> > or function graph tracing that causes the machine to reboot, hang, or crash.
> > Here's the steps to take.
> > 
> > First, determine if function graph is working with a single function:
> > 
> > # cd /sys/kernel/debug/tracing
> > # echo schedule > set_ftrace_filter
> > # echo function_graph > current_tracer
> > 
> > If this works, then we know that something is being traced that shouldn't be.
> > 
> > # echo nop > current_tracer
> > 
> > # cat available_filter_functions > ~/full-file # ftrace-bisect ~/full-file ~/test-file
> > ~/non-test-file # cat ~/test-file > set_ftrace_filter
> > 
> > *** Note *** this will take several minutes. Setting multiple functions is an
> > O(n^2) operation, and we are dealing with thousands of functions.
> > So go have  coffee, talk with your coworkers, read facebook. And eventually,
> > this operation will end.
> > 
> > # echo function_graph > current_tracer
> > 
> > If it crashes, we know that ~/test-file has a bad function.
> > 
> >    Reboot back to test kernel.
> > 
> >    # cd /sys/kernel/debug/tracing
> >    # mv ~/test-file ~/full-file
> > 
> > If it didn't crash.
> > 
> >    # echo nop > current_tracer
> >    # mv ~/non-test-file ~/full-file
> > 
> > Get rid of the other test file from previous run (or save them off somewhere.
> > # rm -f ~/test-file ~/non-test-file
> > 
> > And start again:
> > 
> > # ftrace-bisect ~/full-file ~/test-file ~/non-test-file
> > 
> > The good thing is, because this cuts the number of functions in ~/test-file by half,
> > the cat of it into set_ftrace_filter takes half as long each iteration, so don't talk
> > so much at the water cooler the second time.
> > 
> > Eventually, if you did this correctly, you will get down to the problem function,
> > and all we need to do is to notrace it.
> > 
> > The way to figure out if the problem function is bad, just do:
> > 
> > # echo <problem-function> > set_ftrace_notrace # echo > set_ftrace_filter #
> > echo function_graph > current_tracer
> > 
> > And if it doesn't crash, we are done.
> > 
> > -- Steve  
> 
> 
> Hi, Steve
> Thanks very much! This is a very useful trace tool, I now know the problem function,
> It is gt_counter_read, if not trace this function, ftrace function_graph work well.

I'm not sure whether the commit d6df3576e6b4 ("clocksource/drivers/arm_global_timer
: Prevent ftrace recursion") can fix this issue.

this commit is merged since v4.3, I noticed your kernel version is v4.0

Thanks,
Jisheng

> Do you know now how to deeply debug and trace which line is wrong through Ftrace?
> 
> --Bean
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox