Commit Graph

73 Commits

Author SHA1 Message Date
Caleb Connolly
9a2139c291 spmi: add a helper to look up an SPMI device from a device node
The helper function spmi_device_from_of() takes a device node and
returns the SPMI device associated with it.
This is like of_find_device_by_node but for SPMI devices.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20220429220904.137297-2-caleb.connolly@linaro.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
2022-06-18 13:48:19 +01:00
David Collins
1b18af40c1 spmi: spmi-pmic-arb: fix irq_set_type race condition
The qpnpint_irq_set_type() callback function configures the type
(edge vs level) and polarity (high, low, or both) of a particular
PMIC interrupt within a given peripheral.  To do this, it reads
the three consecutive IRQ configuration registers, modifies the
specified IRQ bit within the register values, and finally writes
the three modified register values back to the PMIC.  While a
spinlock is used to provide mutual exclusion on the SPMI bus
during the register read and write calls, there is no locking
around the overall read, modify, write sequence.  This opens up
the possibility of a race condition if two tasks set the type of
a PMIC IRQ within the same peripheral simultaneously.

When the race condition is encountered, both tasks will read the
old value of the registers and IRQ bits set by one of the tasks
will be dropped upon the register write of the other task.  This
then leads to PMIC IRQs being enabled with an incorrect type and
polarity configured.  Such misconfiguration can lead to an IRQ
storm that overwhelms the system and causes it to crash.

This race condition and IRQ storm have been observed when using
a pair of pm8941-pwrkey devices to handle PMK8350 pwrkey and
resin interrupts.  The independent devices probe asynchronously
in parallel and can simultaneously request and configure PMIC
IRQs in the same PMIC peripheral.

For a good case, the IRQ configuration calls end up serialized
due to timing deltas and the register read/write sequence looks
like this:

1. pwrkey probe: SPMI  read(0x1311): 0x00, 0x00, 0x00
2. pwrkey probe: SPMI write(0x1311): 0x80, 0x80, 0x80
3. resin probe:  SPMI  read(0x1311): 0x80, 0x80, 0x80
4. resin probe:  SPMI write(0x1311): 0xC0, 0xC0, 0xC0

The final register states after both devices have requested and
enabled their respective IRQs is thus:

0x1311: 0xC0
0x1312: 0xC0
0x1313: 0xC0
0x1314: 0x00
0x1315: 0xC0

For a bad case, the IRQ configuration calls end up occurring
simultaneously and the race condition is encountered.  The
register read/write sequence then looks like this:

1. pwrkey probe: SPMI  read(0x1311): 0x00, 0x00, 0x00
2. resin probe:  SPMI  read(0x1311): 0x00, 0x00, 0x00
3. pwrkey probe: SPMI write(0x1311): 0x80, 0x80, 0x80
4. resin probe:  SPMI write(0x1311): 0x40, 0x40, 0x40

In this case, the final register states after both devices have
requested and enabled their respective IRQs is thus:

0x1311: 0x40
0x1312: 0x40
0x1313: 0x40
0x1314: 0x00
0x1315: 0xC0

This corresponds to the resin IRQ being configured for both
rising and falling edges, as expected.  However, the pwrkey IRQ
is misconfigured as level type with both polarity high and low
set to disabled.  The PMIC IRQ triggering hardware treats this
particular register configuration as if level low triggering is
enabled.

The raw pwrkey IRQ signal is low when the power key is not being
pressed.  Thus, the pwrkey IRQ begins firing continuously in an
IRQ storm.

Fix the race condition by holding the spmi-pmic-arb spinlock for
the duration of the read, modify, write sequence performed in the
qpnpint_irq_set_type() function.  Split the pmic_arb_read_cmd()
and pmic_arb_write_cmd() functions each into three parts so that
hardware register IO is decoupled from spinlock locking.  This
allows a new function pmic_arb_masked_write() to be added which
locks the spinlock and then calls register IO functions to
perform SPMI read and write commands in a single atomic
operation.

Link: https://lore.kernel.org/r/20211118034719.28971-1-quic_collinsd@quicinc.com
Signed-off-by: David Collins <quic_collinsd@quicinc.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20211216190812.1574801-7-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-17 17:18:18 +01:00
James Lo
504eb71e47 spmi: mediatek: Add support for MT8195
Add spmi support for MT8195.
Refine indent in spmi-mtk-pmif.c.

