* [PATCH v2 01/26] drm/bridge: allow optionally specifying an owner .odev device
From: Peter Rosin @ 2018-05-04 13:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504135212.26977-1-peda@axentia.se>
Bridge drivers can now (temporarily, in a transition phase) select if
they want to provide a full owner device or keep just providing an
of_node.
By providing a full owner device, the bridge drivers no longer need
to provide an of_node since that node is available via the owner
device.
When all bridge drivers provide an owner device, that will become
mandatory and the .of_node member will be removed.
Signed-off-by: Peter Rosin <peda@axentia.se>
---
drivers/gpu/drm/drm_bridge.c | 3 ++-
drivers/gpu/drm/rockchip/rockchip_lvds.c | 4 +++-
include/drm/drm_bridge.h | 2 ++
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 1638bfe9627c..3872f5379998 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -365,7 +365,8 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np)
mutex_lock(&bridge_lock);
list_for_each_entry(bridge, &bridge_list, list) {
- if (bridge->of_node == np) {
+ if ((bridge->odev && bridge->odev->of_node == np) ||
+ bridge->of_node == np) {
mutex_unlock(&bridge_lock);
return bridge;
}
diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
index 4bd94b167d2c..557e0079c98d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -377,8 +377,10 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
}
if (lvds->panel)
remote = lvds->panel->dev->of_node;
- else
+ else if (lvds->bridge->of_node)
remote = lvds->bridge->of_node;
+ else
+ remote = lvds->bridge->odev->of_node;
if (of_property_read_string(dev->of_node, "rockchip,output", &name))
/* default set it as output rgb */
lvds->output = DISPLAY_OUTPUT_RGB;
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 3270fec46979..7c17977c3537 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -254,6 +254,7 @@ struct drm_bridge_timings {
/**
* struct drm_bridge - central DRM bridge control structure
+ * @odev: device that owns the bridge
* @dev: DRM device this bridge belongs to
* @encoder: encoder to which this bridge is connected
* @next: the next bridge in the encoder chain
@@ -265,6 +266,7 @@ struct drm_bridge_timings {
* @driver_private: pointer to the bridge driver's internal context
*/
struct drm_bridge {
+ struct device *odev;
struct drm_device *dev;
struct drm_encoder *encoder;
struct drm_bridge *next;
--
2.11.0
^ permalink raw reply related
* [PATCH v2 00/26] device link, bridge supplier <-> drm device
From: Peter Rosin @ 2018-05-04 13:51 UTC (permalink / raw)
To: linux-arm-kernel
Hi!
It was noted by Russel King [1] that bridges (not using components)
might disappear unexpectedly if the owner of the bridge was unbound.
Jyri Sarha had previously noted the same thing with panels [2]. Jyri
came up with using device links to resolve the panel issue, which
was also my (independent) reaction to the note from Russel.
This series builds up to the addition of that link in the last
patch, but in my opinion the other 25 patches do have merit on their
own.
The last patch needs testing, while the others look trivial. Jyri, are
you able to test? That said, I might have missed some subtlety.
Oh and the reason I'm pushing this is of course so that the issue
noted by Russel in [1] is addressed which in turn means that the
tda998x bridge driver can be patched according to that series without
objection (hopefully) and then used from the atmel-hlcdc driver (and
other drivers that are not componentized).
Changes since v1 https://lkml.org/lkml/2018/4/26/1018
- rename .owner to .odev to not get mixed up with the module owner.
- added patches for new recent drivers thc63lvd1024 and cdns-dsi
- fix for problem in the rockchip_lvds driver reported by 0day
- added a WARN in drm_bridge_add if there is no .odev owner device
I did *not*:
- add any ack from Daniel since he suggested "pdev", and I ended up
with "odev" in the rename since I disliked "pdev" about as much
as "owner".
- add any port id. The current .of_node (that this series removes)
does not identify the port, so that problem seems orthogonal
to me.
Cheers,
Peter
[1] https://lkml.org/lkml/2018/4/23/769
[2] https://www.spinics.net/lists/dri-devel/msg174275.html
Peter Rosin (26):
drm/bridge: allow optionally specifying an owner .odev device
drm/bridge: adv7511: provide an owner .odev device
drm/bridge/analogix: core: specify the owner .odev of the bridge
drm/bridge: analogix-anx78xx: provide an owner .odev device
drm/bridge: cdns-dsi: provide an owner .odev device
drm/bridge: vga-dac: provide an owner .odev device
drm/bridge: lvds-encoder: provide an owner .odev device
drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: provide an owner .odev
device
drm/bridge: nxp-ptn3460: provide an owner .odev device
drm/bridge: panel: provide an owner .odev device
drm/bridge: ps8622: provide an owner .odev device
drm/bridge: sii902x: provide an owner .odev device
drm/bridge: sii9234: provide an owner .odev device
drm/bridge: sii8620: provide an owner .odev device
drm/bridge: synopsys: provide an owner .odev device for the bridges
drm/bridge: tc358767: provide an owner .odev device
drm/bridge: thc63lvd1024: provide an owner .odev device
drm/bridge: ti-tfp410: provide an owner .odev device
drm/exynos: mic: provide an owner .odev device for the bridge
drm/mediatek: hdmi: provide an owner .odev device for the bridge
drm/msm: specify the owner .odev of the bridges
drm/rcar-du: lvds: provide an owner .odev device for the bridge
drm/sti: provide an owner .odev device for the bridges
drm/bridge: remove the .of_node member
drm/bridge: require the owner .odev to be filled in on
drm_bridge_add/attach
drm/bridge: establish a link between the bridge supplier and consumer
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 +-
drivers/gpu/drm/bridge/analogix-anx78xx.c | 5 +----
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
drivers/gpu/drm/bridge/cdns-dsi.c | 2 +-
drivers/gpu/drm/bridge/dumb-vga-dac.c | 2 +-
drivers/gpu/drm/bridge/lvds-encoder.c | 2 +-
.../drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 2 +-
drivers/gpu/drm/bridge/nxp-ptn3460.c | 2 +-
drivers/gpu/drm/bridge/panel.c | 4 +---
drivers/gpu/drm/bridge/parade-ps8622.c | 2 +-
drivers/gpu/drm/bridge/sii902x.c | 2 +-
drivers/gpu/drm/bridge/sii9234.c | 2 +-
drivers/gpu/drm/bridge/sil-sii8620.c | 2 +-
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 +---
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 4 +---
drivers/gpu/drm/bridge/tc358767.c | 2 +-
drivers/gpu/drm/bridge/thc63lvd1024.c | 2 +-
drivers/gpu/drm/bridge/ti-tfp410.c | 2 +-
drivers/gpu/drm/drm_bridge.c | 26 +++++++++++++++++++++-
drivers/gpu/drm/exynos/exynos_drm_mic.c | 2 +-
drivers/gpu/drm/mediatek/mtk_hdmi.c | 2 +-
drivers/gpu/drm/msm/dsi/dsi_manager.c | 1 +
drivers/gpu/drm/msm/edp/edp_bridge.c | 1 +
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 1 +
drivers/gpu/drm/rcar-du/rcar_lvds.c | 2 +-
drivers/gpu/drm/rockchip/rockchip_lvds.c | 2 +-
drivers/gpu/drm/sti/sti_dvo.c | 2 +-
drivers/gpu/drm/sti/sti_hda.c | 1 +
drivers/gpu/drm/sti/sti_hdmi.c | 1 +
include/drm/drm_bridge.h | 8 +++----
30 files changed, 57 insertions(+), 36 deletions(-)
--
2.11.0
^ permalink raw reply
* [GIT PULL] STM32 DT changes for v4.18 #1
From: Alexandre Torgue @ 2018-05-04 13:46 UTC (permalink / raw)
To: linux-arm-kernel
Hi Arnd, Olof and Kevin,
Please consider this first round of STM32 DT updates for v4.18. As you
will see, main part of patches concerns support for STM32MP157 platform.
I didn't squash DT patches (as I like the way there are split) but let
me know if for next time you prefer I do it.
Regards
Alex
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git
tags/stm32-dt-for-v4.18-1
for you to fetch changes up to 0a84a00094eea4080288f5c62aff8a90e510a252:
ARM: dts: stm32: update pwm-cells for LPTimer on stm32h743
(2018-05-04 09:45:54 +0200)
----------------------------------------------------------------
STM32 DT updates for v4.18, round 1
Highlights:
-----------
-MCU platforms updates:
-Update pwm-cells for stm32h743
-Add I2C support on stm32f7xx-disco boards and
on stm32h743i-eval board
-Add new stm32f469 dtsi file
-Add display support on stm32f469-disco (LTDC/DSI)
+ pannel orisetech (otm8009a)
-MPU STM32MP157 platform updates:
-Fix DTC (W=12) warnings
-Fix IRQ type definition for usart
-Add QSPI & NOR flash support on EV1 board
-Add CEC support
-Add USB host
-Add USBPHYC support and enable it on EV1 board
-Add LTDC and DSI support
-Add I2C support and enable it on ED1 and EV1 boards
-Add CRC support
-Add RNG support
-Add CRYP support
-Add DAC support
-Add LPTIMER support
-Add VREFBUFF support
-Add timers supports and enable timer trigger 6 on ED1 board
-Add MDMA, DMA and DMAMUX support and enable it
-Enable clock driver
----------------------------------------------------------------
Alexandre Torgue (2):
ARM: dts: stm32: Fix DTC warnings for stm32mp157
ARM: dts: stm32: Fix IRQ_TYPE_NONE warnings on stm32mp157c
Amelie Delaunay (4):
ARM: dts: stm32: add USBPHYC support to stm32mp157c
ARM: dts: stm32: add supplies to usbphyc ports on stm32mp157c-ed1
ARM: dts: stm32: enable USBPHYC on stm32mp157c-ev1
ARM: dts: stm32: add USB Host (USBH) support to stm32mp157c
Fabrice Gasnier (8):
ARM: dts: stm32: add timers support to stm32mp157c
ARM: dts: stm32: add PWM pins used on stm32mp157c-ev1 board
ARM: dts: stm32: add PWM and triggers on stm32mp157c-ev1 board
ARM: dts: stm32: enable timer trigger 6 on stm32mp157c-ed1
ARM: dts: stm32: Add vrefbuf support to stm32mp157c
ARM: dts: stm32: Add LPtimer support to stm32mp157c
ARM: dts: stm32: Add DAC support to stm32mp157c
ARM: dts: stm32: update pwm-cells for LPTimer on stm32h743
Gabriel Fernandez (2):
ARM: dts: stm32: Enable stm32mp1 clock driver on stm32mp157c
ARM: dts: stm32: add reset binding on stm32mp157c
Lionel Debieve (4):
ARM: dts: stm32: Add RNG support on stm32mp157c
ARM: dts: stm32: Enable RNG for stm32mp157c-ed1
ARM: dts: stm32: Add CRYP support on stm32mp157c
ARM: dts: stm32: Add CRC support on stm32mp157c
Ludovic Barre (2):
ARM: dts: stm32: add qspi support for stm32mp157c
ARM: dts: stm32: add flash nor support on stm32mp157c eval board
Philippe CORNU (1):
ARM: dts: stm32: Add display support on stm32f469-disco
Philippe Cornu (2):
ARM: dts: stm32: Use gpio bindings in stm32f469-disco
ARM: dts: stm32: Add new stm32f469 dtsi file with mipi dsi
Pierre-Yves MORDRET (12):
ARM: dts: stm32: Add DMAv2 support on STM32MP157C
ARM: dts: stm32: Add DMAMUX support on STM32MP157C
ARM: dts: stm32: Add MDMA support on STM32MP157C
ARM: dts: stm32: Add STM32F7 I2C support for STM32MP157C SoC
ARM: dts: stm32: Add I2Cs pins used on STM32MP157C
ARM: dts: stm32: Add I2C4 support for STM32MP157C-ED1
ARM: dts: stm32: Add I2C2/5 support for STM32MP157C-EV1
ARM: dts: stm32: Append additional I2Cs for STM32F746 SoC
ARM: dts: stm32: Add I2C1 support for stm32f769-disco Board
ARM: dts: stm32: Add I2C1 support for stm32f746-disco Board
ARM: dts: stm32: Add I2C support for STM32H743 SoC
ARM: dts: stm32: Add I2C1 support for stm32h743i-eval Board
yannick fertre (5):
ARM: dts: stm32: add ltdc support on stm32mp157c
ARM: dts: stm32: add dsi support on stm32mp157c
ARM: dts: stm32: add cec support on stm32mp157c
ARM: dts: stm32: add cec pins to stm32mp157c
ARM: dts: stm32: add cec support on stm32mp157c-ev1
arch/arm/boot/dts/stm32f469-disco.dts | 53 ++-
arch/arm/boot/dts/stm32f469.dtsi | 19 +
arch/arm/boot/dts/stm32f746-disco.dts | 8 +
arch/arm/boot/dts/stm32f746.dtsi | 36 ++
arch/arm/boot/dts/stm32f769-disco.dts | 8 +
arch/arm/boot/dts/stm32h743-pinctrl.dtsi | 10 +
arch/arm/boot/dts/stm32h743.dtsi | 53 +++
arch/arm/boot/dts/stm32h743i-eval.dts | 8 +
arch/arm/boot/dts/stm32mp157-pinctrl.dtsi | 151 ++++++-
arch/arm/boot/dts/stm32mp157c-ed1.dts | 57 ++-
arch/arm/boot/dts/stm32mp157c-ev1.dts | 87 ++++
arch/arm/boot/dts/stm32mp157c.dtsi | 720
++++++++++++++++++++++++++++--
12 files changed, 1152 insertions(+), 58 deletions(-)
create mode 100644 arch/arm/boot/dts/stm32f469.dtsi
^ permalink raw reply
* Potential deadlock in vgic
From: Marc Zyngier @ 2018-05-04 13:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504130854.GA14663@hc>
On 04/05/18 14:08, Jan Glauber wrote:
> On Fri, May 04, 2018 at 02:47:42PM +0200, Christoffer Dall wrote:
>> Hi Jan,
>>
>> On Fri, May 04, 2018 at 01:03:44PM +0200, Jan Glauber wrote:
>>> Hi all,
>>>
>>> enabling lockdep I see the following reported in the host when I start a kvm guest:
>>>
>>> [12399.954245] CPU0 CPU1
>>> [12399.958762] ---- ----
>>> [12399.963279] lock(&(&dist->lpi_list_lock)->rlock);
>>> [12399.968146] local_irq_disable();
>>> [12399.974052] lock(&(&vgic_cpu->ap_list_lock)->rlock);
>>> [12399.981696] lock(&(&dist->lpi_list_lock)->rlock);
>>> [12399.989081] <Interrupt>
>>> [12399.991688] lock(&(&vgic_cpu->ap_list_lock)->rlock);
>>> [12399.996989]
>>> *** DEADLOCK ***
>>>
>>> [12400.002897] 2 locks held by qemu-system-aar/5597:
>>> [12400.007587] #0: 0000000042beb9dc (&vcpu->mutex){+.+.}, at: kvm_vcpu_ioctl+0x7c/0xa68
>>> [12400.015411] #1: 00000000c45d644a (&(&vgic_cpu->ap_list_lock)->rlock){-.-.}, at: kvm_vgic_sync_hwstate+0x8c/0x328
>>>
>>>
>>> There is nothing unusual in my config or qemu parameters, I can upload these
>>> if needed. I see this on ThunderX and ThunderX2 and also with older kernels
>>> (4.13+ distribution kernel).
>>>
>>> I tried making the lpi_list_lock irq safe but that just leads to different
>>> warnings. The locking here seems to be quite sophisticated and I'm not familiar
>>> with it.
>>
>> That's unfortunate. The problem here is that we end up violating our
>> locking order, which stipulates that ap_list_lock must be taken before
>> the lpi_list_lock.
>>
>> Give that we can take the ap_list_lock from interrupt context (timers
>> firing), the only solution I can easily think of is to change
>> lpi_list_lock takers to disable interrupts as well.
>>
>> Which warnings did you encounter with that approach?
>
> Hi Christoffer,
>
> making lpi_list_lock irq safe I get:
>
> [ 394.239174] ========================================================
> [ 394.245515] WARNING: possible irq lock inversion dependency detected
> [ 394.251857] 4.17.0-rc3-jang+ #72 Not tainted
> [ 394.256114] --------------------------------------------------------
> [ 394.262454] qemu-system-aar/5596 just changed the state of lock:
> [ 394.268448] 00000000da3f09ef (&(&irq->irq_lock)->rlock#3){+...}, at: update_affinity+0x3c/0xa8
> [ 394.277066] but this lock was taken by another, HARDIRQ-safe lock in the past:
> [ 394.284274] (&(&vgic_cpu->ap_list_lock)->rlock){-.-.}
> [ 394.284278]
>
> and interrupts could create inverse lock ordering between them.
>
> [ 394.300777]
> other info that might help us debug this:
> [ 394.307292] Possible interrupt unsafe locking scenario:
>
> [ 394.314066] CPU0 CPU1
> [ 394.318584] ---- ----
> [ 394.323101] lock(&(&irq->irq_lock)->rlock#3);
> [ 394.327622] local_irq_disable();
> [ 394.333528] lock(&(&vgic_cpu->ap_list_lock)->rlock);
> [ 394.341172] lock(&(&irq->irq_lock)->rlock#3);
> [ 394.348210] <Interrupt>
> [ 394.350817] lock(&(&vgic_cpu->ap_list_lock)->rlock);
> [ 394.356118]
> *** DEADLOCK ***
>
> [ 394.362025] 4 locks held by qemu-system-aar/5596:
> [ 394.366716] #0: 00000000719c7423 (&vcpu->mutex){+.+.}, at: kvm_vcpu_ioctl+0x7c/0xa68
> [ 394.374545] #1: 0000000060090841 (&kvm->srcu){....}, at: kvm_handle_guest_abort+0x11c/0xb70
> [ 394.382984] #2: 0000000064647766 (&its->cmd_lock){+.+.}, at: vgic_mmio_write_its_cwriter+0x44/0xa8
> [ 394.392022] #3: 0000000075f90a8a (&its->its_lock){+.+.}, at: vgic_its_process_commands.part.11+0xac/0x780
Right, that's conceptually the same problem (the ap_list_lock being
always taken with interrupt disabled creates a point where all the
subsequent locks must also be with interrupts disabled.
Another possibility would be to ensure that we always take the ap_list
lock before taking the lpi_list_lock, disabling interrupts in the process.
I need to convince myself that this is correct though...
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH v2 09/10] ARM: dts: sun7i-a20: Add Video Engine and reserved memory nodes
From: Maxime Ripard @ 2018-05-04 13:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <fc064c3f1534a6082dc2b4e18454e054b53e5aee.camel@bootlin.com>
On Fri, May 04, 2018 at 02:04:38PM +0200, Paul Kocialkowski wrote:
> On Fri, 2018-05-04 at 11:15 +0200, Maxime Ripard wrote:
> > On Fri, May 04, 2018 at 10:47:44AM +0200, Paul Kocialkowski wrote:
> > > > > > > + reg = <0x01c0e000 0x1000>;
> > > > > > > + memory-region = <&ve_memory>;
> > > > > >
> > > > > > Since you made the CMA region the default one, you don't need
> > > > > > to
> > > > > > tie
> > > > > > it to that device in particular (and you can drop it being
> > > > > > mandatory
> > > > > > from your binding as well).
> > > > >
> > > > > What if another driver (or the system) claims memory from that
> > > > > zone
> > > > > and
> > > > > that the reserved memory ends up not being available for the VPU
> > > > > anymore?
> > > > >
> > > > > Acccording to the reserved-memory documentation, the reusable
> > > > > property
> > > > > (that we need for dmabuf) puts a limitation that the device
> > > > > driver
> > > > > owning the region must be able to reclaim it back.
> > > > >
> > > > > How does that work out if the CMA region is not tied to a driver
> > > > > in
> > > > > particular?
> > > >
> > > > I'm not sure to get what you're saying. You have the property
> > > > linux,cma-default in your reserved region, so the behaviour you
> > > > described is what you explicitly asked for.
> > >
> > > My point is that I don't see how the driver can claim back (part of)
> > > the
> > > reserved area if the area is not explicitly attached to it.
> > >
> > > Or is that mechanism made in a way that all drivers wishing to use
> > > the
> > > reserved memory area can claim it back from the system, but there is
> > > no
> > > priority (other than first-come first-served) for which drivers
> > > claims
> > > it back in case two want to use the same reserved region (in a
> > > scenario
> > > where there isn't enough memory to allow both drivers)?
> >
> > This is indeed what happens. Reusable is to let the system use the
> > reserved memory for things like caches that can easily be dropped when
> > a driver wants to use the memory in that reserved area. Once that
> > memory has been allocated, there's no claiming back, unless that
> > memory segment was freed of course.
>
> Thanks for the clarification. So in our case, perhaps the best fit would
> be to make that area the default CMA pool so that we can be ensured that
> the whole 96 MiB is available for the VPU and that no other consumer of
> CMA will use it?
The best fit for what use case ? We already discussed this, and I
don't see any point in having two separate CMA regions. If you have a
reasonably sized region that will accomodate for both the VPU and
display engine, why would we want to split them?
Or did you have any experience of running out of buffers?
Maxime
--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/d2d87aa3/attachment.sig>
^ permalink raw reply
* [PATCH v3 0/3] arm64: dts: renesas: salvator-x(s)/ulcb: Add PMIC DDR Backup Power config
From: Simon Horman @ 2018-05-04 13:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525350651-12471-1-git-send-email-geert+renesas@glider.be>
On Thu, May 03, 2018 at 02:30:48PM +0200, Geert Uytterhoeven wrote:
> Hi Simon, Magnus,
>
> The ROHM BD9571MWV PMIC on the Renesas Salvator-X(S) and ULCB
> development boards supports DDR Backup Power, which means that the DDR
> power rails can be kept powered while the main SoC is powered down.
>
> For this to function correctly, the DDR Backup Power configuration
> must be described in DT, which is the topic of this series:
> - The first patch adds the missing device node for the BD9571 PMIC on
> the ULCB boards,
> - The last two patches add DDR Backup Mode configuration for
> Salvator-X(S) and ULCB.
>
> Changes compared to v3:
> - Use a hex value for the bit mask.
>
> Changes compared to v2:
> - Add support for ULCB,
> - Add "rohm,rstbmode-level" for Salvator-X(S).
>
> The relevant DT binding updates have been accepted in
> regulator/for-next, as well as driver support for DDR Backup Mode on
> systems with momentary power switches ("rohm,rstbmode-pulse"), like
> ULCB. Combined with this series, the PMIC on ULCB will be configured
> automatically during system suspend.
>
> Note that driver support for systems with toggle power swiches
> ("rohm,rstbmode-level"), like Salvator-X(S), is still under review
> (https://lkml.org/lkml/2018/3/14/324). But as DT describes hardware,
> not software limitations, this series is safe to apply.
>
> This has been tested on M3ULCB (thanks Jacopo!), and on Salvator-X(S).
> All support has been part of renesas-drivers since a few releases.
>
> Thanks for applying!
Thanks, applied.
^ permalink raw reply
* [PATCH v3 3/3] sh: add the sh_ prefix to early platform symbols
From: Bartosz Golaszewski @ 2018-05-04 13:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504132731.14574-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Old early platform device support is now sh-specific. Before moving on
to implementing new early platform framework based on real platform
devices, prefix all early platform symbols with 'sh_'.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/sh/drivers/platform_early.c | 66 +++++++++++++-------------
arch/sh/include/asm/platform_early.h | 30 ++++++------
arch/sh/kernel/cpu/sh2/setup-sh7619.c | 2 +-
arch/sh/kernel/cpu/sh2a/setup-mxg.c | 2 +-
arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 2 +-
arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 2 +-
arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 2 +-
arch/sh/kernel/cpu/sh2a/setup-sh7264.c | 2 +-
arch/sh/kernel/cpu/sh2a/setup-sh7269.c | 2 +-
arch/sh/kernel/cpu/sh3/setup-sh7705.c | 2 +-
arch/sh/kernel/cpu/sh3/setup-sh770x.c | 2 +-
arch/sh/kernel/cpu/sh3/setup-sh7710.c | 2 +-
arch/sh/kernel/cpu/sh3/setup-sh7720.c | 2 +-
arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 2 +-
arch/sh/kernel/cpu/sh4/setup-sh7750.c | 8 ++--
arch/sh/kernel/cpu/sh4/setup-sh7760.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7734.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 2 +-
arch/sh/kernel/cpu/sh4a/setup-shx3.c | 2 +-
arch/sh/kernel/cpu/sh5/setup-sh5.c | 2 +-
arch/sh/kernel/setup.c | 2 +-
arch/sh/kernel/time.c | 4 +-
drivers/clocksource/sh_cmt.c | 6 +--
drivers/clocksource/sh_mtu2.c | 6 +--
drivers/clocksource/sh_tmu.c | 6 +--
drivers/tty/serial/sh-sci.c | 4 +-
include/linux/platform_device.h | 2 +-
37 files changed, 94 insertions(+), 94 deletions(-)
diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
index bc094f6eb366..6eba755b8c12 100644
--- a/arch/sh/drivers/platform_early.c
+++ b/arch/sh/drivers/platform_early.c
@@ -3,8 +3,8 @@
#include <asm/platform_early.h>
#include <linux/pm.h>
-static __initdata LIST_HEAD(early_platform_driver_list);
-static __initdata LIST_HEAD(early_platform_device_list);
+static __initdata LIST_HEAD(sh_early_platform_driver_list);
+static __initdata LIST_HEAD(sh_early_platform_device_list);
static const struct platform_device_id *
platform_match_id(const struct platform_device_id *id,
@@ -57,13 +57,13 @@ static void pm_runtime_early_init(struct device *dev) {}
#endif
/**
- * early_platform_driver_register - register early platform driver
- * @epdrv: early_platform driver structure
+ * sh_early_platform_driver_register - register early platform driver
+ * @epdrv: sh_early_platform driver structure
* @buf: string passed from early_param()
*
- * Helper function for early_platform_init() / early_platform_init_buffer()
+ * Helper function for sh_early_platform_init() / sh_early_platform_init_buffer()
*/
-int __init early_platform_driver_register(struct early_platform_driver *epdrv,
+int __init sh_early_platform_driver_register(struct sh_early_platform_driver *epdrv,
char *buf)
{
char *tmp;
@@ -74,7 +74,7 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv,
*/
if (!epdrv->list.next) {
INIT_LIST_HEAD(&epdrv->list);
- list_add_tail(&epdrv->list, &early_platform_driver_list);
+ list_add_tail(&epdrv->list, &sh_early_platform_driver_list);
}
/* If the user has specified device then make sure the driver
@@ -83,7 +83,7 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv,
*/
n = strlen(epdrv->pdrv->driver.name);
if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
- list_move(&epdrv->list, &early_platform_driver_list);
+ list_move(&epdrv->list, &sh_early_platform_driver_list);
/* Allow passing parameters after device name */
if (buf[n] == '\0' || buf[n] == ',')
@@ -113,14 +113,14 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv,
}
/**
- * early_platform_add_devices - adds a number of early platform devices
+ * sh_early_platform_add_devices - adds a number of early platform devices
* @devs: array of early platform devices to add
* @num: number of early platform devices in array
*
* Used by early architecture code to register early platform devices and
* their platform data.
*/
-void __init early_platform_add_devices(struct platform_device **devs, int num)
+void __init sh_early_platform_add_devices(struct platform_device **devs, int num)
{
struct device *dev;
int i;
@@ -133,20 +133,20 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)
pm_runtime_early_init(dev);
INIT_LIST_HEAD(&dev->devres_head);
list_add_tail(&dev->devres_head,
- &early_platform_device_list);
+ &sh_early_platform_device_list);
}
}
}
/**
- * early_platform_driver_register_all - register early platform drivers
+ * sh_early_platform_driver_register_all - register early platform drivers
* @class_str: string to identify early platform driver class
*
* Used by architecture code to register all early platform drivers
* for a certain class. If omitted then only early platform drivers
* with matching kernel command line class parameters will be registered.
*/
-void __init early_platform_driver_register_all(char *class_str)
+void __init sh_early_platform_driver_register_all(char *class_str)
{
/* The "class_str" parameter may or may not be present on the kernel
* command line. If it is present then there may be more than one
@@ -159,23 +159,23 @@ void __init early_platform_driver_register_all(char *class_str)
* We use parse_early_options() to make sure the early_param() gets
* called at least once. The early_param() may be called more than
* once since the name of the preferred device may be specified on
- * the kernel command line. early_platform_driver_register() handles
+ * the kernel command line. sh_early_platform_driver_register() handles
* this case for us.
*/
parse_early_options(class_str);
}
/**
- * early_platform_match - find early platform device matching driver
+ * sh_early_platform_match - find early platform device matching driver
* @epdrv: early platform driver structure
* @id: id to match against
*/
static struct platform_device * __init
-early_platform_match(struct early_platform_driver *epdrv, int id)
+sh_early_platform_match(struct sh_early_platform_driver *epdrv, int id)
{
struct platform_device *pd;
- list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+ list_for_each_entry(pd, &sh_early_platform_device_list, dev.devres_head)
if (platform_match(&pd->dev, &epdrv->pdrv->driver))
if (pd->id == id)
return pd;
@@ -184,16 +184,16 @@ early_platform_match(struct early_platform_driver *epdrv, int id)
}
/**
- * early_platform_left - check if early platform driver has matching devices
+ * sh_early_platform_left - check if early platform driver has matching devices
* @epdrv: early platform driver structure
* @id: return true if id or above exists
*/
-static int __init early_platform_left(struct early_platform_driver *epdrv,
+static int __init sh_early_platform_left(struct sh_early_platform_driver *epdrv,
int id)
{
struct platform_device *pd;
- list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+ list_for_each_entry(pd, &sh_early_platform_device_list, dev.devres_head)
if (platform_match(&pd->dev, &epdrv->pdrv->driver))
if (pd->id >= id)
return 1;
@@ -202,22 +202,22 @@ static int __init early_platform_left(struct early_platform_driver *epdrv,
}
/**
- * early_platform_driver_probe_id - probe drivers matching class_str and id
+ * sh_early_platform_driver_probe_id - probe drivers matching class_str and id
* @class_str: string to identify early platform driver class
* @id: id to match against
* @nr_probe: number of platform devices to successfully probe before exiting
*/
-static int __init early_platform_driver_probe_id(char *class_str,
+static int __init sh_early_platform_driver_probe_id(char *class_str,
int id,
int nr_probe)
{
- struct early_platform_driver *epdrv;
+ struct sh_early_platform_driver *epdrv;
struct platform_device *match;
int match_id;
int n = 0;
int left = 0;
- list_for_each_entry(epdrv, &early_platform_driver_list, list) {
+ list_for_each_entry(epdrv, &sh_early_platform_driver_list, list) {
/* only use drivers matching our class_str */
if (strcmp(class_str, epdrv->class_str))
continue;
@@ -228,7 +228,7 @@ static int __init early_platform_driver_probe_id(char *class_str,
} else {
match_id = id;
- left += early_platform_left(epdrv, id);
+ left += sh_early_platform_left(epdrv, id);
/* skip requested id */
switch (epdrv->requested_id) {
@@ -250,7 +250,7 @@ static int __init early_platform_driver_probe_id(char *class_str,
match = NULL;
break;
default:
- match = early_platform_match(epdrv, match_id);
+ match = sh_early_platform_match(epdrv, match_id);
}
if (match) {
@@ -292,7 +292,7 @@ static int __init early_platform_driver_probe_id(char *class_str,
}
/**
- * early_platform_driver_probe - probe a class of registered drivers
+ * sh_early_platform_driver_probe - probe a class of registered drivers
* @class_str: string to identify early platform driver class
* @nr_probe: number of platform devices to successfully probe before exiting
* @user_only: only probe user specified early platform devices
@@ -301,7 +301,7 @@ static int __init early_platform_driver_probe_id(char *class_str,
* within a certain class. For probe to happen a registered early platform
* device matching a registered early platform driver is needed.
*/
-int __init early_platform_driver_probe(char *class_str,
+int __init sh_early_platform_driver_probe(char *class_str,
int nr_probe,
int user_only)
{
@@ -309,7 +309,7 @@ int __init early_platform_driver_probe(char *class_str,
n = 0;
for (i = -2; n < nr_probe; i++) {
- k = early_platform_driver_probe_id(class_str, i, nr_probe - n);
+ k = sh_early_platform_driver_probe_id(class_str, i, nr_probe - n);
if (k < 0)
break;
@@ -324,14 +324,14 @@ int __init early_platform_driver_probe(char *class_str,
}
/**
- * early_platform_cleanup - clean up early platform code
+ * sh_early_platform_cleanup - clean up early platform code
*/
-static int __init early_platform_cleanup(void)
+static int __init sh_early_platform_cleanup(void)
{
struct platform_device *pd, *pd2;
/* clean up the devres list used to chain devices */
- list_for_each_entry_safe(pd, pd2, &early_platform_device_list,
+ list_for_each_entry_safe(pd, pd2, &sh_early_platform_device_list,
dev.devres_head) {
list_del(&pd->dev.devres_head);
memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
@@ -343,4 +343,4 @@ static int __init early_platform_cleanup(void)
* This must happen once after all early devices are probed but before probing
* real platform devices.
*/
-subsys_initcall(early_platform_cleanup);
+subsys_initcall(sh_early_platform_cleanup);
diff --git a/arch/sh/include/asm/platform_early.h b/arch/sh/include/asm/platform_early.h
index 4590ab757d5f..fc802137c37d 100644
--- a/arch/sh/include/asm/platform_early.h
+++ b/arch/sh/include/asm/platform_early.h
@@ -8,7 +8,7 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>
-struct early_platform_driver {
+struct sh_early_platform_driver {
const char *class_str;
struct platform_driver *pdrv;
struct list_head list;
@@ -20,39 +20,39 @@ struct early_platform_driver {
#define EARLY_PLATFORM_ID_UNSET -2
#define EARLY_PLATFORM_ID_ERROR -3
-extern int early_platform_driver_register(struct early_platform_driver *epdrv,
+extern int sh_early_platform_driver_register(struct sh_early_platform_driver *epdrv,
char *buf);
-extern void early_platform_add_devices(struct platform_device **devs, int num);
+extern void sh_early_platform_add_devices(struct platform_device **devs, int num);
-static inline int is_early_platform_device(struct platform_device *pdev)
+static inline int is_sh_early_platform_device(struct platform_device *pdev)
{
return !pdev->dev.driver;
}
-extern void early_platform_driver_register_all(char *class_str);
-extern int early_platform_driver_probe(char *class_str,
+extern void sh_early_platform_driver_register_all(char *class_str);
+extern int sh_early_platform_driver_probe(char *class_str,
int nr_probe, int user_only);
-#define early_platform_init(class_string, platdrv) \
- early_platform_init_buffer(class_string, platdrv, NULL, 0)
+#define sh_early_platform_init(class_string, platdrv) \
+ sh_early_platform_init_buffer(class_string, platdrv, NULL, 0)
#ifndef MODULE
-#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
-static __initdata struct early_platform_driver early_driver = { \
+#define sh_early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
+static __initdata struct sh_early_platform_driver early_driver = { \
.class_str = class_string, \
.buffer = buf, \
.bufsize = bufsiz, \
.pdrv = platdrv, \
.requested_id = EARLY_PLATFORM_ID_UNSET, \
}; \
-static int __init early_platform_driver_setup_func(char *buffer) \
+static int __init sh_early_platform_driver_setup_func(char *buffer) \
{ \
- return early_platform_driver_register(&early_driver, buffer); \
+ return sh_early_platform_driver_register(&early_driver, buffer); \
} \
-early_param(class_string, early_platform_driver_setup_func)
+early_param(class_string, sh_early_platform_driver_setup_func)
#else /* MODULE */
-#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
-static inline char *early_platform_driver_setup_func(void) \
+#define sh_early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
+static inline char *sh_early_platform_driver_setup_func(void) \
{ \
return bufsiz ? buf : NULL; \
}
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index a02fc03baef8..6d0425affa71 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -203,6 +203,6 @@ void __init plat_early_device_setup(void)
/* enable CMT clock */
__raw_writeb(__raw_readb(STBCR3) & ~0x10, STBCR3);
- early_platform_add_devices(sh7619_early_devices,
+ sh_early_platform_add_devices(sh7619_early_devices,
ARRAY_SIZE(sh7619_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
index d33568a12fad..fb9dd473a9cc 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
@@ -173,6 +173,6 @@ static struct platform_device *mxg_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(mxg_early_devices,
+ sh_early_platform_add_devices(mxg_early_devices,
ARRAY_SIZE(mxg_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
index b258c5c3af60..37357d0fc9bc 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
@@ -416,6 +416,6 @@ void __init plat_early_device_setup(void)
/* enable MTU2 clock */
__raw_writeb(__raw_readb(STBCR3) & ~0x20, STBCR3);
- early_platform_add_devices(sh7201_early_devices,
+ sh_early_platform_add_devices(sh7201_early_devices,
ARRAY_SIZE(sh7201_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index db3f8df8d76d..79ba8d0db6b0 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -353,6 +353,6 @@ void __init plat_early_device_setup(void)
/* enable MTU2 clock */
__raw_writeb(__raw_readb(STBCR3) & ~0x20, STBCR3);
- early_platform_add_devices(sh7203_early_devices,
+ sh_early_platform_add_devices(sh7203_early_devices,
ARRAY_SIZE(sh7203_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index e1be4fedc739..501922504a3f 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -289,6 +289,6 @@ void __init plat_early_device_setup(void)
/* enable MTU2 clock */
__raw_writeb(__raw_readb(STBCR3) & ~0x20, STBCR3);
- early_platform_add_devices(sh7206_early_devices,
+ sh_early_platform_add_devices(sh7206_early_devices,
ARRAY_SIZE(sh7206_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
index b5bed10d0d72..955f15386bbd 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
@@ -550,6 +550,6 @@ static struct platform_device *sh7264_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7264_early_devices,
+ sh_early_platform_add_devices(sh7264_early_devices,
ARRAY_SIZE(sh7264_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
index 248a6732397a..d8ecb24a0888 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
@@ -566,6 +566,6 @@ static struct platform_device *sh7269_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7269_early_devices,
+ sh_early_platform_add_devices(sh7269_early_devices,
ARRAY_SIZE(sh7269_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index 7ec8c11c2f7a..481cfbc3b82d 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -182,7 +182,7 @@ static struct platform_device *sh7705_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7705_early_devices,
+ sh_early_platform_add_devices(sh7705_early_devices,
ARRAY_SIZE(sh7705_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index 20839dd40a2f..d0cd14f5fc19 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -234,7 +234,7 @@ static struct platform_device *sh770x_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh770x_early_devices,
+ sh_early_platform_add_devices(sh770x_early_devices,
ARRAY_SIZE(sh770x_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 780ccd202bab..fb680bae22c3 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -181,7 +181,7 @@ static struct platform_device *sh7710_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7710_early_devices,
+ sh_early_platform_add_devices(sh7710_early_devices,
ARRAY_SIZE(sh7710_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 723bd9c04c8a..faf084cbbbed 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -215,7 +215,7 @@ static struct platform_device *sh7720_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7720_early_devices,
+ sh_early_platform_add_devices(sh7720_early_devices,
ARRAY_SIZE(sh7720_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
index 4a5fa86006cd..123b848368d4 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
@@ -80,7 +80,7 @@ static struct platform_device *sh4202_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh4202_early_devices,
+ sh_early_platform_add_devices(sh4202_early_devices,
ARRAY_SIZE(sh4202_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index abb3703c2273..8f6c83b745db 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -165,15 +165,15 @@ void __init plat_early_device_setup(void)
if (mach_is_rts7751r2d()) {
scif_platform_data.scscr |= SCSCR_CKE1;
dev[0] = &scif_device;
- early_platform_add_devices(dev, 1);
+ sh_early_platform_add_devices(dev, 1);
} else {
dev[0] = &sci_device;
- early_platform_add_devices(dev, 1);
+ sh_early_platform_add_devices(dev, 1);
dev[0] = &scif_device;
- early_platform_add_devices(dev, 1);
+ sh_early_platform_add_devices(dev, 1);
}
- early_platform_add_devices(sh7750_early_devices,
+ sh_early_platform_add_devices(sh7750_early_devices,
ARRAY_SIZE(sh7750_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 649f4dcb5935..ab8cc1826d8c 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -275,7 +275,7 @@ static struct platform_device *sh7760_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7760_early_devices,
+ sh_early_platform_add_devices(sh7760_early_devices,
ARRAY_SIZE(sh7760_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 73715a635048..a3ff0803b62e 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -300,7 +300,7 @@ static struct platform_device *sh7343_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7343_early_devices,
+ sh_early_platform_add_devices(sh7343_early_devices,
ARRAY_SIZE(sh7343_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 942856048112..2ad400fef830 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -244,7 +244,7 @@ static struct platform_device *sh7366_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7366_early_devices,
+ sh_early_platform_add_devices(sh7366_early_devices,
ARRAY_SIZE(sh7366_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index bf60456a8012..01e687d72c16 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -516,7 +516,7 @@ static struct platform_device *sh7722_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7722_early_devices,
+ sh_early_platform_add_devices(sh7722_early_devices,
ARRAY_SIZE(sh7722_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index d25d3c3b44ab..6738c39413b2 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -414,7 +414,7 @@ static struct platform_device *sh7723_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7723_early_devices,
+ sh_early_platform_add_devices(sh7723_early_devices,
ARRAY_SIZE(sh7723_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 0eeadabc8065..0163750a3fb0 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -834,7 +834,7 @@ static struct platform_device *sh7724_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7724_early_devices,
+ sh_early_platform_add_devices(sh7724_early_devices,
ARRAY_SIZE(sh7724_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c
index bed9d01fa85f..d3760029f0f3 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c
@@ -284,7 +284,7 @@ static struct platform_device *sh7734_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7734_early_devices,
+ sh_early_platform_add_devices(sh7734_early_devices,
ARRAY_SIZE(sh7734_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index b5b19e81a8dc..25d655ab4114 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -771,7 +771,7 @@ static struct platform_device *sh7757_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7757_early_devices,
+ sh_early_platform_add_devices(sh7757_early_devices,
ARRAY_SIZE(sh7757_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index 51a6c64f860e..42f234efaa42 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -225,7 +225,7 @@ static struct platform_device *sh7763_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7763_early_devices,
+ sh_early_platform_add_devices(sh7763_early_devices,
ARRAY_SIZE(sh7763_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
index 77f228e20599..35420329f5e1 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
@@ -320,7 +320,7 @@ static struct platform_device *sh7770_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7770_early_devices,
+ sh_early_platform_add_devices(sh7770_early_devices,
ARRAY_SIZE(sh7770_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index c4cbb7584122..3a75db564c24 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -289,7 +289,7 @@ void __init plat_early_device_setup(void)
scif1_platform_data.scscr &= ~SCSCR_CKE1;
}
- early_platform_add_devices(sh7780_early_devices,
+ sh_early_platform_add_devices(sh7780_early_devices,
ARRAY_SIZE(sh7780_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index eda0d61ebf71..eb3c003223e2 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -357,7 +357,7 @@ static struct platform_device *sh7785_early_devices[] __initdata = {
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7785_early_devices,
+ sh_early_platform_add_devices(sh7785_early_devices,
ARRAY_SIZE(sh7785_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 77226a60c36f..46473345cb79 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -838,6 +838,6 @@ arch_initcall(sh7786_devices_setup);
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh7786_early_devices,
+ sh_early_platform_add_devices(sh7786_early_devices,
ARRAY_SIZE(sh7786_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index 83feaf0a4aae..c531182425f7 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -156,7 +156,7 @@ arch_initcall(shx3_devices_setup);
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(shx3_early_devices,
+ sh_early_platform_add_devices(shx3_early_devices,
ARRAY_SIZE(shx3_early_devices));
}
diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c
index 8ebd26a9fd90..034bb36bfdc2 100644
--- a/arch/sh/kernel/cpu/sh5/setup-sh5.c
+++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c
@@ -119,6 +119,6 @@ arch_initcall(sh5_devices_setup);
void __init plat_early_device_setup(void)
{
- early_platform_add_devices(sh5_early_devices,
+ sh_early_platform_add_devices(sh5_early_devices,
ARRAY_SIZE(sh5_early_devices));
}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index c9610a2b0888..4713d544b4c4 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -329,7 +329,7 @@ void __init setup_arch(char **cmdline_p)
sh_mv_setup();
/* Let earlyprintk output early console messages */
- early_platform_driver_probe("earlyprintk", 1, 1);
+ sh_early_platform_driver_probe("earlyprintk", 1, 1);
#ifdef CONFIG_OF_FLATTREE
#ifdef CONFIG_USE_BUILTIN_DTB
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 674d8413491b..9c460a74e3c2 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -105,8 +105,8 @@ static void __init sh_late_time_init(void)
* clocksource and the jiffies clocksource is used transparently
* instead. No error handling is necessary here.
*/
- early_platform_driver_register_all("earlytimer");
- early_platform_driver_probe("earlytimer", 2, 0);
+ sh_early_platform_driver_register_all("earlytimer");
+ sh_early_platform_driver_probe("earlytimer", 2, 0);
}
void __init time_init(void)
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 3ce69160efc1..fc45a75783d3 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -1047,7 +1047,7 @@ static int sh_cmt_probe(struct platform_device *pdev)
struct sh_cmt_device *cmt = platform_get_drvdata(pdev);
int ret;
- if (!is_early_platform_device(pdev)) {
+ if (!is_sh_early_platform_device(pdev)) {
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
}
@@ -1067,7 +1067,7 @@ static int sh_cmt_probe(struct platform_device *pdev)
pm_runtime_idle(&pdev->dev);
return ret;
}
- if (is_early_platform_device(pdev))
+ if (is_sh_early_platform_device(pdev))
return 0;
out:
@@ -1105,7 +1105,7 @@ static void __exit sh_cmt_exit(void)
}
#ifdef CONFIG_SUPERH
-early_platform_init("earlytimer", &sh_cmt_device_driver);
+sh_early_platform_init("earlytimer", &sh_cmt_device_driver);
#endif
subsys_initcall(sh_cmt_init);
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index b8211987b02b..f184381cef6e 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -454,7 +454,7 @@ static int sh_mtu2_probe(struct platform_device *pdev)
struct sh_mtu2_device *mtu = platform_get_drvdata(pdev);
int ret;
- if (!is_early_platform_device(pdev)) {
+ if (!is_sh_early_platform_device(pdev)) {
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
}
@@ -474,7 +474,7 @@ static int sh_mtu2_probe(struct platform_device *pdev)
pm_runtime_idle(&pdev->dev);
return ret;
}
- if (is_early_platform_device(pdev))
+ if (is_sh_early_platform_device(pdev))
return 0;
out:
@@ -524,7 +524,7 @@ static void __exit sh_mtu2_exit(void)
}
#ifdef CONFIG_SUPERH
-early_platform_init("earlytimer", &sh_mtu2_device_driver);
+sh_early_platform_init("earlytimer", &sh_mtu2_device_driver);
#endif
subsys_initcall(sh_mtu2_init);
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index 3d929129ed68..fad5ee1037a0 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -610,7 +610,7 @@ static int sh_tmu_probe(struct platform_device *pdev)
struct sh_tmu_device *tmu = platform_get_drvdata(pdev);
int ret;
- if (!is_early_platform_device(pdev)) {
+ if (!is_sh_early_platform_device(pdev)) {
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
}
@@ -631,7 +631,7 @@ static int sh_tmu_probe(struct platform_device *pdev)
return ret;
}
- if (is_early_platform_device(pdev))
+ if (is_sh_early_platform_device(pdev))
return 0;
out:
@@ -682,7 +682,7 @@ static void __exit sh_tmu_exit(void)
}
#ifdef CONFIG_SUPERH
-early_platform_init("earlytimer", &sh_tmu_device_driver);
+sh_early_platform_init("earlytimer", &sh_tmu_device_driver);
#endif
subsys_initcall(sh_tmu_init);
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 37faf3d8d647..2f9bd1900444 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -3196,7 +3196,7 @@ static int sci_probe(struct platform_device *dev)
* to make it beyond this yet.
*/
#ifdef CONFIG_SUPERH
- if (is_early_platform_device(dev))
+ if (is_sh_early_platform_device(dev))
return sci_probe_earlyprintk(dev);
#endif
@@ -3295,7 +3295,7 @@ static void __exit sci_exit(void)
}
#if defined(CONFIG_SUPERH) && defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
-early_platform_init_buffer("earlyprintk", &sci_driver,
+sh_early_platform_init_buffer("earlyprintk", &sci_driver,
early_serial_buf, ARRAY_SIZE(early_serial_buf));
#endif
#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 1236b918e9f0..d0fa23c5a2b2 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -322,7 +322,7 @@ extern int platform_pm_restore(struct device *dev);
* drivers. It should go away once we introduce the new platform_device-based
* early driver framework.
*/
-static inline int is_early_platform_device(struct platform_device *pdev)
+static inline int is_sh_early_platform_device(struct platform_device *pdev)
{
return 0;
}
--
2.17.0
^ permalink raw reply related
* [PATCH v3 2/3] platform: move the early platform device support to arch/sh
From: Bartosz Golaszewski @ 2018-05-04 13:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504132731.14574-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
SuperH is the only user of the current implementation of early platform
device support. We want to introduce a more robust approach to early
probing. As the first step - move all the current early platform code
to arch/sh.
In order not to export internal drivers/base functions to arch code for
this temporary solution - copy the two needed routines for driver
matching from drivers/base/platform.c to arch/sh/drivers/platform_early.c.
Also: call early_platform_cleanup() from subsys_initcall() so that it's
called after all early devices are probed.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/sh/drivers/Makefile | 2 +-
arch/sh/drivers/platform_early.c | 346 +++++++++++++++++++++++++
arch/sh/include/asm/platform_early.h | 61 +++++
arch/sh/kernel/cpu/sh2/setup-sh7619.c | 1 +
arch/sh/kernel/cpu/sh2a/setup-mxg.c | 1 +
arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 1 +
arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 1 +
arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 1 +
arch/sh/kernel/cpu/sh2a/setup-sh7264.c | 1 +
arch/sh/kernel/cpu/sh2a/setup-sh7269.c | 1 +
arch/sh/kernel/cpu/sh3/setup-sh3.c | 1 +
arch/sh/kernel/cpu/sh3/setup-sh7705.c | 1 +
arch/sh/kernel/cpu/sh3/setup-sh770x.c | 1 +
arch/sh/kernel/cpu/sh3/setup-sh7710.c | 1 +
arch/sh/kernel/cpu/sh3/setup-sh7720.c | 1 +
arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 1 +
arch/sh/kernel/cpu/sh4/setup-sh7750.c | 1 +
arch/sh/kernel/cpu/sh4/setup-sh7760.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7734.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 1 +
arch/sh/kernel/cpu/sh4a/setup-shx3.c | 1 +
arch/sh/kernel/cpu/sh5/setup-sh5.c | 1 +
arch/sh/kernel/setup.c | 1 +
arch/sh/kernel/time.c | 1 +
drivers/base/platform.c | 288 --------------------
drivers/clocksource/sh_cmt.c | 7 +
drivers/clocksource/sh_mtu2.c | 7 +
drivers/clocksource/sh_tmu.c | 8 +
drivers/tty/serial/sh-sci.c | 7 +-
include/linux/platform_device.h | 64 +----
40 files changed, 479 insertions(+), 342 deletions(-)
create mode 100644 arch/sh/drivers/platform_early.c
create mode 100644 arch/sh/include/asm/platform_early.h
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile
index 3e93b434e604..56b0acace6e7 100644
--- a/arch/sh/drivers/Makefile
+++ b/arch/sh/drivers/Makefile
@@ -3,7 +3,7 @@
# Makefile for the Linux SuperH-specific device drivers.
#
-obj-y += dma/
+obj-y += dma/ platform_early.o
obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_SUPERHYWAY) += superhyway/
diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
new file mode 100644
index 000000000000..bc094f6eb366
--- /dev/null
+++ b/arch/sh/drivers/platform_early.c
@@ -0,0 +1,346 @@
+// SPDX--License-Identifier: GPL-2.0
+
+#include <asm/platform_early.h>
+#include <linux/pm.h>
+
+static __initdata LIST_HEAD(early_platform_driver_list);
+static __initdata LIST_HEAD(early_platform_device_list);
+
+static const struct platform_device_id *
+platform_match_id(const struct platform_device_id *id,
+ struct platform_device *pdev)
+{
+ while (id->name[0]) {
+ if (strcmp(pdev->name, id->name) == 0) {
+ pdev->id_entry = id;
+ return id;
+ }
+ id++;
+ }
+ return NULL;
+}
+
+static int platform_match(struct device *dev, struct device_driver *drv)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct platform_driver *pdrv = to_platform_driver(drv);
+
+ /* When driver_override is set, only bind to the matching driver */
+ if (pdev->driver_override)
+ return !strcmp(pdev->driver_override, drv->name);
+
+ /* Then try to match against the id table */
+ if (pdrv->id_table)
+ return platform_match_id(pdrv->id_table, pdev) != NULL;
+
+ /* fall-back to driver name match */
+ return (strcmp(pdev->name, drv->name) == 0);
+}
+
+#ifdef CONFIG_PM
+static void device_pm_init_common(struct device *dev)
+{
+ if (!dev->power.early_init) {
+ spin_lock_init(&dev->power.lock);
+ dev->power.qos = NULL;
+ dev->power.early_init = true;
+ }
+}
+
+static void pm_runtime_early_init(struct device *dev)
+{
+ dev->power.disable_depth = 1;
+ device_pm_init_common(dev);
+}
+#else
+static void pm_runtime_early_init(struct device *dev) {}
+#endif
+
+/**
+ * early_platform_driver_register - register early platform driver
+ * @epdrv: early_platform driver structure
+ * @buf: string passed from early_param()
+ *
+ * Helper function for early_platform_init() / early_platform_init_buffer()
+ */
+int __init early_platform_driver_register(struct early_platform_driver *epdrv,
+ char *buf)
+{
+ char *tmp;
+ int n;
+
+ /* Simply add the driver to the end of the global list.
+ * Drivers will by default be put on the list in compiled-in order.
+ */
+ if (!epdrv->list.next) {
+ INIT_LIST_HEAD(&epdrv->list);
+ list_add_tail(&epdrv->list, &early_platform_driver_list);
+ }
+
+ /* If the user has specified device then make sure the driver
+ * gets prioritized. The driver of the last device specified on
+ * command line will be put first on the list.
+ */
+ n = strlen(epdrv->pdrv->driver.name);
+ if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
+ list_move(&epdrv->list, &early_platform_driver_list);
+
+ /* Allow passing parameters after device name */
+ if (buf[n] == '\0' || buf[n] == ',')
+ epdrv->requested_id = -1;
+ else {
+ epdrv->requested_id = simple_strtoul(&buf[n + 1],
+ &tmp, 10);
+
+ if (buf[n] != '.' || (tmp == &buf[n + 1])) {
+ epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
+ n = 0;
+ } else
+ n += strcspn(&buf[n + 1], ",") + 1;
+ }
+
+ if (buf[n] == ',')
+ n++;
+
+ if (epdrv->bufsize) {
+ memcpy(epdrv->buffer, &buf[n],
+ min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1));
+ epdrv->buffer[epdrv->bufsize - 1] = '\0';
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * early_platform_add_devices - adds a number of early platform devices
+ * @devs: array of early platform devices to add
+ * @num: number of early platform devices in array
+ *
+ * Used by early architecture code to register early platform devices and
+ * their platform data.
+ */
+void __init early_platform_add_devices(struct platform_device **devs, int num)
+{
+ struct device *dev;
+ int i;
+
+ /* simply add the devices to list */
+ for (i = 0; i < num; i++) {
+ dev = &devs[i]->dev;
+
+ if (!dev->devres_head.next) {
+ pm_runtime_early_init(dev);
+ INIT_LIST_HEAD(&dev->devres_head);
+ list_add_tail(&dev->devres_head,
+ &early_platform_device_list);
+ }
+ }
+}
+
+/**
+ * early_platform_driver_register_all - register early platform drivers
+ * @class_str: string to identify early platform driver class
+ *
+ * Used by architecture code to register all early platform drivers
+ * for a certain class. If omitted then only early platform drivers
+ * with matching kernel command line class parameters will be registered.
+ */
+void __init early_platform_driver_register_all(char *class_str)
+{
+ /* The "class_str" parameter may or may not be present on the kernel
+ * command line. If it is present then there may be more than one
+ * matching parameter.
+ *
+ * Since we register our early platform drivers using early_param()
+ * we need to make sure that they also get registered in the case
+ * when the parameter is missing from the kernel command line.
+ *
+ * We use parse_early_options() to make sure the early_param() gets
+ * called at least once. The early_param() may be called more than
+ * once since the name of the preferred device may be specified on
+ * the kernel command line. early_platform_driver_register() handles
+ * this case for us.
+ */
+ parse_early_options(class_str);
+}
+
+/**
+ * early_platform_match - find early platform device matching driver
+ * @epdrv: early platform driver structure
+ * @id: id to match against
+ */
+static struct platform_device * __init
+early_platform_match(struct early_platform_driver *epdrv, int id)
+{
+ struct platform_device *pd;
+
+ list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+ if (platform_match(&pd->dev, &epdrv->pdrv->driver))
+ if (pd->id == id)
+ return pd;
+
+ return NULL;
+}
+
+/**
+ * early_platform_left - check if early platform driver has matching devices
+ * @epdrv: early platform driver structure
+ * @id: return true if id or above exists
+ */
+static int __init early_platform_left(struct early_platform_driver *epdrv,
+ int id)
+{
+ struct platform_device *pd;
+
+ list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+ if (platform_match(&pd->dev, &epdrv->pdrv->driver))
+ if (pd->id >= id)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * early_platform_driver_probe_id - probe drivers matching class_str and id
+ * @class_str: string to identify early platform driver class
+ * @id: id to match against
+ * @nr_probe: number of platform devices to successfully probe before exiting
+ */
+static int __init early_platform_driver_probe_id(char *class_str,
+ int id,
+ int nr_probe)
+{
+ struct early_platform_driver *epdrv;
+ struct platform_device *match;
+ int match_id;
+ int n = 0;
+ int left = 0;
+
+ list_for_each_entry(epdrv, &early_platform_driver_list, list) {
+ /* only use drivers matching our class_str */
+ if (strcmp(class_str, epdrv->class_str))
+ continue;
+
+ if (id == -2) {
+ match_id = epdrv->requested_id;
+ left = 1;
+
+ } else {
+ match_id = id;
+ left += early_platform_left(epdrv, id);
+
+ /* skip requested id */
+ switch (epdrv->requested_id) {
+ case EARLY_PLATFORM_ID_ERROR:
+ case EARLY_PLATFORM_ID_UNSET:
+ break;
+ default:
+ if (epdrv->requested_id == id)
+ match_id = EARLY_PLATFORM_ID_UNSET;
+ }
+ }
+
+ switch (match_id) {
+ case EARLY_PLATFORM_ID_ERROR:
+ pr_warn("%s: unable to parse %s parameter\n",
+ class_str, epdrv->pdrv->driver.name);
+ /* fall-through */
+ case EARLY_PLATFORM_ID_UNSET:
+ match = NULL;
+ break;
+ default:
+ match = early_platform_match(epdrv, match_id);
+ }
+
+ if (match) {
+ /*
+ * Set up a sensible init_name to enable
+ * dev_name() and others to be used before the
+ * rest of the driver core is initialized.
+ */
+ if (!match->dev.init_name && slab_is_available()) {
+ if (match->id != -1)
+ match->dev.init_name =
+ kasprintf(GFP_KERNEL, "%s.%d",
+ match->name,
+ match->id);
+ else
+ match->dev.init_name =
+ kasprintf(GFP_KERNEL, "%s",
+ match->name);
+
+ if (!match->dev.init_name)
+ return -ENOMEM;
+ }
+
+ if (epdrv->pdrv->probe(match))
+ pr_warn("%s: unable to probe %s early.\n",
+ class_str, match->name);
+ else
+ n++;
+ }
+
+ if (n >= nr_probe)
+ break;
+ }
+
+ if (left)
+ return n;
+ else
+ return -ENODEV;
+}
+
+/**
+ * early_platform_driver_probe - probe a class of registered drivers
+ * @class_str: string to identify early platform driver class
+ * @nr_probe: number of platform devices to successfully probe before exiting
+ * @user_only: only probe user specified early platform devices
+ *
+ * Used by architecture code to probe registered early platform drivers
+ * within a certain class. For probe to happen a registered early platform
+ * device matching a registered early platform driver is needed.
+ */
+int __init early_platform_driver_probe(char *class_str,
+ int nr_probe,
+ int user_only)
+{
+ int k, n, i;
+
+ n = 0;
+ for (i = -2; n < nr_probe; i++) {
+ k = early_platform_driver_probe_id(class_str, i, nr_probe - n);
+
+ if (k < 0)
+ break;
+
+ n += k;
+
+ if (user_only)
+ break;
+ }
+
+ return n;
+}
+
+/**
+ * early_platform_cleanup - clean up early platform code
+ */
+static int __init early_platform_cleanup(void)
+{
+ struct platform_device *pd, *pd2;
+
+ /* clean up the devres list used to chain devices */
+ list_for_each_entry_safe(pd, pd2, &early_platform_device_list,
+ dev.devres_head) {
+ list_del(&pd->dev.devres_head);
+ memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
+ }
+
+ return 0;
+}
+/*
+ * This must happen once after all early devices are probed but before probing
+ * real platform devices.
+ */
+subsys_initcall(early_platform_cleanup);
diff --git a/arch/sh/include/asm/platform_early.h b/arch/sh/include/asm/platform_early.h
new file mode 100644
index 000000000000..4590ab757d5f
--- /dev/null
+++ b/arch/sh/include/asm/platform_early.h
@@ -0,0 +1,61 @@
+/* SPDX--License-Identifier: GPL-2.0 */
+
+#ifndef __PLATFORM_EARLY__
+#define __PLATFORM_EARLY__
+
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+struct early_platform_driver {
+ const char *class_str;
+ struct platform_driver *pdrv;
+ struct list_head list;
+ int requested_id;
+ char *buffer;
+ int bufsize;
+};
+
+#define EARLY_PLATFORM_ID_UNSET -2
+#define EARLY_PLATFORM_ID_ERROR -3
+
+extern int early_platform_driver_register(struct early_platform_driver *epdrv,
+ char *buf);
+extern void early_platform_add_devices(struct platform_device **devs, int num);
+
+static inline int is_early_platform_device(struct platform_device *pdev)
+{
+ return !pdev->dev.driver;
+}
+
+extern void early_platform_driver_register_all(char *class_str);
+extern int early_platform_driver_probe(char *class_str,
+ int nr_probe, int user_only);
+
+#define early_platform_init(class_string, platdrv) \
+ early_platform_init_buffer(class_string, platdrv, NULL, 0)
+
+#ifndef MODULE
+#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
+static __initdata struct early_platform_driver early_driver = { \
+ .class_str = class_string, \
+ .buffer = buf, \
+ .bufsize = bufsiz, \
+ .pdrv = platdrv, \
+ .requested_id = EARLY_PLATFORM_ID_UNSET, \
+}; \
+static int __init early_platform_driver_setup_func(char *buffer) \
+{ \
+ return early_platform_driver_register(&early_driver, buffer); \
+} \
+early_param(class_string, early_platform_driver_setup_func)
+#else /* MODULE */
+#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
+static inline char *early_platform_driver_setup_func(void) \
+{ \
+ return bufsiz ? buf : NULL; \
+}
+#endif /* MODULE */
+
+#endif /* __PLATFORM_EARLY__ */
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index d08db08dec38..a02fc03baef8 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -15,6 +15,7 @@
#include <linux/sh_eth.h>
#include <linux/sh_timer.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
index 060fdd369f09..d33568a12fad 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
@@ -12,6 +12,7 @@
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
index c1301f68d3cd..b258c5c3af60 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
@@ -14,6 +14,7 @@
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index 32ec732e28e5..db3f8df8d76d 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -13,6 +13,7 @@
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index 8d8d354851ce..e1be4fedc739 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -14,6 +14,7 @@
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
index ab71eab690fd..b5bed10d0d72 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c
@@ -14,6 +14,7 @@
#include <linux/usb/r8a66597.h>
#include <linux/sh_timer.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
index c7e81b20967c..248a6732397a 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c
@@ -15,6 +15,7 @@
#include <linux/usb/r8a66597.h>
#include <linux/sh_timer.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c
index 53be70b98116..65a83ea4bde4 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh3.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
/* All SH3 devices are equipped with IRQ0->5 (except sh7708) */
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index f6e392e0d27e..7ec8c11c2f7a 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -17,6 +17,7 @@
#include <linux/sh_intc.h>
#include <asm/rtc.h>
#include <cpu/serial.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index 59a88611df55..20839dd40a2f 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -21,6 +21,7 @@
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <cpu/serial.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index ea52410b430d..780ccd202bab 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -16,6 +16,7 @@
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <asm/rtc.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index bf34b4e2e9ef..723bd9c04c8a 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -22,6 +22,7 @@
#include <linux/sh_intc.h>
#include <linux/usb/ohci_pdriver.h>
#include <asm/rtc.h>
+#include <asm/platform_early.h>
#include <cpu/serial.h>
static struct resource rtc_resources[] = {
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
index 2623f820d510..4a5fa86006cd 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
@@ -15,6 +15,7 @@
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
static struct plat_sci_port scif0_platform_data = {
.scscr = SCSCR_REIE,
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index 57d30689204d..abb3703c2273 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -16,6 +16,7 @@
#include <linux/sh_intc.h>
#include <linux/serial_sci.h>
#include <generated/machtypes.h>
+#include <asm/platform_early.h>
static struct resource rtc_resources[] = {
[0] = {
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index e51fe1734e13..649f4dcb5935 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -14,6 +14,7 @@
#include <linux/sh_intc.h>
#include <linux/serial_sci.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 5788073a7c30..73715a635048 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -15,6 +15,7 @@
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <asm/clock.h>
+#include <asm/platform_early.h>
/* Serial */
static struct plat_sci_port scif0_platform_data = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 646918713d9a..942856048112 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -18,6 +18,7 @@
#include <linux/sh_intc.h>
#include <linux/usb/r8a66597.h>
#include <asm/clock.h>
+#include <asm/platform_early.h>
static struct plat_sci_port scif0_platform_data = {
.scscr = SCSCR_REIE,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 6b3a26e61abb..bf60456a8012 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -21,6 +21,7 @@
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <asm/siu.h>
+#include <asm/platform_early.h>
#include <cpu/dma-register.h>
#include <cpu/sh7722.h>
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 1c1b3c469831..d25d3c3b44ab 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -19,6 +19,7 @@
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
+#include <asm/platform_early.h>
#include <cpu/sh7723.h>
/* Serial */
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index c20258b18775..0eeadabc8065 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -27,6 +27,7 @@
#include <asm/suspend.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
+#include <asm/platform_early.h>
#include <cpu/dma-register.h>
#include <cpu/sh7724.h>
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c
index 8c0c9da6b5b3..bed9d01fa85f 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/irq.h>
+#include <asm/platform_early.h>
#include <cpu/sh7734.h>
/* SCIF */
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index a46a19b49e08..b5b19e81a8dc 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -22,6 +22,7 @@
#include <linux/usb/ohci_pdriver.h>
#include <cpu/dma-register.h>
#include <cpu/sh7757.h>
+#include <asm/platform_early.h>
static struct plat_sci_port scif2_platform_data = {
.scscr = SCSCR_REIE,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index 40e6cda914d3..51a6c64f860e 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/serial_sci.h>
#include <linux/usb/ohci_pdriver.h>
+#include <asm/platform_early.h>
static struct plat_sci_port scif0_platform_data = {
.scscr = SCSCR_REIE,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
index 82e3bdf2e1b6..77f228e20599 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
@@ -14,6 +14,7 @@
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <linux/io.h>
+#include <asm/platform_early.h>
static struct plat_sci_port scif0_platform_data = {
.scscr = SCSCR_REIE | SCSCR_TOIE,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index d90ff67a4633..c4cbb7584122 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -16,6 +16,7 @@
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <cpu/dma-register.h>
+#include <asm/platform_early.h>
static struct plat_sci_port scif0_platform_data = {
.scscr = SCSCR_REIE | SCSCR_CKE1,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index b0d6f82f2d71..eda0d61ebf71 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -17,6 +17,7 @@
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <asm/mmzone.h>
+#include <asm/platform_early.h>
#include <cpu/dma-register.h>
static struct plat_sci_port scif0_platform_data = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 17aac38a6e90..77226a60c36f 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -26,6 +26,7 @@
#include <linux/usb/ohci_pdriver.h>
#include <cpu/dma-register.h>
#include <asm/mmzone.h>
+#include <asm/platform_early.h>
static struct plat_sci_port scif0_platform_data = {
.scscr = SCSCR_REIE | SCSCR_CKE1,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index ee14d92d840f..83feaf0a4aae 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -17,6 +17,7 @@
#include <linux/sh_intc.h>
#include <cpu/shx3.h>
#include <asm/mmzone.h>
+#include <asm/platform_early.h>
/*
* This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c
index 084a9cc99175..8ebd26a9fd90 100644
--- a/arch/sh/kernel/cpu/sh5/setup-sh5.c
+++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c
@@ -15,6 +15,7 @@
#include <linux/mm.h>
#include <linux/sh_timer.h>
#include <asm/addrspace.h>
+#include <asm/platform_early.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_IOREMAP,
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index d34e998b809f..c9610a2b0888 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -44,6 +44,7 @@
#include <asm/mmu_context.h>
#include <asm/mmzone.h>
#include <asm/sparsemem.h>
+#include <asm/platform_early.h>
/*
* Initialize loops_per_jiffy as 10000000 (1000MIPS).
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index fcd5e41977d1..674d8413491b 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -21,6 +21,7 @@
#include <linux/rtc.h>
#include <asm/clock.h>
#include <asm/rtc.h>
+#include <asm/platform_early.h>
/* Dummy RTC ops */
static void null_rtc_get_time(struct timespec *tv)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8075ddc70a17..70b156ee267a 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1150,8 +1150,6 @@ int __init platform_bus_init(void)
{
int error;
- early_platform_cleanup();
-
error = device_register(&platform_bus);
if (error) {
put_device(&platform_bus);
@@ -1185,289 +1183,3 @@ u64 dma_get_required_mask(struct device *dev)
}
EXPORT_SYMBOL_GPL(dma_get_required_mask);
#endif
-
-static __initdata LIST_HEAD(early_platform_driver_list);
-static __initdata LIST_HEAD(early_platform_device_list);
-
-/**
- * early_platform_driver_register - register early platform driver
- * @epdrv: early_platform driver structure
- * @buf: string passed from early_param()
- *
- * Helper function for early_platform_init() / early_platform_init_buffer()
- */
-int __init early_platform_driver_register(struct early_platform_driver *epdrv,
- char *buf)
-{
- char *tmp;
- int n;
-
- /* Simply add the driver to the end of the global list.
- * Drivers will by default be put on the list in compiled-in order.
- */
- if (!epdrv->list.next) {
- INIT_LIST_HEAD(&epdrv->list);
- list_add_tail(&epdrv->list, &early_platform_driver_list);
- }
-
- /* If the user has specified device then make sure the driver
- * gets prioritized. The driver of the last device specified on
- * command line will be put first on the list.
- */
- n = strlen(epdrv->pdrv->driver.name);
- if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
- list_move(&epdrv->list, &early_platform_driver_list);
-
- /* Allow passing parameters after device name */
- if (buf[n] == '\0' || buf[n] == ',')
- epdrv->requested_id = -1;
- else {
- epdrv->requested_id = simple_strtoul(&buf[n + 1],
- &tmp, 10);
-
- if (buf[n] != '.' || (tmp == &buf[n + 1])) {
- epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
- n = 0;
- } else
- n += strcspn(&buf[n + 1], ",") + 1;
- }
-
- if (buf[n] == ',')
- n++;
-
- if (epdrv->bufsize) {
- memcpy(epdrv->buffer, &buf[n],
- min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1));
- epdrv->buffer[epdrv->bufsize - 1] = '\0';
- }
- }
-
- return 0;
-}
-
-/**
- * early_platform_add_devices - adds a number of early platform devices
- * @devs: array of early platform devices to add
- * @num: number of early platform devices in array
- *
- * Used by early architecture code to register early platform devices and
- * their platform data.
- */
-void __init early_platform_add_devices(struct platform_device **devs, int num)
-{
- struct device *dev;
- int i;
-
- /* simply add the devices to list */
- for (i = 0; i < num; i++) {
- dev = &devs[i]->dev;
-
- if (!dev->devres_head.next) {
- pm_runtime_early_init(dev);
- INIT_LIST_HEAD(&dev->devres_head);
- list_add_tail(&dev->devres_head,
- &early_platform_device_list);
- }
- }
-}
-
-/**
- * early_platform_driver_register_all - register early platform drivers
- * @class_str: string to identify early platform driver class
- *
- * Used by architecture code to register all early platform drivers
- * for a certain class. If omitted then only early platform drivers
- * with matching kernel command line class parameters will be registered.
- */
-void __init early_platform_driver_register_all(char *class_str)
-{
- /* The "class_str" parameter may or may not be present on the kernel
- * command line. If it is present then there may be more than one
- * matching parameter.
- *
- * Since we register our early platform drivers using early_param()
- * we need to make sure that they also get registered in the case
- * when the parameter is missing from the kernel command line.
- *
- * We use parse_early_options() to make sure the early_param() gets
- * called at least once. The early_param() may be called more than
- * once since the name of the preferred device may be specified on
- * the kernel command line. early_platform_driver_register() handles
- * this case for us.
- */
- parse_early_options(class_str);
-}
-
-/**
- * early_platform_match - find early platform device matching driver
- * @epdrv: early platform driver structure
- * @id: id to match against
- */
-static struct platform_device * __init
-early_platform_match(struct early_platform_driver *epdrv, int id)
-{
- struct platform_device *pd;
-
- list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
- if (platform_match(&pd->dev, &epdrv->pdrv->driver))
- if (pd->id == id)
- return pd;
-
- return NULL;
-}
-
-/**
- * early_platform_left - check if early platform driver has matching devices
- * @epdrv: early platform driver structure
- * @id: return true if id or above exists
- */
-static int __init early_platform_left(struct early_platform_driver *epdrv,
- int id)
-{
- struct platform_device *pd;
-
- list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
- if (platform_match(&pd->dev, &epdrv->pdrv->driver))
- if (pd->id >= id)
- return 1;
-
- return 0;
-}
-
-/**
- * early_platform_driver_probe_id - probe drivers matching class_str and id
- * @class_str: string to identify early platform driver class
- * @id: id to match against
- * @nr_probe: number of platform devices to successfully probe before exiting
- */
-static int __init early_platform_driver_probe_id(char *class_str,
- int id,
- int nr_probe)
-{
- struct early_platform_driver *epdrv;
- struct platform_device *match;
- int match_id;
- int n = 0;
- int left = 0;
-
- list_for_each_entry(epdrv, &early_platform_driver_list, list) {
- /* only use drivers matching our class_str */
- if (strcmp(class_str, epdrv->class_str))
- continue;
-
- if (id == -2) {
- match_id = epdrv->requested_id;
- left = 1;
-
- } else {
- match_id = id;
- left += early_platform_left(epdrv, id);
-
- /* skip requested id */
- switch (epdrv->requested_id) {
- case EARLY_PLATFORM_ID_ERROR:
- case EARLY_PLATFORM_ID_UNSET:
- break;
- default:
- if (epdrv->requested_id == id)
- match_id = EARLY_PLATFORM_ID_UNSET;
- }
- }
-
- switch (match_id) {
- case EARLY_PLATFORM_ID_ERROR:
- pr_warn("%s: unable to parse %s parameter\n",
- class_str, epdrv->pdrv->driver.name);
- /* fall-through */
- case EARLY_PLATFORM_ID_UNSET:
- match = NULL;
- break;
- default:
- match = early_platform_match(epdrv, match_id);
- }
-
- if (match) {
- /*
- * Set up a sensible init_name to enable
- * dev_name() and others to be used before the
- * rest of the driver core is initialized.
- */
- if (!match->dev.init_name && slab_is_available()) {
- if (match->id != -1)
- match->dev.init_name =
- kasprintf(GFP_KERNEL, "%s.%d",
- match->name,
- match->id);
- else
- match->dev.init_name =
- kasprintf(GFP_KERNEL, "%s",
- match->name);
-
- if (!match->dev.init_name)
- return -ENOMEM;
- }
-
- if (epdrv->pdrv->probe(match))
- pr_warn("%s: unable to probe %s early.\n",
- class_str, match->name);
- else
- n++;
- }
-
- if (n >= nr_probe)
- break;
- }
-
- if (left)
- return n;
- else
- return -ENODEV;
-}
-
-/**
- * early_platform_driver_probe - probe a class of registered drivers
- * @class_str: string to identify early platform driver class
- * @nr_probe: number of platform devices to successfully probe before exiting
- * @user_only: only probe user specified early platform devices
- *
- * Used by architecture code to probe registered early platform drivers
- * within a certain class. For probe to happen a registered early platform
- * device matching a registered early platform driver is needed.
- */
-int __init early_platform_driver_probe(char *class_str,
- int nr_probe,
- int user_only)
-{
- int k, n, i;
-
- n = 0;
- for (i = -2; n < nr_probe; i++) {
- k = early_platform_driver_probe_id(class_str, i, nr_probe - n);
-
- if (k < 0)
- break;
-
- n += k;
-
- if (user_only)
- break;
- }
-
- return n;
-}
-
-/**
- * early_platform_cleanup - clean up early platform code
- */
-void __init early_platform_cleanup(void)
-{
- struct platform_device *pd, *pd2;
-
- /* clean up the devres list used to chain devices */
- list_for_each_entry_safe(pd, pd2, &early_platform_device_list,
- dev.devres_head) {
- list_del(&pd->dev.devres_head);
- memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
- }
-}
-
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 70b3cf8e23d0..3ce69160efc1 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -33,6 +33,10 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
+#ifdef CONFIG_SUPERH
+#include <asm/platform_early.h>
+#endif
+
struct sh_cmt_device;
/*
@@ -1100,7 +1104,10 @@ static void __exit sh_cmt_exit(void)
platform_driver_unregister(&sh_cmt_device_driver);
}
+#ifdef CONFIG_SUPERH
early_platform_init("earlytimer", &sh_cmt_device_driver);
+#endif
+
subsys_initcall(sh_cmt_init);
module_exit(sh_cmt_exit);
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index 53aa7e92a7d7..b8211987b02b 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -31,6 +31,10 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
+#ifdef CONFIG_SUPERH
+#include <asm/platform_early.h>
+#endif
+
struct sh_mtu2_device;
struct sh_mtu2_channel {
@@ -519,7 +523,10 @@ static void __exit sh_mtu2_exit(void)
platform_driver_unregister(&sh_mtu2_device_driver);
}
+#ifdef CONFIG_SUPERH
early_platform_init("earlytimer", &sh_mtu2_device_driver);
+#endif
+
subsys_initcall(sh_mtu2_init);
module_exit(sh_mtu2_exit);
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index 31d881621e41..3d929129ed68 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -32,6 +32,10 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
+#ifdef CONFIG_SUPERH
+#include <asm/platform_early.h>
+#endif
+
enum sh_tmu_model {
SH_TMU,
SH_TMU_SH3,
@@ -626,6 +630,7 @@ static int sh_tmu_probe(struct platform_device *pdev)
pm_runtime_idle(&pdev->dev);
return ret;
}
+
if (is_early_platform_device(pdev))
return 0;
@@ -676,7 +681,10 @@ static void __exit sh_tmu_exit(void)
platform_driver_unregister(&sh_tmu_device_driver);
}
+#ifdef CONFIG_SUPERH
early_platform_init("earlytimer", &sh_tmu_device_driver);
+#endif
+
subsys_initcall(sh_tmu_init);
module_exit(sh_tmu_exit);
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index fdbbff547106..37faf3d8d647 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -54,6 +54,7 @@
#ifdef CONFIG_SUPERH
#include <asm/sh_bios.h>
+#include <asm/platform_early.h>
#endif
#include "serial_mctrl_gpio.h"
@@ -2968,6 +2969,7 @@ static struct console serial_console = {
.data = &sci_uart_driver,
};
+#ifdef CONFIG_SUPERH
static struct console early_serial_console = {
.name = "early_ttySC",
.write = serial_console_write,
@@ -2996,6 +2998,7 @@ static int sci_probe_earlyprintk(struct platform_device *pdev)
register_console(&early_serial_console);
return 0;
}
+#endif
#define SCI_CONSOLE (&serial_console)
@@ -3192,8 +3195,10 @@ static int sci_probe(struct platform_device *dev)
* the special early probe. We don't have sufficient device state
* to make it beyond this yet.
*/
+#ifdef CONFIG_SUPERH
if (is_early_platform_device(dev))
return sci_probe_earlyprintk(dev);
+#endif
if (dev->dev.of_node) {
p = sci_parse_dt(dev, &dev_id);
@@ -3289,7 +3294,7 @@ static void __exit sci_exit(void)
uart_unregister_driver(&sci_uart_driver);
}
-#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
+#if defined(CONFIG_SUPERH) && defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
early_platform_init_buffer("earlyprintk", &sci_driver,
early_serial_buf, ARRAY_SIZE(early_serial_buf));
#endif
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 49f634d96118..1236b918e9f0 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -284,58 +284,6 @@ void platform_unregister_drivers(struct platform_driver * const *drivers,
#define platform_register_drivers(drivers, count) \
__platform_register_drivers(drivers, count, THIS_MODULE)
-/* early platform driver interface */
-struct early_platform_driver {
- const char *class_str;
- struct platform_driver *pdrv;
- struct list_head list;
- int requested_id;
- char *buffer;
- int bufsize;
-};
-
-#define EARLY_PLATFORM_ID_UNSET -2
-#define EARLY_PLATFORM_ID_ERROR -3
-
-extern int early_platform_driver_register(struct early_platform_driver *epdrv,
- char *buf);
-extern void early_platform_add_devices(struct platform_device **devs, int num);
-
-static inline int is_early_platform_device(struct platform_device *pdev)
-{
- return !pdev->dev.driver;
-}
-
-extern void early_platform_driver_register_all(char *class_str);
-extern int early_platform_driver_probe(char *class_str,
- int nr_probe, int user_only);
-extern void early_platform_cleanup(void);
-
-#define early_platform_init(class_string, platdrv) \
- early_platform_init_buffer(class_string, platdrv, NULL, 0)
-
-#ifndef MODULE
-#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
-static __initdata struct early_platform_driver early_driver = { \
- .class_str = class_string, \
- .buffer = buf, \
- .bufsize = bufsiz, \
- .pdrv = platdrv, \
- .requested_id = EARLY_PLATFORM_ID_UNSET, \
-}; \
-static int __init early_platform_driver_setup_func(char *buffer) \
-{ \
- return early_platform_driver_register(&early_driver, buffer); \
-} \
-early_param(class_string, early_platform_driver_setup_func)
-#else /* MODULE */
-#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
-static inline char *early_platform_driver_setup_func(void) \
-{ \
- return bufsiz ? buf : NULL; \
-}
-#endif /* MODULE */
-
#ifdef CONFIG_SUSPEND
extern int platform_pm_suspend(struct device *dev);
extern int platform_pm_resume(struct device *dev);
@@ -368,4 +316,16 @@ extern int platform_pm_restore(struct device *dev);
#define USE_PLATFORM_PM_SLEEP_OPS
#endif
+#ifndef CONFIG_SUPERH
+/*
+ * REVISIT: This stub is needed for all non-SuperH users of early platform
+ * drivers. It should go away once we introduce the new platform_device-based
+ * early driver framework.
+ */
+static inline int is_early_platform_device(struct platform_device *pdev)
+{
+ return 0;
+}
+#endif /* CONFIG_SUPERH */
+
#endif /* _PLATFORM_DEVICE_H_ */
--
2.17.0
^ permalink raw reply related
* [PATCH v3 1/3] clocksource: timer-ti-dm: remove the early platform driver registration
From: Bartosz Golaszewski @ 2018-05-04 13:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504132731.14574-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This driver is no longer used as an early platform driver. Remove the
registration macro.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/clocksource/timer-ti-dm.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index 4cce6b224b87..595124074821 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -991,7 +991,6 @@ static struct platform_driver omap_dm_timer_driver = {
},
};
-early_platform_init("earlytimer", &omap_dm_timer_driver);
module_platform_driver(omap_dm_timer_driver);
MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
--
2.17.0
^ permalink raw reply related
* [PATCH v3 0/3] sh: make early_platform code SuperH-specific
From: Bartosz Golaszewski @ 2018-05-04 13:27 UTC (permalink / raw)
To: linux-arm-kernel
I recently started a discussion about the need for a proper early device
probing mechanism[1]. One that would be based on real platform drivers
and support both platform data and device tree.
While we're far from reaching any consensus on the implementation, Arnd
suggested that I start off by moving the SuperH-specific early platform
drivers implementation to arch/sh[2].
This series is the first attempt at making way for a new, less hacky
implementation.
The first patch removes the last instance of a non-sh driver using the
early_platform API. It can be removed since ARM no longer probes early
drivers.
The second patch moves all the early_platform code to arch/sh.
The last patch prefixes all early_platform symbols with 'sh_'.
[1] https://lkml.org/lkml/2018/4/26/657
[2] https://lkml.org/lkml/2018/4/27/239
v1 -> v2:
- certain drivers are compiled for arm/mach-shmobile too - we need to
add ifdefs for CONFIG_SUPERH around early_platform calls
v2 -> v3:
- added a stub for is_early_platform_device() which always returns false
on non-SuperH architectures
Bartosz Golaszewski (3):
clocksource: timer-ti-dm: remove the early platform driver
registration
platform: move the early platform device support to arch/sh
sh: add the sh_ prefix to early platform symbols
arch/sh/drivers/Makefile | 2 +-
arch/sh/drivers/platform_early.c | 346 +++++++++++++++++++++++++
arch/sh/include/asm/platform_early.h | 61 +++++
arch/sh/kernel/cpu/sh2/setup-sh7619.c | 3 +-
arch/sh/kernel/cpu/sh2a/setup-mxg.c | 3 +-
arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 3 +-
arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 3 +-
arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 3 +-
arch/sh/kernel/cpu/sh2a/setup-sh7264.c | 3 +-
arch/sh/kernel/cpu/sh2a/setup-sh7269.c | 3 +-
arch/sh/kernel/cpu/sh3/setup-sh3.c | 1 +
arch/sh/kernel/cpu/sh3/setup-sh7705.c | 3 +-
arch/sh/kernel/cpu/sh3/setup-sh770x.c | 3 +-
arch/sh/kernel/cpu/sh3/setup-sh7710.c | 3 +-
arch/sh/kernel/cpu/sh3/setup-sh7720.c | 3 +-
arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 3 +-
arch/sh/kernel/cpu/sh4/setup-sh7750.c | 9 +-
arch/sh/kernel/cpu/sh4/setup-sh7760.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7734.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 3 +-
arch/sh/kernel/cpu/sh4a/setup-shx3.c | 3 +-
arch/sh/kernel/cpu/sh5/setup-sh5.c | 3 +-
arch/sh/kernel/setup.c | 3 +-
arch/sh/kernel/time.c | 5 +-
drivers/base/platform.c | 288 --------------------
drivers/clocksource/sh_cmt.c | 13 +-
drivers/clocksource/sh_mtu2.c | 13 +-
drivers/clocksource/sh_tmu.c | 14 +-
drivers/clocksource/timer-ti-dm.c | 1 -
drivers/tty/serial/sh-sci.c | 11 +-
include/linux/platform_device.h | 64 +----
41 files changed, 524 insertions(+), 388 deletions(-)
create mode 100644 arch/sh/drivers/platform_early.c
create mode 100644 arch/sh/include/asm/platform_early.h
--
2.17.0
^ permalink raw reply
* [PATCH v7 0/2] PCI: mediatek: Fixups for the IRQ handle routine and MT7622's class code
From: Lorenzo Pieralisi @ 2018-05-04 13:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525412853-24367-1-git-send-email-honghui.zhang@mediatek.com>
On Fri, May 04, 2018 at 01:47:31PM +0800, honghui.zhang at mediatek.com wrote:
> From: Honghui Zhang <honghui.zhang@mediatek.com>
>
> Two fixups for mediatek's host bridge:
> The first patch fixup class type and vendor ID for MT7622.
> The second patch fixup the IRQ handle routine by using irq_chip solution
> to avoid IRQ reentry which may exist for both MT2712 and MT7622.
>
> Change since v6:
> - Remove the irq_mask, irq_unmask callback in lower layer irq_chip since we
> have set the MSI_FLAG_USE_DEF_CHIP_OPS flags.
> - Add irq_ack callback in irq_chip to handle edge IRQ.
> - Uing handle_edge_irq to handle the MSI IRQs.
>
> Change since v5:
> - Make the comments consistend with the code modification in the first patch.
> - Using writew to performing a 16-bit write.
> - Using irq_chip solution to fix the IRQ issue.
>
> The v5 patchset could be found in:
> https://patchwork.kernel.org/patch/10133303
> https://patchwork.kernel.org/patch/10133305
>
> Change since v4:
> - Only setup vendor ID for MT7622, igorning the device ID since mediatek's
> host bridge driver does not cares about the device ID.
>
> Change since v3:
> - Setup the class type and vendor ID at the beginning of startup instead
> of in a quirk.
> - Add mediatek's vendor ID, it could be found in:
> https://pcisig.com/membership/member-companies?combine=&page=4
>
> Change since v2:
> - Move the initialize of the iterate before the loop to fix an
> INTx IRQ issue in the first patch
>
> Change since v1:
> - Add the second patch.
> - Make the first patch's commit message more standard.
>
> Honghui Zhang (2):
> PCI: mediatek: Set up vendor ID and class type for MT7622
> PCI: mediatek: Using chained IRQ to setup IRQ handle
>
> drivers/pci/host/pcie-mediatek.c | 234 +++++++++++++++++++++++----------------
> include/linux/pci_ids.h | 2 +
> 2 files changed, 143 insertions(+), 93 deletions(-)
Applied to pci/mediatek for v4.18, thanks.
Lorenzo
^ permalink raw reply
* Potential deadlock in vgic
From: Jan Glauber @ 2018-05-04 13:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504124742.GG10191@C02W217FHV2R.local>
On Fri, May 04, 2018 at 02:47:42PM +0200, Christoffer Dall wrote:
> Hi Jan,
>
> On Fri, May 04, 2018 at 01:03:44PM +0200, Jan Glauber wrote:
> > Hi all,
> >
> > enabling lockdep I see the following reported in the host when I start a kvm guest:
> >
> > [12399.954245] CPU0 CPU1
> > [12399.958762] ---- ----
> > [12399.963279] lock(&(&dist->lpi_list_lock)->rlock);
> > [12399.968146] local_irq_disable();
> > [12399.974052] lock(&(&vgic_cpu->ap_list_lock)->rlock);
> > [12399.981696] lock(&(&dist->lpi_list_lock)->rlock);
> > [12399.989081] <Interrupt>
> > [12399.991688] lock(&(&vgic_cpu->ap_list_lock)->rlock);
> > [12399.996989]
> > *** DEADLOCK ***
> >
> > [12400.002897] 2 locks held by qemu-system-aar/5597:
> > [12400.007587] #0: 0000000042beb9dc (&vcpu->mutex){+.+.}, at: kvm_vcpu_ioctl+0x7c/0xa68
> > [12400.015411] #1: 00000000c45d644a (&(&vgic_cpu->ap_list_lock)->rlock){-.-.}, at: kvm_vgic_sync_hwstate+0x8c/0x328
> >
> >
> > There is nothing unusual in my config or qemu parameters, I can upload these
> > if needed. I see this on ThunderX and ThunderX2 and also with older kernels
> > (4.13+ distribution kernel).
> >
> > I tried making the lpi_list_lock irq safe but that just leads to different
> > warnings. The locking here seems to be quite sophisticated and I'm not familiar
> > with it.
>
> That's unfortunate. The problem here is that we end up violating our
> locking order, which stipulates that ap_list_lock must be taken before
> the lpi_list_lock.
>
> Give that we can take the ap_list_lock from interrupt context (timers
> firing), the only solution I can easily think of is to change
> lpi_list_lock takers to disable interrupts as well.
>
> Which warnings did you encounter with that approach?
Hi Christoffer,
making lpi_list_lock irq safe I get:
[ 394.239174] ========================================================
[ 394.245515] WARNING: possible irq lock inversion dependency detected
[ 394.251857] 4.17.0-rc3-jang+ #72 Not tainted
[ 394.256114] --------------------------------------------------------
[ 394.262454] qemu-system-aar/5596 just changed the state of lock:
[ 394.268448] 00000000da3f09ef (&(&irq->irq_lock)->rlock#3){+...}, at: update_affinity+0x3c/0xa8
[ 394.277066] but this lock was taken by another, HARDIRQ-safe lock in the past:
[ 394.284274] (&(&vgic_cpu->ap_list_lock)->rlock){-.-.}
[ 394.284278]
and interrupts could create inverse lock ordering between them.
[ 394.300777]
other info that might help us debug this:
[ 394.307292] Possible interrupt unsafe locking scenario:
[ 394.314066] CPU0 CPU1
[ 394.318584] ---- ----
[ 394.323101] lock(&(&irq->irq_lock)->rlock#3);
[ 394.327622] local_irq_disable();
[ 394.333528] lock(&(&vgic_cpu->ap_list_lock)->rlock);
[ 394.341172] lock(&(&irq->irq_lock)->rlock#3);
[ 394.348210] <Interrupt>
[ 394.350817] lock(&(&vgic_cpu->ap_list_lock)->rlock);
[ 394.356118]
*** DEADLOCK ***
[ 394.362025] 4 locks held by qemu-system-aar/5596:
[ 394.366716] #0: 00000000719c7423 (&vcpu->mutex){+.+.}, at: kvm_vcpu_ioctl+0x7c/0xa68
[ 394.374545] #1: 0000000060090841 (&kvm->srcu){....}, at: kvm_handle_guest_abort+0x11c/0xb70
[ 394.382984] #2: 0000000064647766 (&its->cmd_lock){+.+.}, at: vgic_mmio_write_its_cwriter+0x44/0xa8
[ 394.392022] #3: 0000000075f90a8a (&its->its_lock){+.+.}, at: vgic_its_process_commands.part.11+0xac/0x780
^ permalink raw reply
* [PATCH] ARM: stm32: Select DMA, DMAMUX and MDMA support on STM32MP157C
From: Alexandre Torgue @ 2018-05-04 13:01 UTC (permalink / raw)
To: linux-arm-kernel
From: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
This patch select DMA, DMAMUX and MDMA support for STM32MP157C machine.
Signed-off-by: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
Signed-off-by: Alexandre Torgue <alexandre.torgue@st.com>
---
Hi Arnd, Kevin and Olof,
I merged several patchs in one so I just have this patch for STM32 SoC update,
so please consider it as my STM32 SOC pull request for v4.18.
Thanks
Alex
diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig
index 713c068..82a93b8 100644
--- a/arch/arm/mach-stm32/Kconfig
+++ b/arch/arm/mach-stm32/Kconfig
@@ -46,6 +46,9 @@ if ARCH_MULTI_V7
config MACH_STM32MP157
bool "STMicroelectronics STM32MP157"
+ select STM32_DMA
+ select STM32_DMAMUX
+ select STM32_MDMA
default y
endif # ARMv7-A
--
2.7.4
^ permalink raw reply related
* Potential deadlock in vgic
From: Christoffer Dall @ 2018-05-04 12:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504110343.GA10968@hc>
Hi Jan,
On Fri, May 04, 2018 at 01:03:44PM +0200, Jan Glauber wrote:
> Hi all,
>
> enabling lockdep I see the following reported in the host when I start a kvm guest:
>
> [12399.954245] CPU0 CPU1
> [12399.958762] ---- ----
> [12399.963279] lock(&(&dist->lpi_list_lock)->rlock);
> [12399.968146] local_irq_disable();
> [12399.974052] lock(&(&vgic_cpu->ap_list_lock)->rlock);
> [12399.981696] lock(&(&dist->lpi_list_lock)->rlock);
> [12399.989081] <Interrupt>
> [12399.991688] lock(&(&vgic_cpu->ap_list_lock)->rlock);
> [12399.996989]
> *** DEADLOCK ***
>
> [12400.002897] 2 locks held by qemu-system-aar/5597:
> [12400.007587] #0: 0000000042beb9dc (&vcpu->mutex){+.+.}, at: kvm_vcpu_ioctl+0x7c/0xa68
> [12400.015411] #1: 00000000c45d644a (&(&vgic_cpu->ap_list_lock)->rlock){-.-.}, at: kvm_vgic_sync_hwstate+0x8c/0x328
>
>
> There is nothing unusual in my config or qemu parameters, I can upload these
> if needed. I see this on ThunderX and ThunderX2 and also with older kernels
> (4.13+ distribution kernel).
>
> I tried making the lpi_list_lock irq safe but that just leads to different
> warnings. The locking here seems to be quite sophisticated and I'm not familiar
> with it.
That's unfortunate. The problem here is that we end up violating our
locking order, which stipulates that ap_list_lock must be taken before
the lpi_list_lock.
Give that we can take the ap_list_lock from interrupt context (timers
firing), the only solution I can easily think of is to change
lpi_list_lock takers to disable interrupts as well.
Which warnings did you encounter with that approach?
(I'll try to reproduce on my end).
Thanks,
-Christoffer
^ permalink raw reply
* [PATCH] ARM: multi_v7_defconfig: Add STM32F7 I2C & STM32 USBPHYC support
From: Alexandre Torgue @ 2018-05-04 12:46 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds STM32F7 I2C support to multi_v7_defconfig and
enable the STM32 USB PHY Controller (USBPHYC) driver, implemented on
STM32MP1 SoC.
Signed-off-by: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
Signed-off-by: Alexandre Torgue <alexandre.torgue@st.com>
---
Hi Arnd, Kevin and Olof,
I just have this patch for STM32 configs update, so please consider it as my
STM32 defconfig pull request for v4.18.
Thanks
Alex
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index e6b3c96..9d0856e 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -385,6 +385,7 @@ CONFIG_I2C_S3C2410=y
CONFIG_I2C_SH_MOBILE=y
CONFIG_I2C_SIRF=y
CONFIG_I2C_ST=y
+CONFIG_I2C_STM32F7=y
CONFIG_I2C_SUN6I_P2WI=y
CONFIG_I2C_TEGRA=y
CONFIG_I2C_UNIPHIER=y
@@ -972,6 +973,7 @@ CONFIG_PHY_QCOM_APQ8064_SATA=m
CONFIG_PHY_MIPHY28LP=y
CONFIG_PHY_RCAR_GEN2=m
CONFIG_PHY_STIH407_USB=y
+CONFIG_PHY_STM32_USBPHYC=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_SUN9I_USB=y
CONFIG_PHY_SAMSUNG_USB2=m
--
2.7.4
^ permalink raw reply related
* [PATCH v5 03/14] clk: qcom: Add CPU clock driver for msm8996
From: kbuild test robot @ 2018-05-04 12:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525348355-25471-4-git-send-email-ilialin@codeaurora.org>
Hi Ilia,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on clk/clk-next]
[also build test WARNING on v4.17-rc3 next-20180503]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Ilia-Lin/CPU-scaling-support-for-msm8996/20180504-174840
base: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
>> drivers/clk/qcom/clk-cpu-8996.c:142:9: sparse: constant 2150400000 is so big it is long
>> drivers/clk/qcom/clk-cpu-8996.c:239:22: sparse: symbol 'clk_cpu_8996_mux_ops' was not declared. Should it be static?
drivers/clk/qcom/clk-cpu-8996.c:324:19: sparse: symbol 'clks' was not declared. Should it be static?
vim +142 drivers/clk/qcom/clk-cpu-8996.c
137
138 static const struct pll_vco alt_pll_vco_modes[] = {
139 VCO(3, 250000000, 500000000),
140 VCO(2, 500000000, 750000000),
141 VCO(1, 750000000, 1000000000),
> 142 VCO(0, 1000000000, 2150400000),
143 };
144
145 static const struct alpha_pll_config altpll_config = {
146 .l = 16,
147 .vco_val = 0x3 << 20,
148 .vco_mask = 0x3 << 20,
149 .config_ctl_val = 0x4001051b,
150 .post_div_mask = 0x3 << 8,
151 .post_div_val = 0x1,
152 .main_output_mask = BIT(0),
153 .early_output_mask = BIT(3),
154 };
155
156 static struct clk_alpha_pll perfcl_alt_pll = {
157 .offset = 0x80100,
158 .regs = alt_pll_regs,
159 .vco_table = alt_pll_vco_modes,
160 .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
161 .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
162 .clkr.hw.init = &(struct clk_init_data) {
163 .name = "perfcl_alt_pll",
164 .parent_names = (const char *[]){ "xo" },
165 .num_parents = 1,
166 .ops = &clk_alpha_pll_hwfsm_ops,
167 },
168 };
169
170 static struct clk_alpha_pll pwrcl_alt_pll = {
171 .offset = 0x100,
172 .regs = alt_pll_regs,
173 .vco_table = alt_pll_vco_modes,
174 .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
175 .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
176 .clkr.hw.init = &(struct clk_init_data) {
177 .name = "pwrcl_alt_pll",
178 .parent_names = (const char *[]){ "xo" },
179 .num_parents = 1,
180 .ops = &clk_alpha_pll_hwfsm_ops,
181 },
182 };
183
184 /* Mux'es */
185
186 struct clk_cpu_8996_mux {
187 u32 reg;
188 u8 shift;
189 u8 width;
190 struct clk_hw *pll;
191 struct clk_regmap clkr;
192 };
193
194 static inline
195 struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
196 {
197 return container_of(to_clk_regmap(hw), struct clk_cpu_8996_mux, clkr);
198 }
199
200 static u8 clk_cpu_8996_mux_get_parent(struct clk_hw *hw)
201 {
202 u32 val;
203 struct clk_regmap *clkr = to_clk_regmap(hw);
204 struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
205 u32 mask = (u32)GENMASK(cpuclk->width - 1, 0);
206
207 regmap_read(clkr->regmap, cpuclk->reg, &val);
208 val >>= (u32)(cpuclk->shift);
209
210 return (u8)(val & mask);
211 }
212
213 static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
214 {
215 u32 val;
216 struct clk_regmap *clkr = to_clk_regmap(hw);
217 struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
218 unsigned int mask = GENMASK(cpuclk->width + cpuclk->shift - 1,
219 cpuclk->shift);
220
221 val = (u32)index;
222 val <<= (u32)(cpuclk->shift);
223
224 return regmap_update_bits(clkr->regmap, cpuclk->reg, mask, val);
225 }
226
227 static int
228 clk_cpu_8996_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
229 {
230 struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
231 struct clk_hw *parent = cpuclk->pll;
232
233 req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
234 req->best_parent_hw = parent;
235
236 return 0;
237 }
238
> 239 const struct clk_ops clk_cpu_8996_mux_ops = {
240 .set_parent = clk_cpu_8996_mux_set_parent,
241 .get_parent = clk_cpu_8996_mux_get_parent,
242 .determine_rate = clk_cpu_8996_mux_determine_rate,
243 };
244
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply
* [PATCH REPOST] mfd: syscon: atmel-smc: include string.h
From: Alexandre Belloni @ 2018-05-04 12:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504103446.20104-1-bigeasy@linutronix.de>
On 04/05/2018 12:34:46+0200, Sebastian Andrzej Siewior wrote:
> The string.h header file is needed for the memset() definition. The RT
> build fails because it is not pulled in via other header files.
>
> Cc: Lee Jones <lee.jones@linaro.org>
> Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---
> drivers/mfd/atmel-smc.c | 1 +
> 1 file changed, 1 insertion(+)
>
> --- a/drivers/mfd/atmel-smc.c
> +++ b/drivers/mfd/atmel-smc.c
> @@ -12,6 +12,7 @@
> */
>
> #include <linux/mfd/syscon/atmel-smc.h>
> +#include <linux/string.h>
>
> /**
> * atmel_smc_cs_conf_init - initialize a SMC CS conf
--
Alexandre Belloni, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH v2 09/10] ARM: dts: sun7i-a20: Add Video Engine and reserved memory nodes
From: Paul Kocialkowski @ 2018-05-04 12:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504091555.idgtzey53lozj2uh@flea>
Hi,
On Fri, 2018-05-04 at 11:15 +0200, Maxime Ripard wrote:
> On Fri, May 04, 2018 at 10:47:44AM +0200, Paul Kocialkowski wrote:
> > > > > > + reg = <0x01c0e000 0x1000>;
> > > > > > + memory-region = <&ve_memory>;
> > > > >
> > > > > Since you made the CMA region the default one, you don't need
> > > > > to
> > > > > tie
> > > > > it to that device in particular (and you can drop it being
> > > > > mandatory
> > > > > from your binding as well).
> > > >
> > > > What if another driver (or the system) claims memory from that
> > > > zone
> > > > and
> > > > that the reserved memory ends up not being available for the VPU
> > > > anymore?
> > > >
> > > > Acccording to the reserved-memory documentation, the reusable
> > > > property
> > > > (that we need for dmabuf) puts a limitation that the device
> > > > driver
> > > > owning the region must be able to reclaim it back.
> > > >
> > > > How does that work out if the CMA region is not tied to a driver
> > > > in
> > > > particular?
> > >
> > > I'm not sure to get what you're saying. You have the property
> > > linux,cma-default in your reserved region, so the behaviour you
> > > described is what you explicitly asked for.
> >
> > My point is that I don't see how the driver can claim back (part of)
> > the
> > reserved area if the area is not explicitly attached to it.
> >
> > Or is that mechanism made in a way that all drivers wishing to use
> > the
> > reserved memory area can claim it back from the system, but there is
> > no
> > priority (other than first-come first-served) for which drivers
> > claims
> > it back in case two want to use the same reserved region (in a
> > scenario
> > where there isn't enough memory to allow both drivers)?
>
> This is indeed what happens. Reusable is to let the system use the
> reserved memory for things like caches that can easily be dropped when
> a driver wants to use the memory in that reserved area. Once that
> memory has been allocated, there's no claiming back, unless that
> memory segment was freed of course.
Thanks for the clarification. So in our case, perhaps the best fit would
be to make that area the default CMA pool so that we can be ensured that
the whole 96 MiB is available for the VPU and that no other consumer of
CMA will use it?
Cheers,
--
Paul Kocialkowski, Bootlin (formerly Free Electrons)
Embedded Linux and kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/dc8274eb/attachment-0001.sig>
^ permalink raw reply
* [PATCH v8 00/13] Support PPTT for ARM64
From: Sudeep Holla @ 2018-05-04 11:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <050a01d3e37f$57678470$06368d50$@codeaurora.org>
Hi Vijaya Kumar,
On 04/05/18 09:10, vkilari at codeaurora.org wrote:
>
[...]
CPI 6.2 adds the Processor Properties Topology Table (PPTT), which is
> used to
>> describe the processor and cache topology. Ideally it is used to
> extend/override
FYI, these messages go no where to the git commit log. Only individual
patch logs/messages will go and not the cover letter ones. Check if you
are happy with those.
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH v2 2/4] KVM: arm/arm64: Introduce helpers to manupulate page table entries
From: Christoffer Dall @ 2018-05-04 11:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <871sevr0n8.fsf@e105922-lin.cambridge.arm.com>
On Tue, May 01, 2018 at 02:00:43PM +0100, Punit Agrawal wrote:
> Hi Suzuki,
>
> Thanks for having a look.
>
> Suzuki K Poulose <Suzuki.Poulose@arm.com> writes:
>
> > On 01/05/18 11:26, Punit Agrawal wrote:
> >> Introduce helpers to abstract architectural handling of the conversion
> >> of pfn to page table entries and marking a PMD page table entry as a
> >> block entry.
> >>
> >> The helpers are introduced in preparation for supporting PUD hugepages
> >> at stage 2 - which are supported on arm64 but do not exist on arm.
> >
> > Punit,
> >
> > The change are fine by me. However, we usually do not define kvm_*
> > accessors for something which we know matches with the host variant.
> > i.e, PMD and PTE helpers, which are always present and we make use
> > of them directly. (see unmap_stage2_pmds for e.g)
>
> In general, I agree - it makes sense to avoid duplication.
>
> Having said that, the helpers here allow following a common pattern for
> handling the various page sizes - pte, pmd and pud - during stage 2
> fault handling (see patch 4).
>
> As you've said you're OK with this change, I'd prefer to keep this patch
> but will drop it if any others reviewers are concerned about the
> duplication as well.
There are arguments for both keeping the kvm_ wrappers and not having
them. I see no big harm or increase in complexity by keeping them
though.
Thanks,
-Christoffer
^ permalink raw reply
* [PATCH v2 4/4] KVM: arm64: Add support for PUD hugepages at stage 2
From: Christoffer Dall @ 2018-05-04 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180501102659.13188-5-punit.agrawal@arm.com>
On Tue, May 01, 2018 at 11:26:59AM +0100, Punit Agrawal wrote:
> KVM currently supports PMD hugepages at stage 2. Extend the stage 2
> fault handling to add support for PUD hugepages.
>
> Addition of pud hugepage support enables additional hugepage
> sizes (e.g., 1G with 4K granule) which can be useful on cores that
> support mapping larger block sizes in the TLB entries.
>
> Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
> Cc: Christoffer Dall <christoffer.dall@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
> ---
> arch/arm/include/asm/kvm_mmu.h | 19 ++++++++++++
> arch/arm64/include/asm/kvm_mmu.h | 15 ++++++++++
> arch/arm64/include/asm/pgtable-hwdef.h | 4 +++
> arch/arm64/include/asm/pgtable.h | 2 ++
> virt/kvm/arm/mmu.c | 40 ++++++++++++++++++++++++--
> 5 files changed, 77 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
> index 224c22c0a69c..155916dbdd7e 100644
> --- a/arch/arm/include/asm/kvm_mmu.h
> +++ b/arch/arm/include/asm/kvm_mmu.h
> @@ -77,8 +77,11 @@ void kvm_clear_hyp_idmap(void);
>
> #define kvm_pfn_pte(pfn, prot) pfn_pte(pfn, prot)
> #define kvm_pfn_pmd(pfn, prot) pfn_pmd(pfn, prot)
> +#define kvm_pfn_pud(pfn, prot) (__pud(0))
>
> #define kvm_pmd_mkhuge(pmd) pmd_mkhuge(pmd)
> +/* No support for pud hugepages */
> +#define kvm_pud_mkhuge(pud) (pud)
>
> /*
> * The following kvm_*pud*() functionas are provided strictly to allow
> @@ -95,6 +98,22 @@ static inline bool kvm_s2pud_readonly(pud_t *pud)
> return false;
> }
>
> +static inline void kvm_set_pud(pud_t *pud, pud_t new_pud)
> +{
> + BUG();
> +}
> +
> +static inline pud_t kvm_s2pud_mkwrite(pud_t pud)
> +{
> + BUG();
> + return pud;
> +}
> +
> +static inline pud_t kvm_s2pud_mkexec(pud_t pud)
> +{
> + BUG();
> + return pud;
> +}
>
> static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd)
> {
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index f440cf216a23..f49a68fcbf26 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -172,11 +172,14 @@ void kvm_clear_hyp_idmap(void);
>
> #define kvm_set_pte(ptep, pte) set_pte(ptep, pte)
> #define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd)
> +#define kvm_set_pud(pudp, pud) set_pud(pudp, pud)
>
> #define kvm_pfn_pte(pfn, prot) pfn_pte(pfn, prot)
> #define kvm_pfn_pmd(pfn, prot) pfn_pmd(pfn, prot)
> +#define kvm_pfn_pud(pfn, prot) pfn_pud(pfn, prot)
>
> #define kvm_pmd_mkhuge(pmd) pmd_mkhuge(pmd)
> +#define kvm_pud_mkhuge(pud) pud_mkhuge(pud)
>
> static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
> {
> @@ -190,6 +193,12 @@ static inline pmd_t kvm_s2pmd_mkwrite(pmd_t pmd)
> return pmd;
> }
>
> +static inline pud_t kvm_s2pud_mkwrite(pud_t pud)
> +{
> + pud_val(pud) |= PUD_S2_RDWR;
> + return pud;
> +}
> +
> static inline pte_t kvm_s2pte_mkexec(pte_t pte)
> {
> pte_val(pte) &= ~PTE_S2_XN;
> @@ -202,6 +211,12 @@ static inline pmd_t kvm_s2pmd_mkexec(pmd_t pmd)
> return pmd;
> }
>
> +static inline pud_t kvm_s2pud_mkexec(pud_t pud)
> +{
> + pud_val(pud) &= ~PUD_S2_XN;
> + return pud;
> +}
> +
> static inline void kvm_set_s2pte_readonly(pte_t *ptep)
> {
> pteval_t old_pteval, pteval;
> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> index fd208eac9f2a..e327665e94d1 100644
> --- a/arch/arm64/include/asm/pgtable-hwdef.h
> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> @@ -193,6 +193,10 @@
> #define PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
> #define PMD_S2_XN (_AT(pmdval_t, 2) << 53) /* XN[1:0] */
>
> +#define PUD_S2_RDONLY (_AT(pudval_t, 1) << 6) /* HAP[2:1] */
> +#define PUD_S2_RDWR (_AT(pudval_t, 3) << 6) /* HAP[2:1] */
> +#define PUD_S2_XN (_AT(pudval_t, 2) << 53) /* XN[1:0] */
> +
> /*
> * Memory Attribute override for Stage-2 (MemAttr[3:0])
> */
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 7c4c8f318ba9..31ea9fda07e3 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -386,6 +386,8 @@ static inline int pmd_protnone(pmd_t pmd)
>
> #define pud_write(pud) pte_write(pud_pte(pud))
>
> +#define pud_mkhuge(pud) (__pud(pud_val(pud) & ~PUD_TABLE_BIT))
> +
> #define __pud_to_phys(pud) __pte_to_phys(pud_pte(pud))
> #define __phys_to_pud_val(phys) __phys_to_pte_val(phys)
> #define pud_pfn(pud) ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT)
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index 3afbf693e045..1fb108d47dbd 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -1036,6 +1036,26 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
> return 0;
> }
>
> +static int stage2_set_pud_huge(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
> + phys_addr_t addr, const pud_t *new_pud)
> +{
> + pud_t *pud, old_pud;
> +
> + pud = stage2_get_pud(kvm, cache, addr);
> + VM_BUG_ON(!pud);
> +
> + old_pud = *pud;
> + if (pud_present(old_pud)) {
> + pud_clear(pud);
> + kvm_tlb_flush_vmid_ipa(kvm, addr);
> + } else {
> + get_page(virt_to_page(pud));
> + }
> +
> + kvm_set_pud(pud, *new_pud);
> + return 0;
> +}
> +
> static bool stage2_is_exec(struct kvm *kvm, phys_addr_t addr)
> {
> pmd_t *pmdp;
> @@ -1467,9 +1487,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> }
>
> vma_pagesize = vma_kernel_pagesize(vma);
> - if (vma_pagesize == PMD_SIZE && !logging_active) {
> + if ((vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE) &&
> + !logging_active) {
> + struct hstate *h = hstate_vma(vma);
> +
> hugetlb = true;
> - gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
> + gfn = (fault_ipa & huge_page_mask(h)) >> PAGE_SHIFT;
> } else {
> /*
> * Pages belonging to memslots that don't have the same
> @@ -1556,7 +1579,18 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> if (exec_fault)
> invalidate_icache_guest_page(pfn, vma_pagesize);
>
> - if (hugetlb) {
> + if (vma_pagesize == PUD_SIZE) {
> + pud_t new_pud = kvm_pfn_pud(pfn, mem_type);
> +
> + new_pud = kvm_pud_mkhuge(new_pud);
> + if (writable)
> + new_pud = kvm_s2pud_mkwrite(new_pud);
> +
> + if (stage2_should_exec(kvm, fault_ipa, exec_fault, fault_status))
> + new_pud = kvm_s2pud_mkexec(new_pud);
> +
> + ret = stage2_set_pud_huge(kvm, memcache, fault_ipa, &new_pud);
> + } else if (vma_pagesize == PMD_SIZE) {
> pmd_t new_pmd = kvm_pfn_pmd(pfn, mem_type);
>
> new_pmd = kvm_pmd_mkhuge(new_pmd);
> --
> 2.17.0
>
^ permalink raw reply
* [PATCH v2 1/4] KVM: arm/arm64: Share common code in user_mem_abort()
From: Christoffer Dall @ 2018-05-04 11:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180501102659.13188-2-punit.agrawal@arm.com>
On Tue, May 01, 2018 at 11:26:56AM +0100, Punit Agrawal wrote:
> The code for operations such as marking the pfn as dirty, and
> dcache/icache maintenance during stage 2 fault handling is duplicated
> between normal pages and PMD hugepages.
>
> Instead of creating another copy of the operations when we introduce
> PUD hugepages, let's share them across the different pagesizes.
>
> Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
> Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> ---
> virt/kvm/arm/mmu.c | 66 +++++++++++++++++++++++++++-------------------
> 1 file changed, 39 insertions(+), 27 deletions(-)
>
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index 7f6a944db23d..686fc6a4b866 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -1396,6 +1396,21 @@ static void invalidate_icache_guest_page(kvm_pfn_t pfn, unsigned long size)
> __invalidate_icache_guest_page(pfn, size);
> }
>
> +static bool stage2_should_exec(struct kvm *kvm, phys_addr_t addr,
> + bool exec_fault, unsigned long fault_status)
> +{
> + /*
> + * If we took an execution fault we will have made the
> + * icache/dcache coherent and should now let the s2 mapping be
> + * executable.
> + *
> + * Write faults (!exec_fault && FSC_PERM) are orthogonal to
> + * execute permissions, and we preserve whatever we have.
> + */
> + return exec_fault ||
> + (fault_status == FSC_PERM && stage2_is_exec(kvm, addr));
> +}
> +
> static void kvm_send_hwpoison_signal(unsigned long address,
> struct vm_area_struct *vma)
> {
> @@ -1428,7 +1443,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> kvm_pfn_t pfn;
> pgprot_t mem_type = PAGE_S2;
> bool logging_active = memslot_is_logging(memslot);
> - unsigned long flags = 0;
> + unsigned long vma_pagesize, flags = 0;
>
> write_fault = kvm_is_write_fault(vcpu);
> exec_fault = kvm_vcpu_trap_is_iabt(vcpu);
> @@ -1448,7 +1463,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> return -EFAULT;
> }
>
> - if (vma_kernel_pagesize(vma) == PMD_SIZE && !logging_active) {
> + vma_pagesize = vma_kernel_pagesize(vma);
> + if (vma_pagesize == PMD_SIZE && !logging_active) {
> hugetlb = true;
> gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
> } else {
> @@ -1517,28 +1533,34 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> if (mmu_notifier_retry(kvm, mmu_seq))
> goto out_unlock;
>
> - if (!hugetlb && !force_pte)
> + if (!hugetlb && !force_pte) {
> hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa);
> + /*
> + * Only PMD_SIZE transparent hugepages(THP) are
> + * currently supported. This code will need to be
> + * updated to support other THP sizes.
> + */
> + if (hugetlb)
> + vma_pagesize = PMD_SIZE;
nit: this is a bit of a trap waiting to happen, as the suggested
semantics of hugetlb is now hugetlbfs and not THP.
It may be slightly nicer to do do:
if (transparent_hugepage_adjust(&pfn, &fault_ipa))
vma_pagesize = PMD_SIZE;
> + }
> +
> + if (writable)
> + kvm_set_pfn_dirty(pfn);
> +
> + if (fault_status != FSC_PERM)
> + clean_dcache_guest_page(pfn, vma_pagesize);
> +
> + if (exec_fault)
> + invalidate_icache_guest_page(pfn, vma_pagesize);
>
> if (hugetlb) {
> pmd_t new_pmd = pfn_pmd(pfn, mem_type);
> new_pmd = pmd_mkhuge(new_pmd);
> - if (writable) {
> + if (writable)
> new_pmd = kvm_s2pmd_mkwrite(new_pmd);
> - kvm_set_pfn_dirty(pfn);
> - }
>
> - if (fault_status != FSC_PERM)
> - clean_dcache_guest_page(pfn, PMD_SIZE);
> -
> - if (exec_fault) {
> + if (stage2_should_exec(kvm, fault_ipa, exec_fault, fault_status))
> new_pmd = kvm_s2pmd_mkexec(new_pmd);
> - invalidate_icache_guest_page(pfn, PMD_SIZE);
> - } else if (fault_status == FSC_PERM) {
> - /* Preserve execute if XN was already cleared */
> - if (stage2_is_exec(kvm, fault_ipa))
> - new_pmd = kvm_s2pmd_mkexec(new_pmd);
> - }
>
> ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd);
> } else {
> @@ -1546,21 +1568,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>
> if (writable) {
> new_pte = kvm_s2pte_mkwrite(new_pte);
> - kvm_set_pfn_dirty(pfn);
> mark_page_dirty(kvm, gfn);
> }
>
> - if (fault_status != FSC_PERM)
> - clean_dcache_guest_page(pfn, PAGE_SIZE);
> -
> - if (exec_fault) {
> + if (stage2_should_exec(kvm, fault_ipa, exec_fault, fault_status))
> new_pte = kvm_s2pte_mkexec(new_pte);
> - invalidate_icache_guest_page(pfn, PAGE_SIZE);
> - } else if (fault_status == FSC_PERM) {
> - /* Preserve execute if XN was already cleared */
> - if (stage2_is_exec(kvm, fault_ipa))
> - new_pte = kvm_s2pte_mkexec(new_pte);
> - }
>
> ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, flags);
> }
> --
> 2.17.0
>
Otherwise looks good.
Thanks,
-Christoffer
^ permalink raw reply
* [PATCH v8 00/13] Support PPTT for ARM64
From: Xiongfeng Wang @ 2018-05-04 11:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180425233121.13270-1-jeremy.linton@arm.com>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Tested on D05 board. 'lscpu' prints the following info:
localhost:~ # lscpu
Architecture: aarch64
Byte Order: Little Endian
CPU(s): 64
On-line CPU(s) list: 0-63
Thread(s) per core: 1
Core(s) per socket: 32
Socket(s): 2
NUMA node(s): 4
L1d cache: 32K
L1i cache: 48K
L2 cache: 1024K
L3 cache: 16384K
NUMA node0 CPU(s): 0-15
NUMA node1 CPU(s): 16-31
NUMA node2 CPU(s): 32-47
NUMA node3 CPU(s): 48-63
'sched_domain' is as follows
localhost:~ # cat /proc/schedstat
version 15
timestamp 4294936236
cpu0 0 0 0 0 0 0 2471285600 2634828800 4813
domain0 00000000,0000ffff 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
domain1 00000000,ffffffff 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
domain2 ffffffff,ffffffff 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
On 2018/4/26 7:31, Jeremy Linton wrote:
> ACPI 6.2 adds the Processor Properties Topology Table (PPTT), which is
> used to describe the processor and cache topology. Ideally it is
> used to extend/override information provided by the hardware, but
> right now ARM64 is entirely dependent on firmware provided tables.
>
> This patch parses the table for the cache topology and CPU topology.
> When we enable ACPI/PPTT for arm64 we map the package_id to the
> PPTT node flagged as the physical package by the firmware.
> This results in topologies that match what the remainder of the
> system expects. Finally, we update the scheduler MC domain so that
> it generally reflects the LLC unless the LLC is too large for the
> NUMA domain (or package).
>
> For example on juno:
> [root at mammon-juno-rh topology]# lstopo-no-graphics
> Package L#0
> L2 L#0 (1024KB)
> L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0)
> L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#1)
> L1d L#2 (32KB) + L1i L#2 (32KB) + Core L#2 + PU L#2 (P#2)
> L1d L#3 (32KB) + L1i L#3 (32KB) + Core L#3 + PU L#3 (P#3)
> L2 L#1 (2048KB)
> L1d L#4 (32KB) + L1i L#4 (48KB) + Core L#4 + PU L#4 (P#4)
> L1d L#5 (32KB) + L1i L#5 (48KB) + Core L#5 + PU L#5 (P#5)
> HostBridge L#0
> PCIBridge
> PCIBridge
> PCIBridge
> PCI 1095:3132
> Block(Disk) L#0 "sda"
> PCIBridge
> PCI 1002:68f9
> GPU L#1 "renderD128"
> GPU L#2 "card0"
> GPU L#3 "controlD64"
> PCIBridge
> PCI 11ab:4380
> Net L#4 "enp8s0"
>
> Git tree at:
> http://linux-arm.org/git?p=linux-jlinton.git
> branch: pptt_v8
>
> v7->v8:
> Modify the logic used to select the MC domain (the change
> shouldn't modify the sched domains on any existing machines
> compared to v7, only how they are built)
> Reduce the severity of some parsing messages.
> Fix s390 link problem.
> Further checks to deal with broken PPTT tables.
> Various style tweaks, SPDX license addition, etc.
>
> v6->v7:
> Add additional patch to use the last cache level within the NUMA
> or socket as the MC domain. This assures the MC domain is
> equal or smaller than the DIE.
>
> Various formatting/etc review comments.
>
> Rebase to 4.16rc2
>
> v5->v6:
> Add additional patches which re-factor how the initial DT code sets
> up the cacheinfo structure so that its not as dependent on the
> of_node stored in that tree. Once that is done we rename it
> for use with the ACPI code.
>
> Additionally there were a fair number of minor name/location/etc
> tweaks scattered about made in response to review comments.
>
> v4->v5:
> Update the cache type from NOCACHE to UNIFIED when all the cache
> attributes we update are valid. This fixes a problem where caches
> which are entirely created by the PPTT don't show up in lstopo.
>
> Give the PPTT its own firmware_node in the cache structure instead of
> sharing it with the of_node.
>
> Move some pieces around between patches.
>
> (see previous cover letters for futher changes)
>
> Jeremy Linton (13):
> drivers: base: cacheinfo: move cache_setup_of_node()
> drivers: base: cacheinfo: setup DT cache properties early
> cacheinfo: rename of_node to fw_token
> arm64/acpi: Create arch specific cpu to acpi id helper
> ACPI/PPTT: Add Processor Properties Topology Table parsing
> ACPI: Enable PPTT support on ARM64
> drivers: base cacheinfo: Add support for ACPI based firmware tables
> arm64: Add support for ACPI based firmware tables
> ACPI/PPTT: Add topology parsing code
> arm64: topology: rename cluster_id
> arm64: topology: enable ACPI/PPTT based CPU topology
> ACPI: Add PPTT to injectable table list
> arm64: topology: divorce MC scheduling domain from core_siblings
>
> arch/arm64/Kconfig | 1 +
> arch/arm64/include/asm/acpi.h | 4 +
> arch/arm64/include/asm/topology.h | 6 +-
> arch/arm64/kernel/cacheinfo.c | 15 +-
> arch/arm64/kernel/topology.c | 103 +++++-
> arch/riscv/kernel/cacheinfo.c | 1 -
> drivers/acpi/Kconfig | 3 +
> drivers/acpi/Makefile | 1 +
> drivers/acpi/pptt.c | 678 ++++++++++++++++++++++++++++++++++++++
> drivers/acpi/tables.c | 2 +-
> drivers/base/cacheinfo.c | 157 ++++-----
> include/linux/acpi.h | 4 +
> include/linux/cacheinfo.h | 18 +-
> 13 files changed, 886 insertions(+), 107 deletions(-)
> create mode 100644 drivers/acpi/pptt.c
>
^ permalink raw reply
* [PATCH REPOST] ARM: smp: Move clear_tasks_mm_cpumask() call to __cpu_die()
From: Sebastian Andrzej Siewior @ 2018-05-04 11:29 UTC (permalink / raw)
To: linux-arm-kernel
From: Grygorii Strashko <grygorii.strashko@ti.com>
Suspending a CPU on a RT kernel results in the following backtrace:
| Disabling non-boot CPUs ...
| BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:917
| in_atomic(): 1, irqs_disabled(): 128, pid: 18, name: migration/1
| INFO: lockdep is turned off.
| irq event stamp: 122
| hardirqs last enabled at (121): [<c06ac0ac>] _raw_spin_unlock_irqrestore+0x88/0x90
| hardirqs last disabled at (122): [<c06abed0>] _raw_spin_lock_irq+0x28/0x5c
| CPU: 1 PID: 18 Comm: migration/1 Tainted: G W 4.1.4-rt3-01046-g96ac8da #204
| Hardware name: Generic DRA74X (Flattened Device Tree)
| [<c0019134>] (unwind_backtrace) from [<c0014774>] (show_stack+0x20/0x24)
| [<c0014774>] (show_stack) from [<c06a70f4>] (dump_stack+0x88/0xdc)
| [<c06a70f4>] (dump_stack) from [<c006cab8>] (___might_sleep+0x198/0x2a8)
| [<c006cab8>] (___might_sleep) from [<c06ac4dc>] (rt_spin_lock+0x30/0x70)
| [<c06ac4dc>] (rt_spin_lock) from [<c013f790>] (find_lock_task_mm+0x9c/0x174)
| [<c013f790>] (find_lock_task_mm) from [<c00409ac>] (clear_tasks_mm_cpumask+0xb4/0x1ac)
| [<c00409ac>] (clear_tasks_mm_cpumask) from [<c00166a4>] (__cpu_disable+0x98/0xbc)
| [<c00166a4>] (__cpu_disable) from [<c06a2e8c>] (take_cpu_down+0x1c/0x50)
| [<c06a2e8c>] (take_cpu_down) from [<c00f2600>] (multi_cpu_stop+0x11c/0x158)
| [<c00f2600>] (multi_cpu_stop) from [<c00f2a9c>] (cpu_stopper_thread+0xc4/0x184)
| [<c00f2a9c>] (cpu_stopper_thread) from [<c0069058>] (smpboot_thread_fn+0x18c/0x324)
| [<c0069058>] (smpboot_thread_fn) from [<c00649c4>] (kthread+0xe8/0x104)
| [<c00649c4>] (kthread) from [<c0010058>] (ret_from_fork+0x14/0x3c)
| CPU1: shutdown
The root cause of above backtrace is task_lock() which takes a sleeping
lock on -RT.
To fix the issue, move clear_tasks_mm_cpumask() call from __cpu_disable()
to __cpu_die() which is called on the thread which is asking for a target
CPU to be shutdown. In addition, this change restores CPU hotplug
functionality on ARM CPU1 can be unplugged/plugged many times.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Cc: <linux-arm-kernel@lists.infradead.org>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Russell King <linux@arm.linux.org.uk>
Link: http://lkml.kernel.org/r/1441995683-30817-1-git-send-email-grygorii.strashko at ti.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[bigeasy: slighty edited the commit message]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
arch/arm/kernel/smp.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -236,8 +236,6 @@ int __cpu_disable(void)
flush_cache_louis();
local_flush_tlb_all();
- clear_tasks_mm_cpumask(cpu);
-
return 0;
}
@@ -255,6 +253,7 @@ void __cpu_die(unsigned int cpu)
}
pr_debug("CPU%u: shutdown\n", cpu);
+ clear_tasks_mm_cpumask(cpu);
/*
* platform_cpu_kill() is generally expected to do the powering off
* and/or cutting of clocks to the dying CPU. Optionally, this may
^ permalink raw reply
* [PATCH v1 03/13] drm/kms/mode/exynos-dsi: using helper func drm_display_mode_to_videomode for calculating timing parameters
From: Robin Murphy @ 2018-05-04 11:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525421726-2817-1-git-send-email-satendra.t@samsung.com>
On 04/05/18 09:15, Satendra Singh Thakur wrote:
> To avoid duplicate logic for the same
>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Please read section 13 of Documentation/process/submitting-patches.rst
for what this tag means; specifically, it is definitely not "this guy
read my patch".
FWIW, in my case the patches I give trivial coding style comments on
tend to be the ones I'm specifically *not* in a position to review in a
technical capacity - the reason I'm looking at them in the first place
is out of interest to learn more about how the relevant subsystems work.
Robin.
> Signed-off-by: Satendra Singh Thakur <satendra.t@samsung.com>
> Acked-by: Madhur Verma <madhur.verma@samsung.com>
> Cc: Hemanshu Srivastava <hemanshu.s@samsung.com>
> ---
> drivers/gpu/drm/exynos/exynos_drm_dsi.c | 13 ++-----------
> 1 file changed, 2 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> index 7904ffa..7fe84fd 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -1490,17 +1490,8 @@ static void exynos_dsi_mode_set(struct drm_encoder *encoder,
> struct drm_display_mode *adjusted_mode)
> {
> struct exynos_dsi *dsi = encoder_to_dsi(encoder);
> - struct videomode *vm = &dsi->vm;
> - struct drm_display_mode *m = adjusted_mode;
> -
> - vm->hactive = m->hdisplay;
> - vm->vactive = m->vdisplay;
> - vm->vfront_porch = m->vsync_start - m->vdisplay;
> - vm->vback_porch = m->vtotal - m->vsync_end;
> - vm->vsync_len = m->vsync_end - m->vsync_start;
> - vm->hfront_porch = m->hsync_start - m->hdisplay;
> - vm->hback_porch = m->htotal - m->hsync_end;
> - vm->hsync_len = m->hsync_end - m->hsync_start;
> +
> + drm_display_mode_to_videomode(adjusted_mode, &dsi->vm);
> }
>
> static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
>
^ 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