mirror of https://gitee.com/openkylin/linux.git
- Core Frameworks
- Add support for a "resource managed strongly uncachable ioremap" call - Provide a collection of MFD helper macros - Remove mfd_clone_cell() from MFD core - Add NULL de-reference protection in MFD core - Remove superfluous function fd_platform_add_cell() from MFD core - Honour Device Tree's request to disable a device - New Drivers - Add support for MediaTek MT6323 PMIC - New Device Support - Add support for Gemini Lake to Intel LPSS PCI - Add support for Cherry Trail Crystal Cover PMIC to Intel SoC PMIC CRC - Add support for PM{I}8950 to Qualcomm SPMI PMIC - Add support for U8420 to ST-Ericsson DB8500 - Add support for Comet Lake PCH-H to Intel LPSS PCI - New Functionality - Add support for requested supply clocks; madera-core - Fix-ups - Lower interrupt priority; rk808 - Use provided helpers (macros, group functions, defines); rk808, ipaq-micro, ab8500-core, db8500-prcmu, mt6397-core, cs5535-mfd - Only allocate IRQs on request; max77620 - Use simplified API; arizona-core - Remove redundant and/or duplicated code; wm8998-tables, arizona, syscon - Device Tree binding fix-ups; madera, max77650, max77693 - Remove mfd_cell->id abuse hack; cs5535-mfd - Remove only user of mfd_clone_cell(); cs5535-mfd - Make resources static; rohm-bd70528 - Bug Fixes - Fix product ID for RK818; rk808 - Fix Power Key; rk808 - Fix booting on the BananaPi; mt6397-core - Endian fix-ups; twl.h - Fix static error checker warnings; ti_am335x_tscadc -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAl3f2k4ACgkQUa+KL4f8 d2GmohAAluAT7hhURCf2HECsbVpeLH5i5UahRTCAlyIqeAiOjGEBGdIT2fYM1B+3 daqj3XiiLqvlnT5FZc4Fw5gR9Nu6Oe+Fo+6p6NnAu7CIt+x9RXOTB5LLXYYKICZK c32SnsSbRQwtzu83d3CjlfQRUZh66fJksWVPnOBkenaR7HaQlujKydBAk3kkLygZ 3GGTzjTXakl/53XJLRNn2wVVEG2gCicZwWxmWYW2000PFWo1upCeJRcwHBOXyy1I oh+KNp28gVQLT3pOte4TZEO3GNacMMs5DvA0hj2j7j+nH5FOryEPjUNbrqkcR+9T aquGbgYWgfJrW9UJhgNVsn754y5sgZ48Q20533AICMDfy3JTzfn91pX5q8mVFaPl Kf4cTVAau7kUCVxrXWuOG2fG2r7BjRABKU5ODDsGWmfWQNdktvLvHJI4j97ct0xj neBijJya70woV1o40v5yTmcUcc7hGEoKXuRWslxNK3K+nQkgRKMKgY4dm3jBeSmD lmBrjtjT0gcNl6+bOOn6IXn5k3sxWUwa799LUDaR5oHj6kB0LkIqz3h6UlOBryKO iQ2xXXCf/gAlkL75SW1rjYBHWkMkswgigppcbw2HB9tMqGL2LtHtgIli8CfGz1vs BzwxOQRvMK+4rG0qNHbocXJK2O4PduTxMXtBDiVK/tXrHaNLs7I= =mugH -----END PGP SIGNATURE----- Merge tag 'mfd-next-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "Core Frameworks: - Add support for a "resource managed strongly uncachable ioremap" call - Provide a collection of MFD helper macros - Remove mfd_clone_cell() from MFD core - Add NULL de-reference protection in MFD core - Remove superfluous function fd_platform_add_cell() from MFD core - Honour Device Tree's request to disable a device New Drivers: - Add support for MediaTek MT6323 PMIC New Device Support: - Add support for Gemini Lake to Intel LPSS PCI - Add support for Cherry Trail Crystal Cover PMIC to Intel SoC PMIC CRC - Add support for PM{I}8950 to Qualcomm SPMI PMIC - Add support for U8420 to ST-Ericsson DB8500 - Add support for Comet Lake PCH-H to Intel LPSS PCI New Functionality: - Add support for requested supply clocks; madera-core Fix-ups: - Lower interrupt priority; rk808 - Use provided helpers (macros, group functions, defines); rk808, ipaq-micro, ab8500-core, db8500-prcmu, mt6397-core, cs5535-mfd - Only allocate IRQs on request; max77620 - Use simplified API; arizona-core - Remove redundant and/or duplicated code; wm8998-tables, arizona, syscon - Device Tree binding fix-ups; madera, max77650, max77693 - Remove mfd_cell->id abuse hack; cs5535-mfd - Remove only user of mfd_clone_cell(); cs5535-mfd - Make resources static; rohm-bd70528 Bug Fixes: - Fix product ID for RK818; rk808 - Fix Power Key; rk808 - Fix booting on the BananaPi; mt6397-core - Endian fix-ups; twl.h - Fix static error checker warnings; ti_am335x_tscadc" * tag 'mfd-next-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (47 commits) Revert "mfd: syscon: Set name of regmap_config" mfd: ti_am335x_tscadc: Fix static checker warning mfd: bd70528: Staticize bit value definitions mfd: mfd-core: Honour Device Tree's request to disable a child-device dt-bindings: mfd: max77693: Fix missing curly brace mfd: intel-lpss: Add Intel Comet Lake PCH-H PCI IDs mfd: db8500-prcmu: Support U8420-sysclk firmware dt-bindings: mfd: max77650: Convert the binding document to yaml mfd: mfd-core: Move pdev->mfd_cell creation back into mfd_add_device() mfd: mfd-core: Remove usage counting for .{en,dis}able() call-backs x86: olpc-xo1-sci: Remove invocation of MFD's .enable()/.disable() call-backs x86: olpc-xo1-pm: Remove invocation of MFD's .enable()/.disable() call-backs mfd: mfd-core: Remove mfd_clone_cell() mfd: mfd-core: Protect against NULL call-back function pointer mfd: cs5535-mfd: Register clients using their own dedicated MFD cell entries mfd: cs5535-mfd: Request shared IO regions centrally mfd: cs5535-mfd: Remove mfd_cell->id hack mfd: cs5535-mfd: Use PLATFORM_DEVID_* defines and tidy error message mfd: intel_soc_pmic_crc: Add "cht_crystal_cove_pmic" cell to CHT cells mfd: madera: Add support for requesting the supply clocks ...
This commit is contained in:
commit
37323918ca
|
@ -67,6 +67,14 @@ Optional properties:
|
||||||
As defined in bindings/gpio.txt.
|
As defined in bindings/gpio.txt.
|
||||||
Although optional, it is strongly recommended to use a hardware reset
|
Although optional, it is strongly recommended to use a hardware reset
|
||||||
|
|
||||||
|
- clocks: Should reference the clocks supplied on MCLK1, MCLK2 and MCLK3
|
||||||
|
- clock-names: May contain up to three strings:
|
||||||
|
"mclk1" for the clock supplied on MCLK1, recommended to be a high
|
||||||
|
quality audio reference clock
|
||||||
|
"mclk2" for the clock supplied on MCLK2, required to be an always on
|
||||||
|
32k clock
|
||||||
|
"mclk3" for the clock supplied on MCLK3
|
||||||
|
|
||||||
- MICBIASx : Initial data for the MICBIAS regulators, as covered in
|
- MICBIASx : Initial data for the MICBIAS regulators, as covered in
|
||||||
Documentation/devicetree/bindings/regulator/regulator.txt.
|
Documentation/devicetree/bindings/regulator/regulator.txt.
|
||||||
One for each MICBIAS generator (MICBIAS1, MICBIAS2, ...)
|
One for each MICBIAS generator (MICBIAS1, MICBIAS2, ...)
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
MAX77650 ultra low-power PMIC from Maxim Integrated.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
-------------------
|
|
||||||
- compatible: Must be "maxim,max77650"
|
|
||||||
- reg: I2C device address.
|
|
||||||
- interrupts: The interrupt on the parent the controller is
|
|
||||||
connected to.
|
|
||||||
- interrupt-controller: Marks the device node as an interrupt controller.
|
|
||||||
- #interrupt-cells: Must be <2>.
|
|
||||||
|
|
||||||
- gpio-controller: Marks the device node as a gpio controller.
|
|
||||||
- #gpio-cells: Must be <2>. The first cell is the pin number and
|
|
||||||
the second cell is used to specify the gpio active
|
|
||||||
state.
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
--------------------
|
|
||||||
gpio-line-names: Single string containing the name of the GPIO line.
|
|
||||||
|
|
||||||
The GPIO-controller module is represented as part of the top-level PMIC
|
|
||||||
node. The device exposes a single GPIO line.
|
|
||||||
|
|
||||||
For device-tree bindings of other sub-modules (regulator, power supply,
|
|
||||||
LEDs and onkey) refer to the binding documents under the respective
|
|
||||||
sub-system directories.
|
|
||||||
|
|
||||||
For more details on GPIO bindings, please refer to the generic GPIO DT
|
|
||||||
binding document <devicetree/bindings/gpio/gpio.txt>.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
--------
|
|
||||||
|
|
||||||
pmic@48 {
|
|
||||||
compatible = "maxim,max77650";
|
|
||||||
reg = <0x48>;
|
|
||||||
|
|
||||||
interrupt-controller;
|
|
||||||
interrupt-parent = <&gpio2>;
|
|
||||||
#interrupt-cells = <2>;
|
|
||||||
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
|
|
||||||
|
|
||||||
gpio-controller;
|
|
||||||
#gpio-cells = <2>;
|
|
||||||
gpio-line-names = "max77650-charger";
|
|
||||||
};
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/mfd/max77650.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: MAX77650 ultra low-power PMIC from Maxim Integrated.
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Bartosz Golaszewski <bgolaszewski@baylibre.com>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
MAX77650 is an ultra-low power PMIC providing battery charging and power
|
||||||
|
supply for low-power IoT and wearable applications.
|
||||||
|
|
||||||
|
The GPIO-controller module is represented as part of the top-level PMIC
|
||||||
|
node. The device exposes a single GPIO line.
|
||||||
|
|
||||||
|
For device-tree bindings of other sub-modules (regulator, power supply,
|
||||||
|
LEDs and onkey) refer to the binding documents under the respective
|
||||||
|
sub-system directories.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: maxim,max77650
|
||||||
|
|
||||||
|
reg:
|
||||||
|
description:
|
||||||
|
I2C device address.
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
interrupt-controller: true
|
||||||
|
|
||||||
|
"#interrupt-cells":
|
||||||
|
const: 2
|
||||||
|
description:
|
||||||
|
The first cell is the IRQ number, the second cell is the trigger type.
|
||||||
|
|
||||||
|
gpio-controller: true
|
||||||
|
|
||||||
|
"#gpio-cells":
|
||||||
|
const: 2
|
||||||
|
description:
|
||||||
|
The first cell is the pin number and the second cell is used to specify
|
||||||
|
the gpio active state.
|
||||||
|
|
||||||
|
gpio-line-names:
|
||||||
|
maxItems: 1
|
||||||
|
description:
|
||||||
|
Single string containing the name of the GPIO line.
|
||||||
|
|
||||||
|
regulators:
|
||||||
|
$ref: ../regulator/max77650-regulator.yaml
|
||||||
|
|
||||||
|
charger:
|
||||||
|
$ref: ../power/supply/max77650-charger.yaml
|
||||||
|
|
||||||
|
leds:
|
||||||
|
$ref: ../leds/leds-max77650.yaml
|
||||||
|
|
||||||
|
onkey:
|
||||||
|
$ref: ../input/max77650-onkey.yaml
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- interrupts
|
||||||
|
- interrupt-controller
|
||||||
|
- "#interrupt-cells"
|
||||||
|
- gpio-controller
|
||||||
|
- "#gpio-cells"
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
#include <dt-bindings/input/linux-event-codes.h>
|
||||||
|
i2c {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
pmic@48 {
|
||||||
|
compatible = "maxim,max77650";
|
||||||
|
reg = <0x48>;
|
||||||
|
|
||||||
|
interrupt-controller;
|
||||||
|
interrupt-parent = <&gpio2>;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
|
||||||
|
|
||||||
|
gpio-controller;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
gpio-line-names = "max77650-charger";
|
||||||
|
|
||||||
|
regulators {
|
||||||
|
compatible = "maxim,max77650-regulator";
|
||||||
|
|
||||||
|
max77650_ldo: regulator@0 {
|
||||||
|
regulator-compatible = "ldo";
|
||||||
|
regulator-name = "max77650-ldo";
|
||||||
|
regulator-min-microvolt = <1350000>;
|
||||||
|
regulator-max-microvolt = <2937500>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77650_sbb0: regulator@1 {
|
||||||
|
regulator-compatible = "sbb0";
|
||||||
|
regulator-name = "max77650-sbb0";
|
||||||
|
regulator-min-microvolt = <800000>;
|
||||||
|
regulator-max-microvolt = <1587500>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
charger {
|
||||||
|
compatible = "maxim,max77650-charger";
|
||||||
|
input-voltage-min-microvolt = <4200000>;
|
||||||
|
input-current-limit-microamp = <285000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
leds {
|
||||||
|
compatible = "maxim,max77650-led";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
led@0 {
|
||||||
|
reg = <0>;
|
||||||
|
label = "blue:usr0";
|
||||||
|
};
|
||||||
|
|
||||||
|
led@1 {
|
||||||
|
reg = <1>;
|
||||||
|
label = "red:usr1";
|
||||||
|
linux,default-trigger = "heartbeat";
|
||||||
|
};
|
||||||
|
|
||||||
|
led@2 {
|
||||||
|
reg = <2>;
|
||||||
|
label = "green:usr2";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
onkey {
|
||||||
|
compatible = "maxim,max77650-onkey";
|
||||||
|
linux,code = <KEY_END>;
|
||||||
|
maxim,onkey-slide;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -175,6 +175,7 @@ Example:
|
||||||
maxim,thermal-regulation-celsius = <75>;
|
maxim,thermal-regulation-celsius = <75>;
|
||||||
maxim,battery-overcurrent-microamp = <3000000>;
|
maxim,battery-overcurrent-microamp = <3000000>;
|
||||||
maxim,charge-input-threshold-microvolt = <4300000>;
|
maxim,charge-input-threshold-microvolt = <4300000>;
|
||||||
|
};
|
||||||
|
|
||||||
led {
|
led {
|
||||||
compatible = "maxim,max77693-led";
|
compatible = "maxim,max77693-led";
|
||||||
|
|
|
@ -29,6 +29,8 @@ Required properties:
|
||||||
"qcom,pm8916",
|
"qcom,pm8916",
|
||||||
"qcom,pm8004",
|
"qcom,pm8004",
|
||||||
"qcom,pm8909",
|
"qcom,pm8909",
|
||||||
|
"qcom,pm8950",
|
||||||
|
"qcom,pmi8950",
|
||||||
"qcom,pm8998",
|
"qcom,pm8998",
|
||||||
"qcom,pmi8998",
|
"qcom,pmi8998",
|
||||||
"qcom,pm8005",
|
"qcom,pm8005",
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
Device-Tree bindings for MediaTek PMIC based RTC
|
||||||
|
|
||||||
|
MediaTek PMIC based RTC is an independent function of MediaTek PMIC that works
|
||||||
|
as a type of multi-function device (MFD). The RTC can be configured and set up
|
||||||
|
with PMIC wrapper bus which is a common resource shared with the other
|
||||||
|
functions found on the same PMIC.
|
||||||
|
|
||||||
|
For MediaTek PMIC MFD bindings, see:
|
||||||
|
../mfd/mt6397.txt
|
||||||
|
|
||||||
|
For MediaTek PMIC wrapper bus bindings, see:
|
||||||
|
../soc/mediatek/pwrap.txt
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: Should be one of follows
|
||||||
|
"mediatek,mt6323-rtc": for MT6323 PMIC
|
||||||
|
"mediatek,mt6397-rtc": for MT6397 PMIC
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
pmic {
|
||||||
|
compatible = "mediatek,mt6323";
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
rtc {
|
||||||
|
compatible = "mediatek,mt6323-rtc";
|
||||||
|
};
|
||||||
|
};
|
|
@ -314,6 +314,7 @@ IOMAP
|
||||||
devm_ioport_unmap()
|
devm_ioport_unmap()
|
||||||
devm_ioremap()
|
devm_ioremap()
|
||||||
devm_ioremap_nocache()
|
devm_ioremap_nocache()
|
||||||
|
devm_ioremap_uc()
|
||||||
devm_ioremap_wc()
|
devm_ioremap_wc()
|
||||||
devm_ioremap_resource() : checks resource, requests memory region, ioremaps
|
devm_ioremap_resource() : checks resource, requests memory region, ioremaps
|
||||||
devm_ioremap_resource_wc()
|
devm_ioremap_resource_wc()
|
||||||
|
|
|
@ -10396,6 +10396,13 @@ S: Maintained
|
||||||
F: drivers/net/dsa/mt7530.*
|
F: drivers/net/dsa/mt7530.*
|
||||||
F: net/dsa/tag_mtk.c
|
F: net/dsa/tag_mtk.c
|
||||||
|
|
||||||
|
MEDIATEK BOARD LEVEL SHUTDOWN DRIVERS
|
||||||
|
M: Sean Wang <sean.wang@mediatek.com>
|
||||||
|
L: linux-pm@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
|
||||||
|
F: drivers/power/reset/mt6323-poweroff.c
|
||||||
|
|
||||||
MEDIATEK JPEG DRIVER
|
MEDIATEK JPEG DRIVER
|
||||||
M: Rick Chang <rick.chang@mediatek.com>
|
M: Rick Chang <rick.chang@mediatek.com>
|
||||||
M: Bin Liu <bin.liu@mediatek.com>
|
M: Bin Liu <bin.liu@mediatek.com>
|
||||||
|
|
|
@ -84,6 +84,7 @@ static void __init ux500_init_irq(void)
|
||||||
struct resource r;
|
struct resource r;
|
||||||
|
|
||||||
irqchip_init();
|
irqchip_init();
|
||||||
|
prcmu_early_init();
|
||||||
np = of_find_compatible_node(NULL, NULL, "stericsson,db8500-prcmu");
|
np = of_find_compatible_node(NULL, NULL, "stericsson,db8500-prcmu");
|
||||||
of_address_to_resource(np, 0, &r);
|
of_address_to_resource(np, 0, &r);
|
||||||
of_node_put(np);
|
of_node_put(np);
|
||||||
|
@ -91,7 +92,6 @@ static void __init ux500_init_irq(void)
|
||||||
pr_err("could not find PRCMU base resource\n");
|
pr_err("could not find PRCMU base resource\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
prcmu_early_init(r.start, r.end-r.start);
|
|
||||||
ux500_pm_init(r.start, r.end-r.start);
|
ux500_pm_init(r.start, r.end-r.start);
|
||||||
|
|
||||||
/* Unlock before init */
|
/* Unlock before init */
|
||||||
|
|
|
@ -407,6 +407,7 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ioremap_nocache(X,Y) ioremap((X),(Y))
|
#define ioremap_nocache(X,Y) ioremap((X),(Y))
|
||||||
|
#define ioremap_uc(X,Y) ioremap((X),(Y))
|
||||||
#define ioremap_wc(X,Y) ioremap((X),(Y))
|
#define ioremap_wc(X,Y) ioremap((X),(Y))
|
||||||
#define ioremap_wt(X,Y) ioremap((X),(Y))
|
#define ioremap_wt(X,Y) ioremap((X),(Y))
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/mfd/core.h>
|
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include <linux/olpc-ec.h>
|
#include <linux/olpc-ec.h>
|
||||||
|
|
||||||
|
@ -120,16 +119,11 @@ static const struct platform_suspend_ops xo1_suspend_ops = {
|
||||||
static int xo1_pm_probe(struct platform_device *pdev)
|
static int xo1_pm_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
int err;
|
|
||||||
|
|
||||||
/* don't run on non-XOs */
|
/* don't run on non-XOs */
|
||||||
if (!machine_is_olpc())
|
if (!machine_is_olpc())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
err = mfd_cell_enable(pdev);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
dev_err(&pdev->dev, "can't fetch device resource info\n");
|
dev_err(&pdev->dev, "can't fetch device resource info\n");
|
||||||
|
@ -152,8 +146,6 @@ static int xo1_pm_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
static int xo1_pm_remove(struct platform_device *pdev)
|
static int xo1_pm_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
mfd_cell_disable(pdev);
|
|
||||||
|
|
||||||
if (strcmp(pdev->name, "cs5535-pms") == 0)
|
if (strcmp(pdev->name, "cs5535-pms") == 0)
|
||||||
pms_base = 0;
|
pms_base = 0;
|
||||||
else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0)
|
else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0)
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/pm_wakeup.h>
|
#include <linux/pm_wakeup.h>
|
||||||
#include <linux/mfd/core.h>
|
|
||||||
#include <linux/power_supply.h>
|
#include <linux/power_supply.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
@ -537,10 +536,6 @@ static int xo1_sci_probe(struct platform_device *pdev)
|
||||||
if (!machine_is_olpc())
|
if (!machine_is_olpc())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
r = mfd_cell_enable(pdev);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
dev_err(&pdev->dev, "can't fetch device resource info\n");
|
dev_err(&pdev->dev, "can't fetch device resource info\n");
|
||||||
|
@ -605,7 +600,6 @@ static int xo1_sci_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
static int xo1_sci_remove(struct platform_device *pdev)
|
static int xo1_sci_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
mfd_cell_disable(pdev);
|
|
||||||
free_irq(sci_irq, pdev);
|
free_irq(sci_irq, pdev);
|
||||||
cancel_work_sync(&sci_work);
|
cancel_work_sync(&sci_work);
|
||||||
free_ec_sci();
|
free_ec_sci();
|
||||||
|
|
|
@ -610,107 +610,53 @@ int ab8500_suspend(struct ab8500 *ab8500)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct mfd_cell ab8500_bm_devs[] = {
|
static const struct mfd_cell ab8500_bm_devs[] = {
|
||||||
{
|
OF_MFD_CELL("ab8500-charger", NULL, &ab8500_bm_data,
|
||||||
.name = "ab8500-charger",
|
sizeof(ab8500_bm_data), 0, "stericsson,ab8500-charger"),
|
||||||
.of_compatible = "stericsson,ab8500-charger",
|
OF_MFD_CELL("ab8500-btemp", NULL, &ab8500_bm_data,
|
||||||
.platform_data = &ab8500_bm_data,
|
sizeof(ab8500_bm_data), 0, "stericsson,ab8500-btemp"),
|
||||||
.pdata_size = sizeof(ab8500_bm_data),
|
OF_MFD_CELL("ab8500-fg", NULL, &ab8500_bm_data,
|
||||||
},
|
sizeof(ab8500_bm_data), 0, "stericsson,ab8500-fg"),
|
||||||
{
|
OF_MFD_CELL("ab8500-chargalg", NULL, &ab8500_bm_data,
|
||||||
.name = "ab8500-btemp",
|
sizeof(ab8500_bm_data), 0, "stericsson,ab8500-chargalg"),
|
||||||
.of_compatible = "stericsson,ab8500-btemp",
|
|
||||||
.platform_data = &ab8500_bm_data,
|
|
||||||
.pdata_size = sizeof(ab8500_bm_data),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "ab8500-fg",
|
|
||||||
.of_compatible = "stericsson,ab8500-fg",
|
|
||||||
.platform_data = &ab8500_bm_data,
|
|
||||||
.pdata_size = sizeof(ab8500_bm_data),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "ab8500-chargalg",
|
|
||||||
.of_compatible = "stericsson,ab8500-chargalg",
|
|
||||||
.platform_data = &ab8500_bm_data,
|
|
||||||
.pdata_size = sizeof(ab8500_bm_data),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mfd_cell ab8500_devs[] = {
|
static const struct mfd_cell ab8500_devs[] = {
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
{
|
OF_MFD_CELL("ab8500-debug",
|
||||||
.name = "ab8500-debug",
|
NULL, NULL, 0, 0, "stericsson,ab8500-debug"),
|
||||||
.of_compatible = "stericsson,ab8500-debug",
|
|
||||||
},
|
|
||||||
#endif
|
#endif
|
||||||
{
|
OF_MFD_CELL("ab8500-sysctrl",
|
||||||
.name = "ab8500-sysctrl",
|
NULL, NULL, 0, 0, "stericsson,ab8500-sysctrl"),
|
||||||
.of_compatible = "stericsson,ab8500-sysctrl",
|
OF_MFD_CELL("ab8500-ext-regulator",
|
||||||
},
|
NULL, NULL, 0, 0, "stericsson,ab8500-ext-regulator"),
|
||||||
{
|
OF_MFD_CELL("ab8500-regulator",
|
||||||
.name = "ab8500-ext-regulator",
|
NULL, NULL, 0, 0, "stericsson,ab8500-regulator"),
|
||||||
.of_compatible = "stericsson,ab8500-ext-regulator",
|
OF_MFD_CELL("abx500-clk",
|
||||||
},
|
NULL, NULL, 0, 0, "stericsson,abx500-clk"),
|
||||||
{
|
OF_MFD_CELL("ab8500-gpadc",
|
||||||
.name = "ab8500-regulator",
|
NULL, NULL, 0, 0, "stericsson,ab8500-gpadc"),
|
||||||
.of_compatible = "stericsson,ab8500-regulator",
|
OF_MFD_CELL("ab8500-rtc",
|
||||||
},
|
NULL, NULL, 0, 0, "stericsson,ab8500-rtc"),
|
||||||
{
|
OF_MFD_CELL("ab8500-acc-det",
|
||||||
.name = "ab8500-clk",
|
NULL, NULL, 0, 0, "stericsson,ab8500-acc-det"),
|
||||||
.of_compatible = "stericsson,ab8500-clk",
|
OF_MFD_CELL("ab8500-poweron-key",
|
||||||
},
|
NULL, NULL, 0, 0, "stericsson,ab8500-poweron-key"),
|
||||||
{
|
OF_MFD_CELL("ab8500-pwm",
|
||||||
.name = "ab8500-gpadc",
|
NULL, NULL, 0, 1, "stericsson,ab8500-pwm"),
|
||||||
.of_compatible = "stericsson,ab8500-gpadc",
|
OF_MFD_CELL("ab8500-pwm",
|
||||||
},
|
NULL, NULL, 0, 2, "stericsson,ab8500-pwm"),
|
||||||
{
|
OF_MFD_CELL("ab8500-pwm",
|
||||||
.name = "ab8500-rtc",
|
NULL, NULL, 0, 3, "stericsson,ab8500-pwm"),
|
||||||
.of_compatible = "stericsson,ab8500-rtc",
|
OF_MFD_CELL("ab8500-denc",
|
||||||
},
|
NULL, NULL, 0, 0, "stericsson,ab8500-denc"),
|
||||||
{
|
OF_MFD_CELL("pinctrl-ab8500",
|
||||||
.name = "ab8500-acc-det",
|
NULL, NULL, 0, 0, "stericsson,ab8500-gpio"),
|
||||||
.of_compatible = "stericsson,ab8500-acc-det",
|
OF_MFD_CELL("abx500-temp",
|
||||||
},
|
NULL, NULL, 0, 0, "stericsson,abx500-temp"),
|
||||||
{
|
OF_MFD_CELL("ab8500-usb",
|
||||||
|
NULL, NULL, 0, 0, "stericsson,ab8500-usb"),
|
||||||
.name = "ab8500-poweron-key",
|
OF_MFD_CELL("ab8500-codec",
|
||||||
.of_compatible = "stericsson,ab8500-poweron-key",
|
NULL, NULL, 0, 0, "stericsson,ab8500-codec"),
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "ab8500-pwm",
|
|
||||||
.of_compatible = "stericsson,ab8500-pwm",
|
|
||||||
.id = 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "ab8500-pwm",
|
|
||||||
.of_compatible = "stericsson,ab8500-pwm",
|
|
||||||
.id = 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "ab8500-pwm",
|
|
||||||
.of_compatible = "stericsson,ab8500-pwm",
|
|
||||||
.id = 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "ab8500-denc",
|
|
||||||
.of_compatible = "stericsson,ab8500-denc",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "pinctrl-ab8500",
|
|
||||||
.of_compatible = "stericsson,ab8500-gpio",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "abx500-temp",
|
|
||||||
.of_compatible = "stericsson,abx500-temp",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "ab8500-usb",
|
|
||||||
.of_compatible = "stericsson,ab8500-usb",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "ab8500-codec",
|
|
||||||
.of_compatible = "stericsson,ab8500-codec",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mfd_cell ab9540_devs[] = {
|
static const struct mfd_cell ab9540_devs[] = {
|
||||||
|
|
|
@ -814,11 +814,7 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
/* Handle old non-standard DT binding */
|
/* Handle old non-standard DT binding */
|
||||||
pdata->reset = devm_gpiod_get_from_of_node(arizona->dev,
|
pdata->reset = devm_gpiod_get(arizona->dev, "wlf,reset", GPIOD_OUT_LOW);
|
||||||
arizona->dev->of_node,
|
|
||||||
"wlf,reset", 0,
|
|
||||||
GPIOD_OUT_LOW,
|
|
||||||
"arizona /RESET");
|
|
||||||
if (IS_ERR(pdata->reset)) {
|
if (IS_ERR(pdata->reset)) {
|
||||||
ret = PTR_ERR(pdata->reset);
|
ret = PTR_ERR(pdata->reset);
|
||||||
|
|
||||||
|
|
|
@ -27,121 +27,106 @@ enum cs5535_mfd_bars {
|
||||||
NR_BARS,
|
NR_BARS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cs5535_mfd_res_enable(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct resource *res;
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
|
||||||
if (!res) {
|
|
||||||
dev_err(&pdev->dev, "can't fetch device resource info\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!request_region(res->start, resource_size(res), DRV_NAME)) {
|
|
||||||
dev_err(&pdev->dev, "can't request region\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cs5535_mfd_res_disable(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct resource *res;
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
|
||||||
if (!res) {
|
|
||||||
dev_err(&pdev->dev, "can't fetch device resource info\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
release_region(res->start, resource_size(res));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct resource cs5535_mfd_resources[NR_BARS];
|
static struct resource cs5535_mfd_resources[NR_BARS];
|
||||||
|
|
||||||
static struct mfd_cell cs5535_mfd_cells[] = {
|
static struct mfd_cell cs5535_mfd_cells[] = {
|
||||||
{
|
{
|
||||||
.id = SMB_BAR,
|
|
||||||
.name = "cs5535-smb",
|
.name = "cs5535-smb",
|
||||||
.num_resources = 1,
|
.num_resources = 1,
|
||||||
.resources = &cs5535_mfd_resources[SMB_BAR],
|
.resources = &cs5535_mfd_resources[SMB_BAR],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.id = GPIO_BAR,
|
|
||||||
.name = "cs5535-gpio",
|
.name = "cs5535-gpio",
|
||||||
.num_resources = 1,
|
.num_resources = 1,
|
||||||
.resources = &cs5535_mfd_resources[GPIO_BAR],
|
.resources = &cs5535_mfd_resources[GPIO_BAR],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.id = MFGPT_BAR,
|
|
||||||
.name = "cs5535-mfgpt",
|
.name = "cs5535-mfgpt",
|
||||||
.num_resources = 1,
|
.num_resources = 1,
|
||||||
.resources = &cs5535_mfd_resources[MFGPT_BAR],
|
.resources = &cs5535_mfd_resources[MFGPT_BAR],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.id = PMS_BAR,
|
|
||||||
.name = "cs5535-pms",
|
.name = "cs5535-pms",
|
||||||
.num_resources = 1,
|
.num_resources = 1,
|
||||||
.resources = &cs5535_mfd_resources[PMS_BAR],
|
.resources = &cs5535_mfd_resources[PMS_BAR],
|
||||||
|
|
||||||
.enable = cs5535_mfd_res_enable,
|
|
||||||
.disable = cs5535_mfd_res_disable,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.id = ACPI_BAR,
|
|
||||||
.name = "cs5535-acpi",
|
|
||||||
.num_resources = 1,
|
|
||||||
.resources = &cs5535_mfd_resources[ACPI_BAR],
|
|
||||||
|
|
||||||
.enable = cs5535_mfd_res_enable,
|
|
||||||
.disable = cs5535_mfd_res_disable,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *olpc_acpi_clones[] = {
|
static struct mfd_cell cs5535_olpc_mfd_cells[] = {
|
||||||
"olpc-xo1-pm-acpi",
|
{
|
||||||
"olpc-xo1-sci-acpi"
|
.name = "olpc-xo1-pm-acpi",
|
||||||
|
.num_resources = 1,
|
||||||
|
.resources = &cs5535_mfd_resources[ACPI_BAR],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "olpc-xo1-sci-acpi",
|
||||||
|
.num_resources = 1,
|
||||||
|
.resources = &cs5535_mfd_resources[ACPI_BAR],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cs5535_mfd_probe(struct pci_dev *pdev,
|
static int cs5535_mfd_probe(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *id)
|
const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
int err, i;
|
int err, bar;
|
||||||
|
|
||||||
err = pci_enable_device(pdev);
|
err = pci_enable_device(pdev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* fill in IO range for each cell; subdrivers handle the region */
|
for (bar = 0; bar < NR_BARS; bar++) {
|
||||||
for (i = 0; i < ARRAY_SIZE(cs5535_mfd_cells); i++) {
|
|
||||||
int bar = cs5535_mfd_cells[i].id;
|
|
||||||
struct resource *r = &cs5535_mfd_resources[bar];
|
struct resource *r = &cs5535_mfd_resources[bar];
|
||||||
|
|
||||||
r->flags = IORESOURCE_IO;
|
r->flags = IORESOURCE_IO;
|
||||||
r->start = pci_resource_start(pdev, bar);
|
r->start = pci_resource_start(pdev, bar);
|
||||||
r->end = pci_resource_end(pdev, bar);
|
r->end = pci_resource_end(pdev, bar);
|
||||||
|
|
||||||
/* id is used for temporarily storing BAR; unset it now */
|
|
||||||
cs5535_mfd_cells[i].id = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells,
|
err = pci_request_region(pdev, PMS_BAR, DRV_NAME);
|
||||||
ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&pdev->dev, "MFD add devices failed: %d\n", err);
|
dev_err(&pdev->dev, "Failed to request PMS_BAR's IO region\n");
|
||||||
goto err_disable;
|
goto err_disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (machine_is_olpc())
|
err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, cs5535_mfd_cells,
|
||||||
mfd_clone_cell("cs5535-acpi", olpc_acpi_clones, ARRAY_SIZE(olpc_acpi_clones));
|
ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL);
|
||||||
|
if (err) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"Failed to add CS5535 sub-devices: %d\n", err);
|
||||||
|
goto err_release_pms;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (machine_is_olpc()) {
|
||||||
|
err = pci_request_region(pdev, ACPI_BAR, DRV_NAME);
|
||||||
|
if (err) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"Failed to request ACPI_BAR's IO region\n");
|
||||||
|
goto err_remove_devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
|
||||||
|
cs5535_olpc_mfd_cells,
|
||||||
|
ARRAY_SIZE(cs5535_olpc_mfd_cells),
|
||||||
|
NULL, 0, NULL);
|
||||||
|
if (err) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"Failed to add CS5535 OLPC sub-devices: %d\n",
|
||||||
|
err);
|
||||||
|
goto err_release_acpi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dev_info(&pdev->dev, "%zu devices registered.\n",
|
dev_info(&pdev->dev, "%zu devices registered.\n",
|
||||||
ARRAY_SIZE(cs5535_mfd_cells));
|
ARRAY_SIZE(cs5535_mfd_cells));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_release_acpi:
|
||||||
|
pci_release_region(pdev, ACPI_BAR);
|
||||||
|
err_remove_devices:
|
||||||
|
mfd_remove_devices(&pdev->dev);
|
||||||
|
err_release_pms:
|
||||||
|
pci_release_region(pdev, PMS_BAR);
|
||||||
err_disable:
|
err_disable:
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
return err;
|
return err;
|
||||||
|
@ -150,6 +135,11 @@ static int cs5535_mfd_probe(struct pci_dev *pdev,
|
||||||
static void cs5535_mfd_remove(struct pci_dev *pdev)
|
static void cs5535_mfd_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
mfd_remove_devices(&pdev->dev);
|
mfd_remove_devices(&pdev->dev);
|
||||||
|
|
||||||
|
if (machine_is_olpc())
|
||||||
|
pci_release_region(pdev, ACPI_BAR);
|
||||||
|
|
||||||
|
pci_release_region(pdev, PMS_BAR);
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
@ -668,6 +669,14 @@ struct prcmu_fw_version *prcmu_get_fw_version(void)
|
||||||
return fw_info.valid ? &fw_info.version : NULL;
|
return fw_info.valid ? &fw_info.version : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool prcmu_is_ulppll_disabled(void)
|
||||||
|
{
|
||||||
|
struct prcmu_fw_version *ver;
|
||||||
|
|
||||||
|
ver = prcmu_get_fw_version();
|
||||||
|
return ver && ver->project == PRCMU_FW_PROJECT_U8420_SYSCLK;
|
||||||
|
}
|
||||||
|
|
||||||
bool prcmu_has_arm_maxopp(void)
|
bool prcmu_has_arm_maxopp(void)
|
||||||
{
|
{
|
||||||
return (readb(tcdm_base + PRCM_AVS_VARM_MAX_OPP) &
|
return (readb(tcdm_base + PRCM_AVS_VARM_MAX_OPP) &
|
||||||
|
@ -1308,10 +1317,23 @@ static int request_sysclk(bool enable)
|
||||||
|
|
||||||
static int request_timclk(bool enable)
|
static int request_timclk(bool enable)
|
||||||
{
|
{
|
||||||
u32 val = (PRCM_TCR_DOZE_MODE | PRCM_TCR_TENSEL_MASK);
|
u32 val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On the U8420_CLKSEL firmware, the ULP (Ultra Low Power)
|
||||||
|
* PLL is disabled so we cannot use doze mode, this will
|
||||||
|
* stop the clock on this firmware.
|
||||||
|
*/
|
||||||
|
if (prcmu_is_ulppll_disabled())
|
||||||
|
val = 0;
|
||||||
|
else
|
||||||
|
val = (PRCM_TCR_DOZE_MODE | PRCM_TCR_TENSEL_MASK);
|
||||||
|
|
||||||
if (!enable)
|
if (!enable)
|
||||||
val |= PRCM_TCR_STOP_TIMERS;
|
val |= PRCM_TCR_STOP_TIMERS |
|
||||||
|
PRCM_TCR_DOZE_MODE |
|
||||||
|
PRCM_TCR_TENSEL_MASK;
|
||||||
|
|
||||||
writel(val, PRCM_TCR);
|
writel(val, PRCM_TCR);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1615,7 +1637,8 @@ unsigned long prcmu_clock_rate(u8 clock)
|
||||||
if (clock < PRCMU_NUM_REG_CLOCKS)
|
if (clock < PRCMU_NUM_REG_CLOCKS)
|
||||||
return clock_rate(clock);
|
return clock_rate(clock);
|
||||||
else if (clock == PRCMU_TIMCLK)
|
else if (clock == PRCMU_TIMCLK)
|
||||||
return ROOT_CLOCK_RATE / 16;
|
return prcmu_is_ulppll_disabled() ?
|
||||||
|
32768 : ROOT_CLOCK_RATE / 16;
|
||||||
else if (clock == PRCMU_SYSCLK)
|
else if (clock == PRCMU_SYSCLK)
|
||||||
return ROOT_CLOCK_RATE;
|
return ROOT_CLOCK_RATE;
|
||||||
else if (clock == PRCMU_PLLSOC0)
|
else if (clock == PRCMU_PLLSOC0)
|
||||||
|
@ -2646,6 +2669,8 @@ static char *fw_project_name(u32 project)
|
||||||
return "U8520 MBL";
|
return "U8520 MBL";
|
||||||
case PRCMU_FW_PROJECT_U8420:
|
case PRCMU_FW_PROJECT_U8420:
|
||||||
return "U8420";
|
return "U8420";
|
||||||
|
case PRCMU_FW_PROJECT_U8420_SYSCLK:
|
||||||
|
return "U8420-sysclk";
|
||||||
case PRCMU_FW_PROJECT_U9540:
|
case PRCMU_FW_PROJECT_U9540:
|
||||||
return "U9540";
|
return "U9540";
|
||||||
case PRCMU_FW_PROJECT_A9420:
|
case PRCMU_FW_PROJECT_A9420:
|
||||||
|
@ -2693,27 +2718,18 @@ static int db8500_irq_init(struct device_node *np)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dbx500_fw_version_init(struct platform_device *pdev,
|
static void dbx500_fw_version_init(struct device_node *np)
|
||||||
u32 version_offset)
|
|
||||||
{
|
{
|
||||||
struct resource *res;
|
|
||||||
void __iomem *tcpm_base;
|
void __iomem *tcpm_base;
|
||||||
u32 version;
|
u32 version;
|
||||||
|
|
||||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
tcpm_base = of_iomap(np, 1);
|
||||||
"prcmu-tcpm");
|
|
||||||
if (!res) {
|
|
||||||
dev_err(&pdev->dev,
|
|
||||||
"Error: no prcmu tcpm memory region provided\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tcpm_base = ioremap(res->start, resource_size(res));
|
|
||||||
if (!tcpm_base) {
|
if (!tcpm_base) {
|
||||||
dev_err(&pdev->dev, "no prcmu tcpm mem region provided\n");
|
pr_err("no prcmu tcpm mem region provided\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
version = readl(tcpm_base + version_offset);
|
version = readl(tcpm_base + DB8500_PRCMU_FW_VERSION_OFFSET);
|
||||||
fw_info.version.project = (version & 0xFF);
|
fw_info.version.project = (version & 0xFF);
|
||||||
fw_info.version.api_version = (version >> 8) & 0xFF;
|
fw_info.version.api_version = (version >> 8) & 0xFF;
|
||||||
fw_info.version.func_version = (version >> 16) & 0xFF;
|
fw_info.version.func_version = (version >> 16) & 0xFF;
|
||||||
|
@ -2731,7 +2747,7 @@ static void dbx500_fw_version_init(struct platform_device *pdev,
|
||||||
iounmap(tcpm_base);
|
iounmap(tcpm_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init db8500_prcmu_early_init(u32 phy_base, u32 size)
|
void __init db8500_prcmu_early_init(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This is a temporary remap to bring up the clocks. It is
|
* This is a temporary remap to bring up the clocks. It is
|
||||||
|
@ -2740,9 +2756,17 @@ void __init db8500_prcmu_early_init(u32 phy_base, u32 size)
|
||||||
* clock driver can probe independently. An early initcall will
|
* clock driver can probe independently. An early initcall will
|
||||||
* still be needed, but it can be diverted into drivers/clk/ux500.
|
* still be needed, but it can be diverted into drivers/clk/ux500.
|
||||||
*/
|
*/
|
||||||
prcmu_base = ioremap(phy_base, size);
|
struct device_node *np;
|
||||||
if (!prcmu_base)
|
|
||||||
|
np = of_find_compatible_node(NULL, NULL, "stericsson,db8500-prcmu");
|
||||||
|
prcmu_base = of_iomap(np, 0);
|
||||||
|
if (!prcmu_base) {
|
||||||
|
of_node_put(np);
|
||||||
pr_err("%s: ioremap() of prcmu registers failed!\n", __func__);
|
pr_err("%s: ioremap() of prcmu registers failed!\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dbx500_fw_version_init(np);
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
spin_lock_init(&mb0_transfer.lock);
|
spin_lock_init(&mb0_transfer.lock);
|
||||||
spin_lock_init(&mb0_transfer.dbb_irqs_lock);
|
spin_lock_init(&mb0_transfer.dbb_irqs_lock);
|
||||||
|
@ -3024,20 +3048,13 @@ static const struct mfd_cell common_prcmu_devs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mfd_cell db8500_prcmu_devs[] = {
|
static const struct mfd_cell db8500_prcmu_devs[] = {
|
||||||
{
|
OF_MFD_CELL("db8500-prcmu-regulators", NULL,
|
||||||
.name = "db8500-prcmu-regulators",
|
&db8500_regulators, sizeof(db8500_regulators), 0,
|
||||||
.of_compatible = "stericsson,db8500-prcmu-regulator",
|
"stericsson,db8500-prcmu-regulator"),
|
||||||
.platform_data = &db8500_regulators,
|
OF_MFD_CELL("cpuidle-dbx500",
|
||||||
.pdata_size = sizeof(db8500_regulators),
|
NULL, NULL, 0, 0, "stericsson,cpuidle-dbx500"),
|
||||||
},
|
OF_MFD_CELL("db8500-thermal",
|
||||||
{
|
NULL, NULL, 0, 0, "stericsson,db8500-thermal"),
|
||||||
.name = "cpuidle-dbx500",
|
|
||||||
.of_compatible = "stericsson,cpuidle-dbx500",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "db8500-thermal",
|
|
||||||
.of_compatible = "stericsson,db8500-thermal",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int db8500_prcmu_register_ab8500(struct device *parent)
|
static int db8500_prcmu_register_ab8500(struct device *parent)
|
||||||
|
@ -3091,7 +3108,6 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
init_prcm_registers();
|
init_prcm_registers();
|
||||||
dbx500_fw_version_init(pdev, DB8500_PRCMU_FW_VERSION_OFFSET);
|
|
||||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm");
|
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm");
|
||||||
if (!res) {
|
if (!res) {
|
||||||
dev_err(&pdev->dev, "no prcmu tcdm region provided\n");
|
dev_err(&pdev->dev, "no prcmu tcdm region provided\n");
|
||||||
|
|
|
@ -122,13 +122,25 @@ static const struct intel_lpss_platform_info apl_i2c_info = {
|
||||||
.properties = apl_i2c_properties,
|
.properties = apl_i2c_properties,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct property_entry glk_i2c_properties[] = {
|
||||||
|
PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 313),
|
||||||
|
PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
|
||||||
|
PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 290),
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct intel_lpss_platform_info glk_i2c_info = {
|
||||||
|
.clk_rate = 133000000,
|
||||||
|
.properties = glk_i2c_properties,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct intel_lpss_platform_info cnl_i2c_info = {
|
static const struct intel_lpss_platform_info cnl_i2c_info = {
|
||||||
.clk_rate = 216000000,
|
.clk_rate = 216000000,
|
||||||
.properties = spt_i2c_properties,
|
.properties = spt_i2c_properties,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pci_device_id intel_lpss_pci_ids[] = {
|
static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||||
/* CML */
|
/* CML-LP */
|
||||||
{ PCI_VDEVICE(INTEL, 0x02a8), (kernel_ulong_t)&spt_uart_info },
|
{ PCI_VDEVICE(INTEL, 0x02a8), (kernel_ulong_t)&spt_uart_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x02a9), (kernel_ulong_t)&spt_uart_info },
|
{ PCI_VDEVICE(INTEL, 0x02a9), (kernel_ulong_t)&spt_uart_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x02aa), (kernel_ulong_t)&spt_info },
|
{ PCI_VDEVICE(INTEL, 0x02aa), (kernel_ulong_t)&spt_info },
|
||||||
|
@ -141,6 +153,17 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||||
{ PCI_VDEVICE(INTEL, 0x02ea), (kernel_ulong_t)&cnl_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x02ea), (kernel_ulong_t)&cnl_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x02eb), (kernel_ulong_t)&cnl_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x02eb), (kernel_ulong_t)&cnl_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x02fb), (kernel_ulong_t)&spt_info },
|
{ PCI_VDEVICE(INTEL, 0x02fb), (kernel_ulong_t)&spt_info },
|
||||||
|
/* CML-H */
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06a8), (kernel_ulong_t)&spt_uart_info },
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06a9), (kernel_ulong_t)&spt_uart_info },
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06aa), (kernel_ulong_t)&spt_info },
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06ab), (kernel_ulong_t)&spt_info },
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06c7), (kernel_ulong_t)&spt_uart_info },
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06e8), (kernel_ulong_t)&cnl_i2c_info },
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06e9), (kernel_ulong_t)&cnl_i2c_info },
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06ea), (kernel_ulong_t)&cnl_i2c_info },
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06eb), (kernel_ulong_t)&cnl_i2c_info },
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x06fb), (kernel_ulong_t)&spt_info },
|
||||||
/* BXT A-Step */
|
/* BXT A-Step */
|
||||||
{ PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info },
|
||||||
|
@ -174,14 +197,14 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||||
{ PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info },
|
{ PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info },
|
{ PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info },
|
||||||
/* GLK */
|
/* GLK */
|
||||||
{ PCI_VDEVICE(INTEL, 0x31ac), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x31ac), (kernel_ulong_t)&glk_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31ae), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x31ae), (kernel_ulong_t)&glk_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31b0), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x31b0), (kernel_ulong_t)&glk_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31b2), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x31b2), (kernel_ulong_t)&glk_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31b4), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x31b4), (kernel_ulong_t)&glk_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31b6), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x31b6), (kernel_ulong_t)&glk_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31b8), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x31b8), (kernel_ulong_t)&glk_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31ba), (kernel_ulong_t)&bxt_i2c_info },
|
{ PCI_VDEVICE(INTEL, 0x31ba), (kernel_ulong_t)&glk_i2c_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31bc), (kernel_ulong_t)&bxt_uart_info },
|
{ PCI_VDEVICE(INTEL, 0x31bc), (kernel_ulong_t)&bxt_uart_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31be), (kernel_ulong_t)&bxt_uart_info },
|
{ PCI_VDEVICE(INTEL, 0x31be), (kernel_ulong_t)&bxt_uart_info },
|
||||||
{ PCI_VDEVICE(INTEL, 0x31c0), (kernel_ulong_t)&bxt_uart_info },
|
{ PCI_VDEVICE(INTEL, 0x31c0), (kernel_ulong_t)&bxt_uart_info },
|
||||||
|
|
|
@ -384,7 +384,7 @@ int intel_lpss_probe(struct device *dev,
|
||||||
if (!lpss)
|
if (!lpss)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
lpss->priv = devm_ioremap(dev, info->mem->start + LPSS_PRIV_OFFSET,
|
lpss->priv = devm_ioremap_uc(dev, info->mem->start + LPSS_PRIV_OFFSET,
|
||||||
LPSS_PRIV_SIZE);
|
LPSS_PRIV_SIZE);
|
||||||
if (!lpss->priv)
|
if (!lpss->priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -88,6 +88,9 @@ static struct mfd_cell crystal_cove_cht_dev[] = {
|
||||||
.num_resources = ARRAY_SIZE(gpio_resources),
|
.num_resources = ARRAY_SIZE(gpio_resources),
|
||||||
.resources = gpio_resources,
|
.resources = gpio_resources,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "cht_crystal_cove_pmic",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "crystal_cove_pwm",
|
.name = "crystal_cove_pwm",
|
||||||
},
|
},
|
||||||
|
|
|
@ -396,11 +396,7 @@ static int __init micro_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(micro->base))
|
if (IS_ERR(micro->base))
|
||||||
return PTR_ERR(micro->base);
|
return PTR_ERR(micro->base);
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
micro->sdlc = devm_platform_ioremap_resource(pdev, 1);
|
||||||
if (!res)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
micro->sdlc = devm_ioremap_resource(&pdev->dev, res);
|
|
||||||
if (IS_ERR(micro->sdlc))
|
if (IS_ERR(micro->sdlc))
|
||||||
return PTR_ERR(micro->sdlc);
|
return PTR_ERR(micro->sdlc);
|
||||||
|
|
||||||
|
|
|
@ -450,6 +450,21 @@ int madera_dev_init(struct madera *madera)
|
||||||
sizeof(madera->pdata));
|
sizeof(madera->pdata));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
madera->mclk[MADERA_MCLK1].id = "mclk1";
|
||||||
|
madera->mclk[MADERA_MCLK2].id = "mclk2";
|
||||||
|
madera->mclk[MADERA_MCLK3].id = "mclk3";
|
||||||
|
|
||||||
|
ret = devm_clk_bulk_get_optional(madera->dev, ARRAY_SIZE(madera->mclk),
|
||||||
|
madera->mclk);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(madera->dev, "Failed to get clocks: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not using devm_clk_get to prevent breakage of existing DTs */
|
||||||
|
if (!madera->mclk[MADERA_MCLK2].clk)
|
||||||
|
dev_warn(madera->dev, "Missing MCLK2, requires 32kHz clock\n");
|
||||||
|
|
||||||
ret = madera_get_reset_gpio(madera);
|
ret = madera_get_reset_gpio(madera);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -660,13 +675,19 @@ int madera_dev_init(struct madera *madera)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init 32k clock sourced from MCLK2 */
|
/* Init 32k clock sourced from MCLK2 */
|
||||||
|
ret = clk_prepare_enable(madera->mclk[MADERA_MCLK2].clk);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(madera->dev, "Failed to enable 32k clock: %d\n", ret);
|
||||||
|
goto err_reset;
|
||||||
|
}
|
||||||
|
|
||||||
ret = regmap_update_bits(madera->regmap,
|
ret = regmap_update_bits(madera->regmap,
|
||||||
MADERA_CLOCK_32K_1,
|
MADERA_CLOCK_32K_1,
|
||||||
MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK,
|
MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK,
|
||||||
MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2);
|
MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret);
|
dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret);
|
||||||
goto err_reset;
|
goto err_clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_runtime_set_active(madera->dev);
|
pm_runtime_set_active(madera->dev);
|
||||||
|
@ -687,6 +708,8 @@ int madera_dev_init(struct madera *madera)
|
||||||
|
|
||||||
err_pm_runtime:
|
err_pm_runtime:
|
||||||
pm_runtime_disable(madera->dev);
|
pm_runtime_disable(madera->dev);
|
||||||
|
err_clock:
|
||||||
|
clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
|
||||||
err_reset:
|
err_reset:
|
||||||
madera_enable_hard_reset(madera);
|
madera_enable_hard_reset(madera);
|
||||||
regulator_disable(madera->dcvdd);
|
regulator_disable(madera->dcvdd);
|
||||||
|
@ -713,6 +736,8 @@ int madera_dev_exit(struct madera *madera)
|
||||||
*/
|
*/
|
||||||
pm_runtime_disable(madera->dev);
|
pm_runtime_disable(madera->dev);
|
||||||
|
|
||||||
|
clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
|
||||||
|
|
||||||
regulator_disable(madera->dcvdd);
|
regulator_disable(madera->dcvdd);
|
||||||
regulator_put(madera->dcvdd);
|
regulator_put(madera->dcvdd);
|
||||||
|
|
||||||
|
|
|
@ -507,7 +507,6 @@ static int max77620_probe(struct i2c_client *client,
|
||||||
|
|
||||||
i2c_set_clientdata(client, chip);
|
i2c_set_clientdata(client, chip);
|
||||||
chip->dev = &client->dev;
|
chip->dev = &client->dev;
|
||||||
chip->irq_base = -1;
|
|
||||||
chip->chip_irq = client->irq;
|
chip->chip_irq = client->irq;
|
||||||
chip->chip_id = (enum max77620_chip_id)id->driver_data;
|
chip->chip_id = (enum max77620_chip_id)id->driver_data;
|
||||||
|
|
||||||
|
@ -545,8 +544,8 @@ static int max77620_probe(struct i2c_client *client,
|
||||||
|
|
||||||
max77620_top_irq_chip.irq_drv_data = chip;
|
max77620_top_irq_chip.irq_drv_data = chip;
|
||||||
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
|
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
|
||||||
IRQF_ONESHOT | IRQF_SHARED,
|
IRQF_ONESHOT | IRQF_SHARED, 0,
|
||||||
chip->irq_base, &max77620_top_irq_chip,
|
&max77620_top_irq_chip,
|
||||||
&chip->top_irq_data);
|
&chip->top_irq_data);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
|
dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
|
||||||
|
|
|
@ -26,55 +26,29 @@ static struct device_type mfd_dev_type = {
|
||||||
int mfd_cell_enable(struct platform_device *pdev)
|
int mfd_cell_enable(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
const struct mfd_cell *cell = mfd_get_cell(pdev);
|
const struct mfd_cell *cell = mfd_get_cell(pdev);
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
/* only call enable hook if the cell wasn't previously enabled */
|
if (!cell->enable) {
|
||||||
if (atomic_inc_return(cell->usage_count) == 1)
|
dev_dbg(&pdev->dev, "No .enable() call-back registered\n");
|
||||||
err = cell->enable(pdev);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* if the enable hook failed, decrement counter to allow retries */
|
return cell->enable(pdev);
|
||||||
if (err)
|
|
||||||
atomic_dec(cell->usage_count);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mfd_cell_enable);
|
EXPORT_SYMBOL(mfd_cell_enable);
|
||||||
|
|
||||||
int mfd_cell_disable(struct platform_device *pdev)
|
int mfd_cell_disable(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
const struct mfd_cell *cell = mfd_get_cell(pdev);
|
const struct mfd_cell *cell = mfd_get_cell(pdev);
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
/* only disable if no other clients are using it */
|
if (!cell->disable) {
|
||||||
if (atomic_dec_return(cell->usage_count) == 0)
|
dev_dbg(&pdev->dev, "No .disable() call-back registered\n");
|
||||||
err = cell->disable(pdev);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* if the disable hook failed, increment to allow retries */
|
return cell->disable(pdev);
|
||||||
if (err)
|
|
||||||
atomic_inc(cell->usage_count);
|
|
||||||
|
|
||||||
/* sanity check; did someone call disable too many times? */
|
|
||||||
WARN_ON(atomic_read(cell->usage_count) < 0);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mfd_cell_disable);
|
EXPORT_SYMBOL(mfd_cell_disable);
|
||||||
|
|
||||||
static int mfd_platform_add_cell(struct platform_device *pdev,
|
|
||||||
const struct mfd_cell *cell,
|
|
||||||
atomic_t *usage_count)
|
|
||||||
{
|
|
||||||
if (!cell)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pdev->mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL);
|
|
||||||
if (!pdev->mfd_cell)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
pdev->mfd_cell->usage_count = usage_count;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ACPI)
|
#if IS_ENABLED(CONFIG_ACPI)
|
||||||
static void mfd_acpi_add_device(const struct mfd_cell *cell,
|
static void mfd_acpi_add_device(const struct mfd_cell *cell,
|
||||||
struct platform_device *pdev)
|
struct platform_device *pdev)
|
||||||
|
@ -134,7 +108,7 @@ static inline void mfd_acpi_add_device(const struct mfd_cell *cell,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int mfd_add_device(struct device *parent, int id,
|
static int mfd_add_device(struct device *parent, int id,
|
||||||
const struct mfd_cell *cell, atomic_t *usage_count,
|
const struct mfd_cell *cell,
|
||||||
struct resource *mem_base,
|
struct resource *mem_base,
|
||||||
int irq_base, struct irq_domain *domain)
|
int irq_base, struct irq_domain *domain)
|
||||||
{
|
{
|
||||||
|
@ -154,6 +128,10 @@ static int mfd_add_device(struct device *parent, int id,
|
||||||
if (!pdev)
|
if (!pdev)
|
||||||
goto fail_alloc;
|
goto fail_alloc;
|
||||||
|
|
||||||
|
pdev->mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL);
|
||||||
|
if (!pdev->mfd_cell)
|
||||||
|
goto fail_device;
|
||||||
|
|
||||||
res = kcalloc(cell->num_resources, sizeof(*res), GFP_KERNEL);
|
res = kcalloc(cell->num_resources, sizeof(*res), GFP_KERNEL);
|
||||||
if (!res)
|
if (!res)
|
||||||
goto fail_device;
|
goto fail_device;
|
||||||
|
@ -174,6 +152,11 @@ static int mfd_add_device(struct device *parent, int id,
|
||||||
if (parent->of_node && cell->of_compatible) {
|
if (parent->of_node && cell->of_compatible) {
|
||||||
for_each_child_of_node(parent->of_node, np) {
|
for_each_child_of_node(parent->of_node, np) {
|
||||||
if (of_device_is_compatible(np, cell->of_compatible)) {
|
if (of_device_is_compatible(np, cell->of_compatible)) {
|
||||||
|
if (!of_device_is_available(np)) {
|
||||||
|
/* Ignore disabled devices error free */
|
||||||
|
ret = 0;
|
||||||
|
goto fail_alias;
|
||||||
|
}
|
||||||
pdev->dev.of_node = np;
|
pdev->dev.of_node = np;
|
||||||
pdev->dev.fwnode = &np->fwnode;
|
pdev->dev.fwnode = &np->fwnode;
|
||||||
break;
|
break;
|
||||||
|
@ -196,10 +179,6 @@ static int mfd_add_device(struct device *parent, int id,
|
||||||
goto fail_alias;
|
goto fail_alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mfd_platform_add_cell(pdev, cell, usage_count);
|
|
||||||
if (ret)
|
|
||||||
goto fail_alias;
|
|
||||||
|
|
||||||
for (r = 0; r < cell->num_resources; r++) {
|
for (r = 0; r < cell->num_resources; r++) {
|
||||||
res[r].name = cell->resources[r].name;
|
res[r].name = cell->resources[r].name;
|
||||||
res[r].flags = cell->resources[r].flags;
|
res[r].flags = cell->resources[r].flags;
|
||||||
|
@ -286,16 +265,9 @@ int mfd_add_devices(struct device *parent, int id,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
atomic_t *cnts;
|
|
||||||
|
|
||||||
/* initialize reference counting for all cells */
|
|
||||||
cnts = kcalloc(n_devs, sizeof(*cnts), GFP_KERNEL);
|
|
||||||
if (!cnts)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
for (i = 0; i < n_devs; i++) {
|
for (i = 0; i < n_devs; i++) {
|
||||||
atomic_set(&cnts[i], 0);
|
ret = mfd_add_device(parent, id, cells + i, mem_base,
|
||||||
ret = mfd_add_device(parent, id, cells + i, cnts + i, mem_base,
|
|
||||||
irq_base, domain);
|
irq_base, domain);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -306,17 +278,15 @@ int mfd_add_devices(struct device *parent, int id,
|
||||||
fail:
|
fail:
|
||||||
if (i)
|
if (i)
|
||||||
mfd_remove_devices(parent);
|
mfd_remove_devices(parent);
|
||||||
else
|
|
||||||
kfree(cnts);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mfd_add_devices);
|
EXPORT_SYMBOL(mfd_add_devices);
|
||||||
|
|
||||||
static int mfd_remove_devices_fn(struct device *dev, void *c)
|
static int mfd_remove_devices_fn(struct device *dev, void *data)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
const struct mfd_cell *cell;
|
const struct mfd_cell *cell;
|
||||||
atomic_t **usage_count = c;
|
|
||||||
|
|
||||||
if (dev->type != &mfd_dev_type)
|
if (dev->type != &mfd_dev_type)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -327,20 +297,13 @@ static int mfd_remove_devices_fn(struct device *dev, void *c)
|
||||||
regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
|
regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
|
||||||
cell->num_parent_supplies);
|
cell->num_parent_supplies);
|
||||||
|
|
||||||
/* find the base address of usage_count pointers (for freeing) */
|
|
||||||
if (!*usage_count || (cell->usage_count < *usage_count))
|
|
||||||
*usage_count = cell->usage_count;
|
|
||||||
|
|
||||||
platform_device_unregister(pdev);
|
platform_device_unregister(pdev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mfd_remove_devices(struct device *parent)
|
void mfd_remove_devices(struct device *parent)
|
||||||
{
|
{
|
||||||
atomic_t *cnts = NULL;
|
device_for_each_child_reverse(parent, NULL, mfd_remove_devices_fn);
|
||||||
|
|
||||||
device_for_each_child_reverse(parent, &cnts, mfd_remove_devices_fn);
|
|
||||||
kfree(cnts);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mfd_remove_devices);
|
EXPORT_SYMBOL(mfd_remove_devices);
|
||||||
|
|
||||||
|
@ -382,38 +345,5 @@ int devm_mfd_add_devices(struct device *dev, int id,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(devm_mfd_add_devices);
|
EXPORT_SYMBOL(devm_mfd_add_devices);
|
||||||
|
|
||||||
int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
|
|
||||||
{
|
|
||||||
struct mfd_cell cell_entry;
|
|
||||||
struct device *dev;
|
|
||||||
struct platform_device *pdev;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* fetch the parent cell's device (should already be registered!) */
|
|
||||||
dev = bus_find_device_by_name(&platform_bus_type, NULL, cell);
|
|
||||||
if (!dev) {
|
|
||||||
printk(KERN_ERR "failed to find device for cell %s\n", cell);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
pdev = to_platform_device(dev);
|
|
||||||
memcpy(&cell_entry, mfd_get_cell(pdev), sizeof(cell_entry));
|
|
||||||
|
|
||||||
WARN_ON(!cell_entry.enable);
|
|
||||||
|
|
||||||
for (i = 0; i < n_clones; i++) {
|
|
||||||
cell_entry.name = clones[i];
|
|
||||||
/* don't give up if a single call fails; just report error */
|
|
||||||
if (mfd_add_device(pdev->dev.parent, -1, &cell_entry,
|
|
||||||
cell_entry.usage_count, NULL, 0, NULL))
|
|
||||||
dev_err(dev, "failed to create platform device '%s'\n",
|
|
||||||
clones[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
put_device(dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(mfd_clone_cell);
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
|
MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
|
||||||
|
|
|
@ -189,16 +189,16 @@ static int mt6397_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
switch (pmic->chip_id) {
|
switch (pmic->chip_id) {
|
||||||
case MT6323_CHIP_ID:
|
case MT6323_CHIP_ID:
|
||||||
ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
|
ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
|
||||||
ARRAY_SIZE(mt6323_devs), NULL,
|
mt6323_devs, ARRAY_SIZE(mt6323_devs),
|
||||||
0, pmic->irq_domain);
|
NULL, 0, pmic->irq_domain);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MT6391_CHIP_ID:
|
case MT6391_CHIP_ID:
|
||||||
case MT6397_CHIP_ID:
|
case MT6397_CHIP_ID:
|
||||||
ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
|
ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
|
||||||
ARRAY_SIZE(mt6397_devs), NULL,
|
mt6397_devs, ARRAY_SIZE(mt6397_devs),
|
||||||
0, pmic->irq_domain);
|
NULL, 0, pmic->irq_domain);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#define PM8916_SUBTYPE 0x0b
|
#define PM8916_SUBTYPE 0x0b
|
||||||
#define PM8004_SUBTYPE 0x0c
|
#define PM8004_SUBTYPE 0x0c
|
||||||
#define PM8909_SUBTYPE 0x0d
|
#define PM8909_SUBTYPE 0x0d
|
||||||
|
#define PM8950_SUBTYPE 0x10
|
||||||
|
#define PMI8950_SUBTYPE 0x11
|
||||||
#define PM8998_SUBTYPE 0x14
|
#define PM8998_SUBTYPE 0x14
|
||||||
#define PMI8998_SUBTYPE 0x15
|
#define PMI8998_SUBTYPE 0x15
|
||||||
#define PM8005_SUBTYPE 0x18
|
#define PM8005_SUBTYPE 0x18
|
||||||
|
@ -50,6 +52,8 @@ static const struct of_device_id pmic_spmi_id_table[] = {
|
||||||
{ .compatible = "qcom,pm8916", .data = (void *)PM8916_SUBTYPE },
|
{ .compatible = "qcom,pm8916", .data = (void *)PM8916_SUBTYPE },
|
||||||
{ .compatible = "qcom,pm8004", .data = (void *)PM8004_SUBTYPE },
|
{ .compatible = "qcom,pm8004", .data = (void *)PM8004_SUBTYPE },
|
||||||
{ .compatible = "qcom,pm8909", .data = (void *)PM8909_SUBTYPE },
|
{ .compatible = "qcom,pm8909", .data = (void *)PM8909_SUBTYPE },
|
||||||
|
{ .compatible = "qcom,pm8950", .data = (void *)PM8950_SUBTYPE },
|
||||||
|
{ .compatible = "qcom,pmi8950", .data = (void *)PMI8950_SUBTYPE },
|
||||||
{ .compatible = "qcom,pm8998", .data = (void *)PM8998_SUBTYPE },
|
{ .compatible = "qcom,pm8998", .data = (void *)PM8998_SUBTYPE },
|
||||||
{ .compatible = "qcom,pmi8998", .data = (void *)PMI8998_SUBTYPE },
|
{ .compatible = "qcom,pmi8998", .data = (void *)PMI8998_SUBTYPE },
|
||||||
{ .compatible = "qcom,pm8005", .data = (void *)PM8005_SUBTYPE },
|
{ .compatible = "qcom,pm8005", .data = (void *)PM8005_SUBTYPE },
|
||||||
|
|
|
@ -109,11 +109,7 @@ static const struct regmap_config rk817_regmap_config = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource rtc_resources[] = {
|
static struct resource rtc_resources[] = {
|
||||||
{
|
DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
|
||||||
.start = RK808_IRQ_RTC_ALARM,
|
|
||||||
.end = RK808_IRQ_RTC_ALARM,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource rk817_rtc_resources[] = {
|
static struct resource rk817_rtc_resources[] = {
|
||||||
|
@ -121,16 +117,8 @@ static struct resource rk817_rtc_resources[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource rk805_key_resources[] = {
|
static struct resource rk805_key_resources[] = {
|
||||||
{
|
DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
|
||||||
.start = RK805_IRQ_PWRON_FALL,
|
DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
|
||||||
.end = RK805_IRQ_PWRON_FALL,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = RK805_IRQ_PWRON_RISE,
|
|
||||||
.end = RK805_IRQ_PWRON_RISE,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource rk817_pwrkey_resources[] = {
|
static struct resource rk817_pwrkey_resources[] = {
|
||||||
|
@ -167,7 +155,7 @@ static const struct mfd_cell rk817s[] = {
|
||||||
{ .name = "rk808-clkout",},
|
{ .name = "rk808-clkout",},
|
||||||
{ .name = "rk808-regulator",},
|
{ .name = "rk808-regulator",},
|
||||||
{
|
{
|
||||||
.name = "rk8xx-pwrkey",
|
.name = "rk805-pwrkey",
|
||||||
.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
|
.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
|
||||||
.resources = &rk817_pwrkey_resources[0],
|
.resources = &rk817_pwrkey_resources[0],
|
||||||
},
|
},
|
||||||
|
@ -215,7 +203,7 @@ static const struct rk808_reg_data rk808_pre_init_reg[] = {
|
||||||
|
|
||||||
static const struct rk808_reg_data rk817_pre_init_reg[] = {
|
static const struct rk808_reg_data rk817_pre_init_reg[] = {
|
||||||
{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
|
{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
|
||||||
{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_H},
|
{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L},
|
||||||
{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
|
{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
|
||||||
RK817_HOTDIE_105 | RK817_TSD_140},
|
RK817_HOTDIE_105 | RK817_TSD_140},
|
||||||
};
|
};
|
||||||
|
|
|
@ -105,15 +105,14 @@ static struct regmap_config bd70528_regmap = {
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* bit [0] - Shutdown register */
|
static unsigned int bit0_offsets[] = {0}; /* Shutdown */
|
||||||
unsigned int bit0_offsets[] = {0}; /* Shutdown register */
|
static unsigned int bit1_offsets[] = {1}; /* Power failure */
|
||||||
unsigned int bit1_offsets[] = {1}; /* Power failure register */
|
static unsigned int bit2_offsets[] = {2}; /* VR FAULT */
|
||||||
unsigned int bit2_offsets[] = {2}; /* VR FAULT register */
|
static unsigned int bit3_offsets[] = {3}; /* PMU interrupts */
|
||||||
unsigned int bit3_offsets[] = {3}; /* PMU register interrupts */
|
static unsigned int bit4_offsets[] = {4, 5}; /* Charger 1 and Charger 2 */
|
||||||
unsigned int bit4_offsets[] = {4, 5}; /* Charger 1 and Charger 2 registers */
|
static unsigned int bit5_offsets[] = {6}; /* RTC */
|
||||||
unsigned int bit5_offsets[] = {6}; /* RTC register */
|
static unsigned int bit6_offsets[] = {7}; /* GPIO */
|
||||||
unsigned int bit6_offsets[] = {7}; /* GPIO register */
|
static unsigned int bit7_offsets[] = {8}; /* Invalid operation */
|
||||||
unsigned int bit7_offsets[] = {8}; /* Invalid operation register */
|
|
||||||
|
|
||||||
static struct regmap_irq_sub_irq_map bd70528_sub_irq_offsets[] = {
|
static struct regmap_irq_sub_irq_map bd70528_sub_irq_offsets[] = {
|
||||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
|
REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
|
||||||
|
|
|
@ -105,7 +105,6 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk)
|
||||||
syscon_config.reg_stride = reg_io_width;
|
syscon_config.reg_stride = reg_io_width;
|
||||||
syscon_config.val_bits = reg_io_width * 8;
|
syscon_config.val_bits = reg_io_width * 8;
|
||||||
syscon_config.max_register = resource_size(&res) - reg_io_width;
|
syscon_config.max_register = resource_size(&res) - reg_io_width;
|
||||||
syscon_config.name = of_node_full_name(np);
|
|
||||||
|
|
||||||
regmap = regmap_init_mmio(NULL, base, &syscon_config);
|
regmap = regmap_init_mmio(NULL, base, &syscon_config);
|
||||||
if (IS_ERR(regmap)) {
|
if (IS_ERR(regmap)) {
|
||||||
|
|
|
@ -182,11 +182,11 @@ static int ti_tscadc_probe(struct platform_device *pdev)
|
||||||
tscadc->irq = err;
|
tscadc->irq = err;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
tscadc->tscadc_phys_base = res->start;
|
|
||||||
tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res);
|
tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (IS_ERR(tscadc->tscadc_base))
|
if (IS_ERR(tscadc->tscadc_base))
|
||||||
return PTR_ERR(tscadc->tscadc_base);
|
return PTR_ERR(tscadc->tscadc_base);
|
||||||
|
|
||||||
|
tscadc->tscadc_phys_base = res->start;
|
||||||
tscadc->regmap = devm_regmap_init_mmio(&pdev->dev,
|
tscadc->regmap = devm_regmap_init_mmio(&pdev->dev,
|
||||||
tscadc->tscadc_base, &tscadc_regmap_config);
|
tscadc->tscadc_base, &tscadc_regmap_config);
|
||||||
if (IS_ERR(tscadc->regmap)) {
|
if (IS_ERR(tscadc->regmap)) {
|
||||||
|
|
|
@ -806,12 +806,6 @@ static const struct reg_default wm8998_reg_default[] = {
|
||||||
{ 0x00000EF3, 0x0000 }, /* R3827 - ISRC 2 CTRL 1 */
|
{ 0x00000EF3, 0x0000 }, /* R3827 - ISRC 2 CTRL 1 */
|
||||||
{ 0x00000EF4, 0x0001 }, /* R3828 - ISRC 2 CTRL 2 */
|
{ 0x00000EF4, 0x0001 }, /* R3828 - ISRC 2 CTRL 2 */
|
||||||
{ 0x00000EF5, 0x0000 }, /* R3829 - ISRC 2 CTRL 3 */
|
{ 0x00000EF5, 0x0000 }, /* R3829 - ISRC 2 CTRL 3 */
|
||||||
{ 0x00001700, 0x0000 }, /* R5888 - FRF_COEFF_1 */
|
|
||||||
{ 0x00001701, 0x0000 }, /* R5889 - FRF_COEFF_2 */
|
|
||||||
{ 0x00001702, 0x0000 }, /* R5890 - FRF_COEFF_3 */
|
|
||||||
{ 0x00001703, 0x0000 }, /* R5891 - FRF_COEFF_4 */
|
|
||||||
{ 0x00001704, 0x0000 }, /* R5892 - DAC_COMP_1 */
|
|
||||||
{ 0x00001705, 0x0000 }, /* R5893 - DAC_COMP_2 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool wm8998_readable_register(struct device *dev, unsigned int reg)
|
static bool wm8998_readable_register(struct device *dev, unsigned int reg)
|
||||||
|
@ -1492,12 +1486,6 @@ static bool wm8998_readable_register(struct device *dev, unsigned int reg)
|
||||||
case ARIZONA_ISRC_2_CTRL_1:
|
case ARIZONA_ISRC_2_CTRL_1:
|
||||||
case ARIZONA_ISRC_2_CTRL_2:
|
case ARIZONA_ISRC_2_CTRL_2:
|
||||||
case ARIZONA_ISRC_2_CTRL_3:
|
case ARIZONA_ISRC_2_CTRL_3:
|
||||||
case ARIZONA_FRF_COEFF_1:
|
|
||||||
case ARIZONA_FRF_COEFF_2:
|
|
||||||
case ARIZONA_FRF_COEFF_3:
|
|
||||||
case ARIZONA_FRF_COEFF_4:
|
|
||||||
case ARIZONA_V2_DAC_COMP_1:
|
|
||||||
case ARIZONA_V2_DAC_COMP_2:
|
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -140,6 +140,16 @@ config POWER_RESET_LTC2952
|
||||||
This driver supports an external powerdown trigger and board power
|
This driver supports an external powerdown trigger and board power
|
||||||
down via the LTC2952. Bindings are made in the device tree.
|
down via the LTC2952. Bindings are made in the device tree.
|
||||||
|
|
||||||
|
config POWER_RESET_MT6323
|
||||||
|
bool "MediaTek MT6323 power-off driver"
|
||||||
|
depends on MFD_MT6397
|
||||||
|
help
|
||||||
|
The power-off driver is responsible for externally shutdown down
|
||||||
|
the power of a remote MediaTek SoC MT6323 is connected to through
|
||||||
|
controlling a tiny circuit BBPU inside MT6323 RTC.
|
||||||
|
|
||||||
|
Say Y if you have a board where MT6323 could be found.
|
||||||
|
|
||||||
config POWER_RESET_QNAP
|
config POWER_RESET_QNAP
|
||||||
bool "QNAP power-off driver"
|
bool "QNAP power-off driver"
|
||||||
depends on OF_GPIO && PLAT_ORION
|
depends on OF_GPIO && PLAT_ORION
|
||||||
|
|
|
@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
|
||||||
obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
|
obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
|
||||||
obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
|
obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
|
||||||
obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
|
obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
|
||||||
|
obj-$(CONFIG_POWER_RESET_MT6323) += mt6323-poweroff.o
|
||||||
obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o
|
obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o
|
||||||
obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o
|
obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o
|
||||||
obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
|
obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Power off through MediaTek PMIC
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 MediaTek Inc.
|
||||||
|
*
|
||||||
|
* Author: Sean Wang <sean.wang@mediatek.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/mfd/mt6397/core.h>
|
||||||
|
#include <linux/mfd/mt6397/rtc.h>
|
||||||
|
|
||||||
|
struct mt6323_pwrc {
|
||||||
|
struct device *dev;
|
||||||
|
struct regmap *regmap;
|
||||||
|
u32 base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mt6323_pwrc *mt_pwrc;
|
||||||
|
|
||||||
|
static void mt6323_do_pwroff(void)
|
||||||
|
{
|
||||||
|
struct mt6323_pwrc *pwrc = mt_pwrc;
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY);
|
||||||
|
regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR, 1);
|
||||||
|
|
||||||
|
ret = regmap_read_poll_timeout(pwrc->regmap,
|
||||||
|
pwrc->base + RTC_BBPU, val,
|
||||||
|
!(val & RTC_BBPU_CBUSY),
|
||||||
|
MTK_RTC_POLL_DELAY_US,
|
||||||
|
MTK_RTC_POLL_TIMEOUT);
|
||||||
|
if (ret)
|
||||||
|
dev_err(pwrc->dev, "failed to write BBPU: %d\n", ret);
|
||||||
|
|
||||||
|
/* Wait some time until system down, otherwise, notice with a warn */
|
||||||
|
mdelay(1000);
|
||||||
|
|
||||||
|
WARN_ONCE(1, "Unable to power off system\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt6323_pwrc_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
|
||||||
|
struct mt6323_pwrc *pwrc;
|
||||||
|
struct resource *res;
|
||||||
|
|
||||||
|
pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
|
||||||
|
if (!pwrc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
pwrc->base = res->start;
|
||||||
|
pwrc->regmap = mt6397_chip->regmap;
|
||||||
|
pwrc->dev = &pdev->dev;
|
||||||
|
mt_pwrc = pwrc;
|
||||||
|
|
||||||
|
pm_power_off = &mt6323_do_pwroff;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt6323_pwrc_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
if (pm_power_off == &mt6323_do_pwroff)
|
||||||
|
pm_power_off = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id mt6323_pwrc_dt_match[] = {
|
||||||
|
{ .compatible = "mediatek,mt6323-pwrc" },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match);
|
||||||
|
|
||||||
|
static struct platform_driver mt6323_pwrc_driver = {
|
||||||
|
.probe = mt6323_pwrc_probe,
|
||||||
|
.remove = mt6323_pwrc_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "mt6323-pwrc",
|
||||||
|
.of_match_table = mt6323_pwrc_dt_match,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module_platform_driver(mt6323_pwrc_driver);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("Poweroff driver for MT6323 PMIC");
|
||||||
|
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
|
@ -4,69 +4,19 @@
|
||||||
* Author: Tianping.Fang <tianping.fang@mediatek.com>
|
* Author: Tianping.Fang <tianping.fang@mediatek.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/mfd/mt6397/core.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/rtc.h>
|
#include <linux/rtc.h>
|
||||||
#include <linux/irqdomain.h>
|
#include <linux/mfd/mt6397/rtc.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/mod_devicetable.h>
|
||||||
#include <linux/of_address.h>
|
|
||||||
#include <linux/of_irq.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/mfd/mt6397/core.h>
|
|
||||||
|
|
||||||
#define RTC_BBPU 0x0000
|
|
||||||
#define RTC_BBPU_CBUSY BIT(6)
|
|
||||||
|
|
||||||
#define RTC_WRTGR 0x003c
|
|
||||||
|
|
||||||
#define RTC_IRQ_STA 0x0002
|
|
||||||
#define RTC_IRQ_STA_AL BIT(0)
|
|
||||||
#define RTC_IRQ_STA_LP BIT(3)
|
|
||||||
|
|
||||||
#define RTC_IRQ_EN 0x0004
|
|
||||||
#define RTC_IRQ_EN_AL BIT(0)
|
|
||||||
#define RTC_IRQ_EN_ONESHOT BIT(2)
|
|
||||||
#define RTC_IRQ_EN_LP BIT(3)
|
|
||||||
#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL)
|
|
||||||
|
|
||||||
#define RTC_AL_MASK 0x0008
|
|
||||||
#define RTC_AL_MASK_DOW BIT(4)
|
|
||||||
|
|
||||||
#define RTC_TC_SEC 0x000a
|
|
||||||
/* Min, Hour, Dom... register offset to RTC_TC_SEC */
|
|
||||||
#define RTC_OFFSET_SEC 0
|
|
||||||
#define RTC_OFFSET_MIN 1
|
|
||||||
#define RTC_OFFSET_HOUR 2
|
|
||||||
#define RTC_OFFSET_DOM 3
|
|
||||||
#define RTC_OFFSET_DOW 4
|
|
||||||
#define RTC_OFFSET_MTH 5
|
|
||||||
#define RTC_OFFSET_YEAR 6
|
|
||||||
#define RTC_OFFSET_COUNT 7
|
|
||||||
|
|
||||||
#define RTC_AL_SEC 0x0018
|
|
||||||
|
|
||||||
#define RTC_PDN2 0x002e
|
|
||||||
#define RTC_PDN2_PWRON_ALARM BIT(4)
|
|
||||||
|
|
||||||
#define RTC_MIN_YEAR 1968
|
|
||||||
#define RTC_BASE_YEAR 1900
|
|
||||||
#define RTC_NUM_YEARS 128
|
|
||||||
#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR)
|
|
||||||
|
|
||||||
struct mt6397_rtc {
|
|
||||||
struct device *dev;
|
|
||||||
struct rtc_device *rtc_dev;
|
|
||||||
struct mutex lock;
|
|
||||||
struct regmap *regmap;
|
|
||||||
int irq;
|
|
||||||
u32 addr_base;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
|
static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
|
||||||
{
|
{
|
||||||
unsigned long timeout = jiffies + HZ;
|
|
||||||
int ret;
|
int ret;
|
||||||
u32 data;
|
u32 data;
|
||||||
|
|
||||||
|
@ -74,19 +24,13 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
while (1) {
|
ret = regmap_read_poll_timeout(rtc->regmap,
|
||||||
ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU,
|
rtc->addr_base + RTC_BBPU, data,
|
||||||
&data);
|
!(data & RTC_BBPU_CBUSY),
|
||||||
|
MTK_RTC_POLL_DELAY_US,
|
||||||
|
MTK_RTC_POLL_TIMEOUT);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret);
|
||||||
if (!(data & RTC_BBPU_CBUSY))
|
|
||||||
break;
|
|
||||||
if (time_after(jiffies, timeout)) {
|
|
||||||
ret = -ETIMEDOUT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cpu_relax();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -319,19 +263,19 @@ static int mtk_rtc_probe(struct platform_device *pdev)
|
||||||
return rtc->irq;
|
return rtc->irq;
|
||||||
|
|
||||||
rtc->regmap = mt6397_chip->regmap;
|
rtc->regmap = mt6397_chip->regmap;
|
||||||
rtc->dev = &pdev->dev;
|
|
||||||
mutex_init(&rtc->lock);
|
mutex_init(&rtc->lock);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, rtc);
|
platform_set_drvdata(pdev, rtc);
|
||||||
|
|
||||||
rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev);
|
rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
|
||||||
if (IS_ERR(rtc->rtc_dev))
|
if (IS_ERR(rtc->rtc_dev))
|
||||||
return PTR_ERR(rtc->rtc_dev);
|
return PTR_ERR(rtc->rtc_dev);
|
||||||
|
|
||||||
ret = request_threaded_irq(rtc->irq, NULL,
|
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
|
||||||
mtk_rtc_irq_handler_thread,
|
mtk_rtc_irq_handler_thread,
|
||||||
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
|
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
|
||||||
"mt6397-rtc", rtc);
|
"mt6397-rtc", rtc);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
|
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
|
||||||
rtc->irq, ret);
|
rtc->irq, ret);
|
||||||
|
@ -353,15 +297,6 @@ static int mtk_rtc_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mtk_rtc_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct mt6397_rtc *rtc = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
free_irq(rtc->irq, rtc);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
static int mt6397_rtc_suspend(struct device *dev)
|
static int mt6397_rtc_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -388,6 +323,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
|
||||||
mt6397_rtc_resume);
|
mt6397_rtc_resume);
|
||||||
|
|
||||||
static const struct of_device_id mt6397_rtc_of_match[] = {
|
static const struct of_device_id mt6397_rtc_of_match[] = {
|
||||||
|
{ .compatible = "mediatek,mt6323-rtc", },
|
||||||
{ .compatible = "mediatek,mt6397-rtc", },
|
{ .compatible = "mediatek,mt6397-rtc", },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
@ -400,7 +336,6 @@ static struct platform_driver mtk_rtc_driver = {
|
||||||
.pm = &mt6397_pm_ops,
|
.pm = &mt6397_pm_ops,
|
||||||
},
|
},
|
||||||
.probe = mtk_rtc_probe,
|
.probe = mtk_rtc_probe,
|
||||||
.remove = mtk_rtc_remove,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module_platform_driver(mtk_rtc_driver);
|
module_platform_driver(mtk_rtc_driver);
|
||||||
|
|
|
@ -64,6 +64,8 @@ static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr)
|
||||||
|
|
||||||
void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
|
void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
|
||||||
resource_size_t size);
|
resource_size_t size);
|
||||||
|
void __iomem *devm_ioremap_uc(struct device *dev, resource_size_t offset,
|
||||||
|
resource_size_t size);
|
||||||
void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
|
void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
|
||||||
resource_size_t size);
|
resource_size_t size);
|
||||||
void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
|
void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
|
||||||
|
|
|
@ -1186,13 +1186,6 @@
|
||||||
#define ARIZONA_DSP4_SCRATCH_1 0x1441
|
#define ARIZONA_DSP4_SCRATCH_1 0x1441
|
||||||
#define ARIZONA_DSP4_SCRATCH_2 0x1442
|
#define ARIZONA_DSP4_SCRATCH_2 0x1442
|
||||||
#define ARIZONA_DSP4_SCRATCH_3 0x1443
|
#define ARIZONA_DSP4_SCRATCH_3 0x1443
|
||||||
#define ARIZONA_FRF_COEFF_1 0x1700
|
|
||||||
#define ARIZONA_FRF_COEFF_2 0x1701
|
|
||||||
#define ARIZONA_FRF_COEFF_3 0x1702
|
|
||||||
#define ARIZONA_FRF_COEFF_4 0x1703
|
|
||||||
#define ARIZONA_V2_DAC_COMP_1 0x1704
|
|
||||||
#define ARIZONA_V2_DAC_COMP_2 0x1705
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Field Definitions.
|
* Field Definitions.
|
||||||
|
|
|
@ -12,6 +12,35 @@
|
||||||
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
#define MFD_RES_SIZE(arr) (sizeof(arr) / sizeof(struct resource))
|
||||||
|
|
||||||
|
#define MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, _match)\
|
||||||
|
{ \
|
||||||
|
.name = (_name), \
|
||||||
|
.resources = (_res), \
|
||||||
|
.num_resources = MFD_RES_SIZE((_res)), \
|
||||||
|
.platform_data = (_pdata), \
|
||||||
|
.pdata_size = (_pdsize), \
|
||||||
|
.of_compatible = (_compat), \
|
||||||
|
.acpi_match = (_match), \
|
||||||
|
.id = (_id), \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OF_MFD_CELL(_name, _res, _pdata, _pdsize,_id, _compat) \
|
||||||
|
MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, NULL) \
|
||||||
|
|
||||||
|
#define ACPI_MFD_CELL(_name, _res, _pdata, _pdsize, _id, _match) \
|
||||||
|
MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, _match) \
|
||||||
|
|
||||||
|
#define MFD_CELL_BASIC(_name, _res, _pdata, _pdsize, _id) \
|
||||||
|
MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, NULL) \
|
||||||
|
|
||||||
|
#define MFD_CELL_RES(_name, _res) \
|
||||||
|
MFD_CELL_ALL(_name, _res, NULL, 0, 0, NULL, NULL) \
|
||||||
|
|
||||||
|
#define MFD_CELL_NAME(_name) \
|
||||||
|
MFD_CELL_ALL(_name, NULL, NULL, 0, 0, NULL, NULL) \
|
||||||
|
|
||||||
struct irq_domain;
|
struct irq_domain;
|
||||||
struct property_entry;
|
struct property_entry;
|
||||||
|
|
||||||
|
@ -30,8 +59,6 @@ struct mfd_cell {
|
||||||
const char *name;
|
const char *name;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
/* refcounting for multiple drivers to use a single cell */
|
|
||||||
atomic_t *usage_count;
|
|
||||||
int (*enable)(struct platform_device *dev);
|
int (*enable)(struct platform_device *dev);
|
||||||
int (*disable)(struct platform_device *dev);
|
int (*disable)(struct platform_device *dev);
|
||||||
|
|
||||||
|
@ -86,24 +113,6 @@ struct mfd_cell {
|
||||||
extern int mfd_cell_enable(struct platform_device *pdev);
|
extern int mfd_cell_enable(struct platform_device *pdev);
|
||||||
extern int mfd_cell_disable(struct platform_device *pdev);
|
extern int mfd_cell_disable(struct platform_device *pdev);
|
||||||
|
|
||||||
/*
|
|
||||||
* "Clone" multiple platform devices for a single cell. This is to be used
|
|
||||||
* for devices that have multiple users of a cell. For example, if an mfd
|
|
||||||
* driver wants the cell "foo" to be used by a GPIO driver, an MTD driver,
|
|
||||||
* and a platform driver, the following bit of code would be use after first
|
|
||||||
* calling mfd_add_devices():
|
|
||||||
*
|
|
||||||
* const char *fclones[] = { "foo-gpio", "foo-mtd" };
|
|
||||||
* err = mfd_clone_cells("foo", fclones, ARRAY_SIZE(fclones));
|
|
||||||
*
|
|
||||||
* Each driver (MTD, GPIO, and platform driver) would then register
|
|
||||||
* platform_drivers for "foo-mtd", "foo-gpio", and "foo", respectively.
|
|
||||||
* The cell's .enable/.disable hooks should be used to deal with hardware
|
|
||||||
* resource contention.
|
|
||||||
*/
|
|
||||||
extern int mfd_clone_cell(const char *cell, const char **clones,
|
|
||||||
size_t n_clones);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a platform device that's been created by mfd_add_devices(), fetch
|
* Given a platform device that's been created by mfd_add_devices(), fetch
|
||||||
* the mfd_cell that created it.
|
* the mfd_cell that created it.
|
||||||
|
|
|
@ -489,7 +489,7 @@ struct prcmu_auto_pm_config {
|
||||||
|
|
||||||
#ifdef CONFIG_MFD_DB8500_PRCMU
|
#ifdef CONFIG_MFD_DB8500_PRCMU
|
||||||
|
|
||||||
void db8500_prcmu_early_init(u32 phy_base, u32 size);
|
void db8500_prcmu_early_init(void);
|
||||||
int prcmu_set_rc_a2p(enum romcode_write);
|
int prcmu_set_rc_a2p(enum romcode_write);
|
||||||
enum romcode_read prcmu_get_rc_p2a(void);
|
enum romcode_read prcmu_get_rc_p2a(void);
|
||||||
enum ap_pwrst prcmu_get_xp70_current_state(void);
|
enum ap_pwrst prcmu_get_xp70_current_state(void);
|
||||||
|
@ -546,7 +546,7 @@ void db8500_prcmu_write_masked(unsigned int reg, u32 mask, u32 value);
|
||||||
|
|
||||||
#else /* !CONFIG_MFD_DB8500_PRCMU */
|
#else /* !CONFIG_MFD_DB8500_PRCMU */
|
||||||
|
|
||||||
static inline void db8500_prcmu_early_init(u32 phy_base, u32 size) {}
|
static inline void db8500_prcmu_early_init(void) {}
|
||||||
|
|
||||||
static inline int prcmu_set_rc_a2p(enum romcode_write code)
|
static inline int prcmu_set_rc_a2p(enum romcode_write code)
|
||||||
{
|
{
|
||||||
|
|
|
@ -190,6 +190,7 @@ enum ddr_pwrst {
|
||||||
#define PRCMU_FW_PROJECT_U8500_MBL2 12 /* Customer specific */
|
#define PRCMU_FW_PROJECT_U8500_MBL2 12 /* Customer specific */
|
||||||
#define PRCMU_FW_PROJECT_U8520 13
|
#define PRCMU_FW_PROJECT_U8520 13
|
||||||
#define PRCMU_FW_PROJECT_U8420 14
|
#define PRCMU_FW_PROJECT_U8420 14
|
||||||
|
#define PRCMU_FW_PROJECT_U8420_SYSCLK 17
|
||||||
#define PRCMU_FW_PROJECT_A9420 20
|
#define PRCMU_FW_PROJECT_A9420 20
|
||||||
/* [32..63] 9540 and derivatives */
|
/* [32..63] 9540 and derivatives */
|
||||||
#define PRCMU_FW_PROJECT_U9540 32
|
#define PRCMU_FW_PROJECT_U9540 32
|
||||||
|
@ -211,9 +212,9 @@ struct prcmu_fw_version {
|
||||||
|
|
||||||
#if defined(CONFIG_UX500_SOC_DB8500)
|
#if defined(CONFIG_UX500_SOC_DB8500)
|
||||||
|
|
||||||
static inline void prcmu_early_init(u32 phy_base, u32 size)
|
static inline void prcmu_early_init(void)
|
||||||
{
|
{
|
||||||
return db8500_prcmu_early_init(phy_base, size);
|
return db8500_prcmu_early_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
||||||
|
@ -401,7 +402,7 @@ static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline void prcmu_early_init(u32 phy_base, u32 size) {}
|
static inline void prcmu_early_init(void) {}
|
||||||
|
|
||||||
static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
||||||
bool keep_ap_pll)
|
bool keep_ap_pll)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#ifndef MADERA_CORE_H
|
#ifndef MADERA_CORE_H
|
||||||
#define MADERA_CORE_H
|
#define MADERA_CORE_H
|
||||||
|
|
||||||
|
#include <linux/clk.h>
|
||||||
#include <linux/gpio/consumer.h>
|
#include <linux/gpio/consumer.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/mfd/madera/pdata.h>
|
#include <linux/mfd/madera/pdata.h>
|
||||||
|
@ -29,6 +30,13 @@ enum madera_type {
|
||||||
CS42L92 = 9,
|
CS42L92 = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MADERA_MCLK1,
|
||||||
|
MADERA_MCLK2,
|
||||||
|
MADERA_MCLK3,
|
||||||
|
MADERA_NUM_MCLK
|
||||||
|
};
|
||||||
|
|
||||||
#define MADERA_MAX_CORE_SUPPLIES 2
|
#define MADERA_MAX_CORE_SUPPLIES 2
|
||||||
#define MADERA_MAX_GPIOS 40
|
#define MADERA_MAX_GPIOS 40
|
||||||
|
|
||||||
|
@ -155,6 +163,7 @@ struct snd_soc_dapm_context;
|
||||||
* @irq_dev: the irqchip child driver device
|
* @irq_dev: the irqchip child driver device
|
||||||
* @irq_data: pointer to irqchip data for the child irqchip driver
|
* @irq_data: pointer to irqchip data for the child irqchip driver
|
||||||
* @irq: host irq number from SPI or I2C configuration
|
* @irq: host irq number from SPI or I2C configuration
|
||||||
|
* @mclk: Structure holding clock supplies
|
||||||
* @out_clamp: indicates output clamp state for each analogue output
|
* @out_clamp: indicates output clamp state for each analogue output
|
||||||
* @out_shorted: indicates short circuit state for each analogue output
|
* @out_shorted: indicates short circuit state for each analogue output
|
||||||
* @hp_ena: bitflags of enable state for the headphone outputs
|
* @hp_ena: bitflags of enable state for the headphone outputs
|
||||||
|
@ -184,6 +193,8 @@ struct madera {
|
||||||
struct regmap_irq_chip_data *irq_data;
|
struct regmap_irq_chip_data *irq_data;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
|
struct clk_bulk_data mclk[MADERA_NUM_MCLK];
|
||||||
|
|
||||||
unsigned int num_micbias;
|
unsigned int num_micbias;
|
||||||
unsigned int num_childbias[MADERA_MAX_MICBIAS];
|
unsigned int num_childbias[MADERA_MAX_MICBIAS];
|
||||||
|
|
||||||
|
|
|
@ -329,7 +329,6 @@ struct max77620_chip {
|
||||||
struct regmap *rmap;
|
struct regmap *rmap;
|
||||||
|
|
||||||
int chip_irq;
|
int chip_irq;
|
||||||
int irq_base;
|
|
||||||
|
|
||||||
/* chip id */
|
/* chip id */
|
||||||
enum max77620_chip_id chip_id;
|
enum max77620_chip_id chip_id;
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014-2019 MediaTek Inc.
|
||||||
|
*
|
||||||
|
* Author: Tianping.Fang <tianping.fang@mediatek.com>
|
||||||
|
* Sean Wang <sean.wang@mediatek.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LINUX_MFD_MT6397_RTC_H_
|
||||||
|
#define _LINUX_MFD_MT6397_RTC_H_
|
||||||
|
|
||||||
|
#include <linux/jiffies.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
|
|
||||||
|
#define RTC_BBPU 0x0000
|
||||||
|
#define RTC_BBPU_CBUSY BIT(6)
|
||||||
|
#define RTC_BBPU_KEY (0x43 << 8)
|
||||||
|
|
||||||
|
#define RTC_WRTGR 0x003c
|
||||||
|
|
||||||
|
#define RTC_IRQ_STA 0x0002
|
||||||
|
#define RTC_IRQ_STA_AL BIT(0)
|
||||||
|
#define RTC_IRQ_STA_LP BIT(3)
|
||||||
|
|
||||||
|
#define RTC_IRQ_EN 0x0004
|
||||||
|
#define RTC_IRQ_EN_AL BIT(0)
|
||||||
|
#define RTC_IRQ_EN_ONESHOT BIT(2)
|
||||||
|
#define RTC_IRQ_EN_LP BIT(3)
|
||||||
|
#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL)
|
||||||
|
|
||||||
|
#define RTC_AL_MASK 0x0008
|
||||||
|
#define RTC_AL_MASK_DOW BIT(4)
|
||||||
|
|
||||||
|
#define RTC_TC_SEC 0x000a
|
||||||
|
/* Min, Hour, Dom... register offset to RTC_TC_SEC */
|
||||||
|
#define RTC_OFFSET_SEC 0
|
||||||
|
#define RTC_OFFSET_MIN 1
|
||||||
|
#define RTC_OFFSET_HOUR 2
|
||||||
|
#define RTC_OFFSET_DOM 3
|
||||||
|
#define RTC_OFFSET_DOW 4
|
||||||
|
#define RTC_OFFSET_MTH 5
|
||||||
|
#define RTC_OFFSET_YEAR 6
|
||||||
|
#define RTC_OFFSET_COUNT 7
|
||||||
|
|
||||||
|
#define RTC_AL_SEC 0x0018
|
||||||
|
|
||||||
|
#define RTC_PDN2 0x002e
|
||||||
|
#define RTC_PDN2_PWRON_ALARM BIT(4)
|
||||||
|
|
||||||
|
#define RTC_MIN_YEAR 1968
|
||||||
|
#define RTC_BASE_YEAR 1900
|
||||||
|
#define RTC_NUM_YEARS 128
|
||||||
|
#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR)
|
||||||
|
|
||||||
|
#define MTK_RTC_POLL_DELAY_US 10
|
||||||
|
#define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ))
|
||||||
|
|
||||||
|
struct mt6397_rtc {
|
||||||
|
struct device *dev;
|
||||||
|
struct rtc_device *rtc_dev;
|
||||||
|
|
||||||
|
/* Protect register access from multiple tasks */
|
||||||
|
struct mutex lock;
|
||||||
|
struct regmap *regmap;
|
||||||
|
int irq;
|
||||||
|
u32 addr_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _LINUX_MFD_MT6397_RTC_H_ */
|
|
@ -610,7 +610,7 @@ enum {
|
||||||
RK808_ID = 0x0000,
|
RK808_ID = 0x0000,
|
||||||
RK809_ID = 0x8090,
|
RK809_ID = 0x8090,
|
||||||
RK817_ID = 0x8170,
|
RK817_ID = 0x8170,
|
||||||
RK818_ID = 0x8181,
|
RK818_ID = 0x8180,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rk808 {
|
struct rk808 {
|
||||||
|
|
|
@ -181,14 +181,18 @@ static inline int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int twl_i2c_write_u16(u8 mod_no, u16 val, u8 reg) {
|
static inline int twl_i2c_write_u16(u8 mod_no, u16 val, u8 reg) {
|
||||||
val = cpu_to_le16(val);
|
__le16 value;
|
||||||
return twl_i2c_write(mod_no, (u8*) &val, reg, 2);
|
|
||||||
|
value = cpu_to_le16(val);
|
||||||
|
return twl_i2c_write(mod_no, (u8 *) &value, reg, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int twl_i2c_read_u16(u8 mod_no, u16 *val, u8 reg) {
|
static inline int twl_i2c_read_u16(u8 mod_no, u16 *val, u8 reg) {
|
||||||
int ret;
|
int ret;
|
||||||
ret = twl_i2c_read(mod_no, (u8*) val, reg, 2);
|
__le16 value;
|
||||||
*val = le16_to_cpu(*val);
|
|
||||||
|
ret = twl_i2c_read(mod_no, (u8 *) &value, reg, 2);
|
||||||
|
*val = le16_to_cpu(value);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
lib/devres.c
19
lib/devres.c
|
@ -9,6 +9,7 @@
|
||||||
enum devm_ioremap_type {
|
enum devm_ioremap_type {
|
||||||
DEVM_IOREMAP = 0,
|
DEVM_IOREMAP = 0,
|
||||||
DEVM_IOREMAP_NC,
|
DEVM_IOREMAP_NC,
|
||||||
|
DEVM_IOREMAP_UC,
|
||||||
DEVM_IOREMAP_WC,
|
DEVM_IOREMAP_WC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,6 +40,9 @@ static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
|
||||||
case DEVM_IOREMAP_NC:
|
case DEVM_IOREMAP_NC:
|
||||||
addr = ioremap_nocache(offset, size);
|
addr = ioremap_nocache(offset, size);
|
||||||
break;
|
break;
|
||||||
|
case DEVM_IOREMAP_UC:
|
||||||
|
addr = ioremap_uc(offset, size);
|
||||||
|
break;
|
||||||
case DEVM_IOREMAP_WC:
|
case DEVM_IOREMAP_WC:
|
||||||
addr = ioremap_wc(offset, size);
|
addr = ioremap_wc(offset, size);
|
||||||
break;
|
break;
|
||||||
|
@ -68,6 +72,21 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(devm_ioremap);
|
EXPORT_SYMBOL(devm_ioremap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_ioremap_uc - Managed ioremap_uc()
|
||||||
|
* @dev: Generic device to remap IO address for
|
||||||
|
* @offset: Resource address to map
|
||||||
|
* @size: Size of map
|
||||||
|
*
|
||||||
|
* Managed ioremap_uc(). Map is automatically unmapped on driver detach.
|
||||||
|
*/
|
||||||
|
void __iomem *devm_ioremap_uc(struct device *dev, resource_size_t offset,
|
||||||
|
resource_size_t size)
|
||||||
|
{
|
||||||
|
return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_UC);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_ioremap_uc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devm_ioremap_nocache - Managed ioremap_nocache()
|
* devm_ioremap_nocache - Managed ioremap_nocache()
|
||||||
* @dev: Generic device to remap IO address for
|
* @dev: Generic device to remap IO address for
|
||||||
|
|
Loading…
Reference in New Issue