Link: https://lore.kernel.org/r/20211119034613.32489-5-james.lo@mediatek.com
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: James Lo <james.lo@mediatek.com>
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20211216190812.1574801-6-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-17 17:18:18 +01:00
James Lo
b45b3ccef8 spmi: mediatek: Add support for MT6873/8192
Add spmi support for MT6873/8192.
Refine indent in spmi-mtk-pmif.c.

Link: https://lore.kernel.org/r/20211119034613.32489-4-james.lo@mediatek.com
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: James Lo <james.lo@mediatek.com>
Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20211216190812.1574801-5-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-17 17:18:18 +01:00
Stephen Boyd
b56ca501a4 spmi: pmic-arb: Add sid and address to error messages
It's useful to know what particular device/component is having trouble
accessing the bus. Add the sid and address to error messages here so
that debugging is a little simpler.

Link: https://lore.kernel.org/r/20210920234849.3614036-1-swboyd@chromium.org
Cc: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
Cc: satya priya <skakit@codeaurora.org>
Reviewed-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
Reviewed-by: Satya Priya <skakit@codeaurora.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20211216190812.1574801-2-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-17 17:18:18 +01:00
Uwe Kleine-König
fc7a6209d5 bus: Make remove callback return void
The driver core ignores the return value of this callback because there
is only little it can do when a device disappears.

This is the final bit of a long lasting cleanup quest where several
buses were converted to also return void from their remove callback.
Additionally some resource leaks were fixed that were caused by drivers
returning an error code in the expectation that the driver won't go
away.

With struct bus_type::remove returning void it's prevented that newly
implemented buses return an ignored error code and so don't anticipate
wrong expectations for driver authors.

Reviewed-by: Tom Rix <trix@redhat.com> (For fpga)
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Cornelia Huck <cohuck@redhat.com> (For drivers/s390 and drivers/vfio)
Acked-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> (For ARM, Amba and related parts)
Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Chen-Yu Tsai <wens@csie.org> (for sunxi-rsb)
Acked-by: Pali Rohár <pali@kernel.org>
Acked-by: Mauro Carvalho Chehab <mchehab@kernel.org> (for media)
Acked-by: Hans de Goede <hdegoede@redhat.com> (For drivers/platform)
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-By: Vinod Koul <vkoul@kernel.org>
Acked-by: Juergen Gross <jgross@suse.com> (For xen)
Acked-by: Lee Jones <lee.jones@linaro.org> (For mfd)
Acked-by: Johannes Thumshirn <jth@kernel.org> (For mcb)
Acked-by: Johan Hovold <johan@kernel.org>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> (For slimbus)
Acked-by: Kirti Wankhede <kwankhede@nvidia.com> (For vfio)
Acked-by: Maximilian Luz <luzmaximilian@gmail.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> (For ulpi and typec)
Acked-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> (For ipack)
Acked-by: Geoff Levand <geoff@infradead.org> (For ps3)
Acked-by: Yehezkel Bernat <YehezkelShB@gmail.com> (For thunderbolt)
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> (For intel_th)
Acked-by: Dominik Brodowski <linux@dominikbrodowski.net> (For pcmcia)
Acked-by: Rafael J. Wysocki <rafael@kernel.org> (For ACPI)
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org> (rpmsg and apr)
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> (For intel-ish-hid)
Acked-by: Dan Williams <dan.j.williams@intel.com> (For CXL, DAX, and NVDIMM)
Acked-by: William Breathitt Gray <vilhelm.gray@gmail.com> (For isa)
Acked-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (For firewire)
Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> (For hid)
Acked-by: Thorsten Scherer <t.scherer@eckelmann.de> (For siox)
Acked-by: Sven Van Asbroeck <TheSven73@gmail.com> (For anybuss)
Acked-by: Ulf Hansson <ulf.hansson@linaro.org> (For MMC)
Acked-by: Wolfram Sang <wsa@kernel.org> # for I2C
Acked-by: Sudeep Holla <sudeep.holla@arm.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Acked-by: Finn Thain <fthain@linux-m68k.org>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20210713193522.1770306-6-u.kleine-koenig@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-07-21 11:53:42 +02:00
Mauro Carvalho Chehab
e562cf3aea spmi: hisi-spmi-controller: move driver from staging
The Hisilicon 6421v600 SPMI driver is ready for mainstream.

So, move it from staging.

Acked-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Link: https://lore.kernel.org/r/35b9f9169889c1f4d51eff8bf2035450c9e02576.1624606660.git.mchehab+huawei@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-06-25 10:02:05 +02:00
Subbaraman Narayanamurthy
d19db80a36 spmi: spmi-pmic-arb: Fix hw_irq overflow
Currently, when handling the SPMI summary interrupt, the hw_irq
number is calculated based on SID, Peripheral ID, IRQ index and
APID. This is then passed to irq_find_mapping() to see if a
mapping exists for this hw_irq and if available, invoke the
interrupt handler. Since the IRQ index uses an "int" type, hw_irq
which is of unsigned long data type can take a large value when
SID has its MSB set to 1 and the type conversion happens. Because
of this, irq_find_mapping() returns 0 as there is no mapping
for this hw_irq. This ends up invoking cleanup_irq() as if
the interrupt is spurious whereas it is actually a valid
interrupt. Fix this by using the proper data type (u32) for id.

Cc: stable@vger.kernel.org
Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
Link: https://lore.kernel.org/r/1612812784-26369-1-git-send-email-subbaram@codeaurora.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20210212031417.3148936-1-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-02-12 12:26:46 +01:00
Hsin-Hsiung Wang
d40c2d4ed6 spmi: Add driver shutdown support
Add new shutdown() method.  Use it in the standard driver model style.

Link: https://lore.kernel.org/r/1603187810-30481-2-git-send-email-hsin-hsiung.wang@mediatek.com
Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20201210023344.2838141-4-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-12-10 10:45:36 +01:00
Mauro Carvalho Chehab
0be0a733c9 spmi: fix some coding style issues at the spmi core
While preparing to port the HiSilicon 6421v600 SPMI driver,
I noticed some coding style issues at the SPMI core.

Address them.

Link: https://lore.kernel.org/r/fec878502147336cbf2cf86e476e9dd797cd7e6f.1601360391.git.mchehab+huawei@kernel.org
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20201210023344.2838141-3-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-12-10 10:45:36 +01:00
Mauro Carvalho Chehab
b1f0aeecd2 spmi: get rid of a warning when built with W=1
The SPMI core complaing with this warning when built with W=1:

	drivers/spmi/spmi.c: In function ‘spmi_controller_remove’:
	drivers/spmi/spmi.c:548:6: warning: variable ‘dummy’ set but not used [-Wunused-but-set-variable]
	  548 |  int dummy;
	      |      ^~~~~

As the dummy var isn't needed, remove it.

Link: https://lore.kernel.org/r/aacfd03835b7d1b3b6c21665b44000fe7242e535.1601360391.git.mchehab+huawei@kernel.org
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20201210023344.2838141-2-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-12-10 10:45:35 +01:00
Stephen Boyd
2d5a2f913b spmi: pmic-arb: Set lockdep class for hierarchical irq domains
I see the following lockdep splat in the qcom pinctrl driver when
attempting to suspend the device.

 WARNING: possible recursive locking detected
 5.4.11 #3 Tainted: G        W
 --------------------------------------------
 cat/3074 is trying to acquire lock:
 ffffff81f49804c0 (&irq_desc_lock_class){-.-.}, at: __irq_get_desc_lock+0x64/0x94

 but task is already holding lock:
 ffffff81f1cc10c0 (&irq_desc_lock_class){-.-.}, at: __irq_get_desc_lock+0x64/0x94

 other info that might help us debug this:
  Possible unsafe locking scenario:

        CPU0
        ----
   lock(&irq_desc_lock_class);
   lock(&irq_desc_lock_class);

  *** DEADLOCK ***

  May be due to missing lock nesting notation

 6 locks held by cat/3074:
  #0: ffffff81f01d9420 (sb_writers#7){.+.+}, at: vfs_write+0xd0/0x1a4
  #1: ffffff81bd7d2080 (&of->mutex){+.+.}, at: kernfs_fop_write+0x12c/0x1fc
  #2: ffffff81f4c322f0 (kn->count#337){.+.+}, at: kernfs_fop_write+0x134/0x1fc
  #3: ffffffe411a41d60 (system_transition_mutex){+.+.}, at: pm_suspend+0x108/0x348
  #4: ffffff81f1c5e970 (&dev->mutex){....}, at: __device_suspend+0x168/0x41c
  #5: ffffff81f1cc10c0 (&irq_desc_lock_class){-.-.}, at: __irq_get_desc_lock+0x64/0x94

 stack backtrace:
 CPU: 5 PID: 3074 Comm: cat Tainted: G        W         5.4.11 #3
 Hardware name: Google Cheza (rev3+) (DT)
 Call trace:
  dump_backtrace+0x0/0x174
  show_stack+0x20/0x2c
  dump_stack+0xc8/0x124
  __lock_acquire+0x460/0x2388
  lock_acquire+0x1cc/0x210
  _raw_spin_lock_irqsave+0x64/0x80
  __irq_get_desc_lock+0x64/0x94
  irq_set_irq_wake+0x40/0x144
  qpnpint_irq_set_wake+0x28/0x34
  set_irq_wake_real+0x40/0x5c
  irq_set_irq_wake+0x70/0x144
  pm8941_pwrkey_suspend+0x34/0x44
  platform_pm_suspend+0x34/0x60
  dpm_run_callback+0x64/0xcc
  __device_suspend+0x310/0x41c
  dpm_suspend+0xf8/0x298
  dpm_suspend_start+0x84/0xb4
  suspend_devices_and_enter+0xbc/0x620
  pm_suspend+0x210/0x348
  state_store+0xb0/0x108
  kobj_attr_store+0x14/0x24
  sysfs_kf_write+0x4c/0x64
  kernfs_fop_write+0x15c/0x1fc
  __vfs_write+0x54/0x18c
  vfs_write+0xe4/0x1a4
  ksys_write+0x7c/0xe4
  __arm64_sys_write+0x20/0x2c
  el0_svc_common+0xa8/0x160
  el0_svc_handler+0x7c/0x98
  el0_svc+0x8/0xc

Set a lockdep class when we map the irq so that irq_set_wake() doesn't
warn about a lockdep bug that doesn't exist.

Fixes: 12a9eeaebb ("spmi: pmic-arb: convert to v2 irq interfaces to support hierarchical IRQ chips")
Cc: Douglas Anderson <dianders@chromium.org>
Cc: Brian Masney <masneyb@onstation.org>
Cc: Lina Iyer <ilina@codeaurora.org>
Cc: Maulik Shah <mkshah@codeaurora.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Link: https://lore.kernel.org/r/20200121183748.68662-1-swboyd@chromium.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-02-10 13:16:04 +01:00
Thomas Gleixner
97fb5e8d9b treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 284
Based on 1 normalized pattern(s):

  this program is free software you can redistribute it and or modify
  it under the terms of the gnu general public license version 2 and
  only version 2 as published by the free software foundation this
  program is distributed in the hope that it will be useful but
  without any warranty without even the implied warranty of
  merchantability or fitness for a particular purpose see the gnu
  general public license for more details

extracted by the scancode license scanner the SPDX license identifier

  GPL-2.0-only

has been chosen to replace the boilerplate/reference in 294 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Alexios Zavras <alexios.zavras@intel.com>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190529141900.825281744@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-05 17:36:37 +02:00
Thomas Gleixner
ec8f24b7fa treewide: Add SPDX license identifier - Makefile/Kconfig
Add SPDX license identifiers to all Make/Kconfig files which:

 - Have no license information of any form

These files fall under the project license, GPL v2 only. The resulting SPDX
license identifier is:

  GPL-2.0-only

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-05-21 10:50:46 +02:00
Brian Masney
760a160e8b spmi: pmic-arb: select IRQ_DOMAIN_HIERARCHY in Kconfig
Select IRQ_DOMAIN_HIERARCHY for pmic-arb in Kconfig since this driver
uses the version 2 IRQ interfaces. IRQ_DOMAIN_HIERARCHY selects
IRQ_DOMAIN, so it can be removed from here.

Signed-off-by: Brian Masney <masneyb@onstation.org>
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2019-02-14 09:14:50 +01:00
Brian Masney
25655c7532 spmi: pmic-arb: revert "validate type when mapping IRQ"
Validation of the IRQ type was added to spmi pmic-arb, however spmi-mpp
in device tree still uses IRQ_TYPE_NONE. This commit caused the
spmi-mpp probe to fail since platform_irq_count() would return 0.
Correct this by backing out the previous patch.

Signed-off-by: Brian Masney <masneyb@onstation.org>
Fixes: 135ef21ab0 ("spmi: pmic-arb: validate type when mapping IRQ")
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2019-02-09 11:33:38 +01:00
Brian Masney
e7dc6af82c spmi: pmic-arb: revert "disassociate old virq if hwirq mapping already exists"
Now that spmi-gpio is a proper hierarchical IRQ chip, and all in-tree
users of device tree have been updated, we can now drop the hack that
was introduced to disassociate the old Linux virq if a hwirq mapping
already exists. That patch was introduced to not break git bisect for
any existing boards.

Driver was tested using gpio-keys and iadc/vadc on the LG Nexus 5
(hammerhead) phone.

Signed-off-by: Brian Masney <masneyb@onstation.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2019-01-24 15:33:34 +01:00
Brian Masney
135ef21ab0 spmi: pmic-arb: validate type when mapping IRQ
qpnpint_irq_domain_map did not validate the IRQ type and this can cause
IRQs to not work as expected if an unsupported type (such as
IRQ_TYPE_NONE) is passed in. Now that spmi-gpio is a hierarchical IRQ
controller, and all device tree bindings have been updated, add
additional validation to the type field.

Signed-off-by: Brian Masney <masneyb@onstation.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2019-01-24 15:33:33 +01:00
Brian Masney
682aefaa81 spmi: pmic-arb: disassociate old virq if hwirq mapping already exists
Check to see if the hwirq is already associated with another virq on
this IRQ domain. If so, then disassociate it before associating the
hwirq with the new virq.

This is a temporary hack that is needed in order to not break git
bisect for existing boards. The next patch in this series converts
spmi-gpio to be a hierarchical IRQ chip, then there are several patches
to update all of the device tree files, and finally this patch will be
reverted within the same patch series.

IRQs for spmi-gpio are all initially setup without an IRQ hierarchy
on pmic-arb when mfd/qcom-spmi-pmic.c is probed (via the
devm_of_platform_populate call) due to the interrupts property in
device tree. Once spmi-gpio is converted to be a hierarchical IRQ chip
in the next patch, existing users of gpio[d]_to_irq() will call
pmic_gpio_to_irq(), and that will use the new IRQ chip code in
spmi-gpio that sets up the IRQ in an IRQ hierarchy. The hwirq is now
associated with two Linux virqs and interrupts will not work as
expected. This patch corrects that issue.

Driver was tested using gpio-keys and iadc/vadc on the LG Nexus 5
(hammerhead) phone.

Signed-off-by: Brian Masney <masneyb@onstation.org>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2019-01-24 15:33:04 +01:00
Brian Masney
12a9eeaebb spmi: pmic-arb: convert to v2 irq interfaces to support hierarchical IRQ chips
Convert the spmi-pmic-arb IRQ code to use the version 2 IRQ interface
in order to support hierarchical IRQ chips. This is necessary so that
spmi-gpio can be setup as a hierarchical IRQ chip with pmic-arb as the
parent. IRQ chips in device tree should be usable from the start without
the consumer having to make an additional call to gpio[d]_to_irq() to
get the proper IRQ on the parent.

The old qpnpint_irq_domain_map function would hardcode the handler as
handle_level_irq, however qpnpint_irq_set_type would later override the
handler. Properly set the handler when the IRQ is mapped. This new code
doesn't return an error for IRQ_TYPE_NONE and preserves the existing
behavior of using handle_level_irq since there are some broken device
tree bindings that need to be corrected first.

Driver was tested on a LG Nexus 5 (hammerhead) phone.

Signed-off-by: Brian Masney <masneyb@onstation.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2019-01-24 15:32:52 +01:00
Kiran Gunda
2fb4f2581d spmi: pmic-arb: Move the ownership check to irq_chip callback
Check the irq ownership in the irq_request_resources callback
instead of checking it during the irq mapping. This can prevent
installing the flow handler for the interrupt that is not owned by the EE
and allow the irq translation during the gpio driver probe.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Tested-by: Shawn Guo <shawnguo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:52:22 +02:00
Rob Herring
e55fe64a19 spmi: Convert to using %pOF instead of full_name
Now that we have a custom printf format specifier, convert users of
full_name to use %pOF instead. This is preparation to remove storing
of the full path string for each node.

Signed-off-by: Rob Herring <robh@kernel.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:20 +02:00
Fenglin Wu
53d296b594 spmi: pmic-arb: Remove checking opc value not less than 0
The opc parameter in pmic_arb_write_cmd() function is defined with type
u8 and it's always greater than or equal to 0. Checking that it's not
less than 0 is redundant and it can cause a forbidden warning during
compilation. Remove the check.

Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
David Collins
40f318f0ed spmi: pmic-arb: add support for HW version 5
Add support for version 5 of the SPMI PMIC arbiter.  It utilizes
different offsets for registers than those found on version 3.
Also, the procedure to determine if writing and IRQ access is
allowed for a given PPID changes for version 5.

Signed-off-by: David Collins <collinsd@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
000e1a43d3 spmi: pmic-arb: fix a possible null pointer dereference
If "core" memory resource is not specified, then the driver could
end up dereferencing a null pointer. Fix this issue.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
e95d073c8c spmi: pmic-arb: return __iomem pointer instead of offset
Modify the pmic_arb version ops to return an __iomem pointer
to the address instead of an offset. That way we do not need to
care about the base address changes in the new HW version.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
cdeef07a8d spmi: pmic-arb: use irq_chip callback to set spmi irq wakeup capability
Currently the driver sets the pmic arbiter core interrupt as wakeup capable
irrespective of the child irqs which causes the system to wakeup
unnecessarily. To fix this, set the core interrupt as wakeup capable
only if any of the child irqs request for it. Do this by marking it as
wakeup capable in the irq_set_wake callback.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
ff615ed91b spmi: pmic-arb: return the value instead of passing by pointer
Returning the output value from a function, when it is possible, is the
better and cleaner way than passing it by the pointer. Hence, modify
the ppid_to_apid mapping function to return apid instead of passing
it by a pointer. While at it, pass the ppid as function parameter to
ppid_to_apid mapping function instead of passing the sid and addr.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
9f7a9a448d spmi: pmic-arb: replace the writel_relaxed with __raw_writel
Replace the writel_relaxed with __raw_writel to avoid byte swapping
in pmic_arb_write_data() function. That way the code is independent
of the CPU endianness.

Fixes: 111a10bf3e ("spmi: pmic-arb: rename spmi_pmic_arb_dev to
spmi_pmic_arb")
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
4788e613a6 spmi: pmic-arb: fix memory allocation for mapping_table
Allocate the correct memory size (max_pmic_peripherals) for the
mapping_table that holds the apid to ppid mapping. Also use a local
variable for mapping_table for better alignment of the code.

Fixes: 987a9f128b ("spmi: pmic-arb: Support more than 128 peripherals")
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
325255bc95 spmi: pmic-arb: optimize qpnpint_irq_set_type function
Optimize the qpnpint_irq_set_type() by using a local variable
to hold the handler type. Also clean up other variable usage.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
f2f3156472 spmi: pmic-arb: clean up pmic_arb_find_apid function
Clean up the pmic_arb_find_apid() by using the local
variables to improve the code readability.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
02abec3616 spmi: pmic-arb: rename pa_xx to pmic_arb_xx and other cleanup
This patch cleans up the following.

- Rename the "pa" to "pmic_arb".
- Rename the spmi_pmic_arb *dev to spmi_pmic_arb *pmic_arb.
- Rename the pa_{read,write}_data() functions to
  pmic_arb_{read,write}_data().
- Rename channel to APID.
- Rename the HWIRQ_*() macros to hwirq_to_*().

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Kiran Gunda
b319b5922d spmi: pmic-arb: remove the read/write access checks
The access mode checks for peripheral ownership for read/write
permissions should not be required. Every peripheral enabled for
this master is expected to have a read/write permissions. If there
is any such invalid access due to wrong configuration in boot loader
or device tree files, then it should be fixed in those locations.
Hence, remove the access mode checks from the driver.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 13:51:19 +02:00
Stephen Boyd
eba9718ed2 spmi: pmic-arb: Always allocate ppid_to_apid table
After commit 7f1d4e58da ("spmi: pmic-arb: optimize table
lookups") we always need the ppid_to_apid table regardless of the
version of pmic arbiter we have. Otherwise, we will try to deref
the array when we don't allocate it on v2 hardware like the
msm8974 SoCs.

Cc: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Cc: Kiran Gunda <kgunda@codeaurora.org>
Fixes: 7f1d4e58da ("spmi: pmic-arb: optimize table lookups")
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Tested-by: Luca Weiss <luca@z3ntu.xyz>
Reviewed-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-07-17 15:00:47 +02:00
Bjorn Andersson
d50daa2af2 spmi: Include OF based modalias in device uevent
Include the OF-based modalias in the uevent sent when registering SPMI
devices, so that user space has a chance to autoload the kernel module
for the device.

Tested-by: Rob Clark <robdclark@gmail.com>
Reported-by: Rob Clark <robdclark@gmail.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-07-17 15:00:47 +02:00
Kiran Gunda
76b069b1cb spmi: spmi-pmic-arb: enable the SPMI interrupt as a wakeup source
Currently the SPMI interrupt will not wake the device. Enable this
interrupt as a wakeup source.

Signed-off-by: Nicholas Troast <ntroast@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
319f68843d spmi: pmic_arb: add support for PMIC bus arbiter v3
PMIC bus arbiter v3 supports 512 SPMI peripherals. Add the v3 operators to
support this new arbiter version.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
472eaf8bed spmi: pmic-arb: check apid enabled before calling the handler
The driver currently invokes the apid handler (periph_handler())
once it sees that the summary status bit for that apid is set.

However the hardware is designed to set that bit even if the apid
interrupts are disabled. The driver should check whether the apid
is indeed enabled before calling the apid handler.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
5f9b2ea3da spmi: pmic_arb: use appropriate flow handler
The current code uses handle_level_irq flow handler even if the
trigger type of the interrupt is edge. This can lead to missing
of an edge transition that happens when the interrupt is being
handled. The level flow handler masks the interrupt while it is
being handled, so if an edge transition happens at that time,
that edge is lost.

Use an edge flow handler for edge type interrupts which ensures
that the interrupt stays enabled while being handled - at least
until it triggers at which point the flow handler sets the
IRQF_PENDING flag and only then masks the interrupt. That
IRQF_PENDING state indicates an edge transition happened while
the interrupt was being handled and the handler is called again.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
cee0fad772 spmi: pmic-arb: clear the latched status of the interrupt
PMIC interrupts each have an internal latched status bit which is
not visible from any register.  This status bit is set as soon as
the conditions specified in the interrupt type and polarity
registers are met even if the interrupt is not enabled.  When it
is set, nothing else changes within the PMIC and no interrupt
notification packets are sent.  If the internal latched status
bit is set when an interrupt is enabled, then the value is
immediately propagated into the interrupt latched status register
and an interrupt notification packet is sent out from the PMIC
over SPMI.

This PMIC hardware behavior can lead to a situation where the
handler for a level triggered interrupt is called immediately
after enable_irq() is called even though the interrupt physically
triggered while it was disabled within the genirq framework.
This situation takes place if the the interrupt fires twice after
calling disable_irq().  The first time it fires, the level flow
handler will mask and disregard it.  Unfortunately, the second
time it fires, the internal latched status bit is set within the
PMIC and no further notification is received.  When enable_irq()
is called later, the interrupt is unmasked (enabled in the PMIC)
which results in the PMIC immediately sending an interrupt
notification packet out over SPMI.  This breaks the semantics
of level triggered interrupts within the genirq framework since
they should be completely ignored while disabled.

The PMIC internal latched status behavior also affects how
interrupts are treated during suspend.  While entering suspend,
all interrupts not specified as wakeup mode are masked.  Upon
resume, these interrupts are unmasked.  Thus if any of the
non-wakeup PMIC interrupts fired while the system was suspended,
then the PMIC will send interrupt notification packets out via
SPMI as soon as they are unmasked during resume.  This behavior
violates genirq semantics as well since non-wakeup interrupts
should be completely ignored during suspend.

Modify the qpnpint_irq_unmask() function so that the interrupt
latched status clear register is written immediately before the
interrupt enable register.  This clears the internal latched
status bit of the interrupt so that it cannot trigger spuriously
immediately upon being enabled.

Also, while resuming an irq, an unmask could be called even if it
was not previously masked.  So, before writing these registers,
check if the interrupt is already enabled within the PMIC. If it
is, then no further register writes are required.  This
condition check ensures that a valid latched status register bit
is not cleared until it is properly handled.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
f6dda8e2e8 spmi: pmic-arb: fix missing interrupts
irq_enable is called when the device resumes. Note that the
irq_enable is called regardless of whether the interrupt was
marked enabled/disabled in the descriptor or whether it was
masked/unmasked at the controller while resuming.

The current driver unconditionally clears the interrupt in its
irq_enable callback. This is dangerous as any interrupts that
happen right before the resume could be missed.
Remove the irq_enable callback and use mask/unmask instead.

Also remove struct pmic_arb_irq_spec as it serves no real purpose.
It is used only in the translate function and the code is much
cleaner without it.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
6bc546e71e spmi: pmic-arb: cleanup unrequested irqs
We see a unmapped irqs trigger right around bootup. This could
likely be because the bootloader exited leaving the interrupts
in an unknown or unhandled state.  Ack and mask the interrupt
if one is found. A request_irq later will unmask it and also
setup proper mapping structures.

Also the current driver ensures that no read/write transaction
is in progress while it makes changes to the interrupt regions.
This is not necessary because read/writes over spmi and arbiter
interrupt control are independent operations. Hence, remove the
synchronized accesses to interrupt region.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
7f1d4e58da spmi: pmic-arb: optimize table lookups
The current driver uses a mix of radix tree and a fwd lookup
table to translate between apid and ppid. It is buggy and confusing.

Instead simply use a radix tree for v1 hardware and use the
forward lookup table for v2.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
1ef1ce4e9d spmi: pmic-arb: fix inconsistent use of apid and chan
The driver currently uses "apid" and "chan" to mean apid. Remove
the use of chan and use only apid.

On a SPMI bus there is allocation to manage up to 4K peripherals.
However, in practice only few peripherals are instantiated
and only few among the instantiated ones actually interrupt.

APID is CPU's way of keeping track of peripherals that could interrupt.
There is a table that maps the 256 interrupting peripherals to
a number between 0 and 255. This number is called APID. Information about
that interrupting peripheral is stored in registers offset by its
corresponding apid.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
111a10bf3e spmi: pmic-arb: rename spmi_pmic_arb_dev to spmi_pmic_arb
Usually *_dev best used for structures that embed a struct device in
them. spmi_pmic_arb_dev doesn't embed one. It is simply a driver data
structure. Use an appropriate name for it.

Also there are many places in the driver that left shift the bit to
generate a bit mask. Replace it with the BIT() macro.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Abhijeet Dharmapurikar
57102ad792 spmi: pmic_arb: block access of invalid read and writes
The system crashes due to bad access when reading from an non configured
peripheral and when writing to peripheral which is not owned by current
ee. This patch verifies ownership to avoid crashing on
write.
For reads, since the forward mapping table, data_channel->ppid, is
towards the end of the block, we use the core size to figure the
max number of ppids supported. The table starts at an offset of 0x800
within the block, so size - 0x800 will give us the area used by the
table. Since each table is 4 bytes long (core_size - 0x800) / 4 will
gives us the number of data_channel supported.
This new protection is functional on hw v2.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-03 19:05:47 +09:00
Christophe JAILLET
e98cc182a0 spmi: pmic-arb: Return an error code if sanity check fails
If the test 'if (channel > 5)' is true, then we will return 'err' which
is known to be 0 at this point.
Return -EINVAL instead.

Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-09-27 12:43:34 +02:00
Sudip Mukherjee
47f55b74cf spmi: do not use bus internal data
The variable p is a data structure which is used by the driver core
internally and it is not expected that busses will be directly accessing
these driver core internal only data.

Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-04-30 14:15:56 -07:00
Stephen Boyd
987a9f128b spmi: pmic-arb: Support more than 128 peripherals
Add support for more than 128 peripherals by taking a lazy
caching approach to the mapping tables. Instead of reading and
caching the tables at boot given some fixed size, read them and
cache them on an as needed basis. We still assume a max size of
512 peripherals, trading off some space for simplicity.

Based on a patch by Gilad Avidov <gavidov@codeaurora.org> and
Sagar Dharia <sdharia@codeaurora.org>.

Cc: Gilad Avidov <gavidov@codeaurora.org>
Cc: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-02-08 14:57:30 -08:00