diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt index 8f2e2822238df0769615eff3df8a5ce052d2dc35..b37bdde5cfda3e959887fe5ed434a7a4697a7bdf 100644 --- a/Documentation/devicetree/bindings/mfd/arizona.txt +++ b/Documentation/devicetree/bindings/mfd/arizona.txt @@ -30,7 +30,8 @@ Required properties: - gpio-controller : Indicates this device is a GPIO controller. - #gpio-cells : Must be 2. The first cell is the pin number and the - second cell is used to specify optional parameters (currently unused). + second cell is used to specify optional parameters, see ../gpio/gpio.txt + for details. - AVDD-supply, DBVDD1-supply, CPVDD-supply : Power supplies for the device, as covered in Documentation/devicetree/bindings/regulator/regulator.txt diff --git a/Documentation/devicetree/bindings/mfd/lp87565.txt b/Documentation/devicetree/bindings/mfd/lp87565.txt new file mode 100644 index 0000000000000000000000000000000000000000..a48df7c08ab087d7873306e319b7e2384a439fbe --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/lp87565.txt @@ -0,0 +1,43 @@ +TI LP87565 PMIC MFD driver + +Required properties: + - compatible: "ti,lp87565", "ti,lp87565-q1" + - reg: I2C slave address. + - gpio-controller: Marks the device node as a GPIO Controller. + - #gpio-cells: Should be two. The first cell is the pin number and + the second cell is used to specify flags. + See ../gpio/gpio.txt for more information. + - xxx-in-supply: Phandle to parent supply node of each regulator + populated under regulators node. xxx should match + the supply_name populated in driver. +Example: + +lp87565_pmic: pmic@60 { + compatible = "ti,lp87565-q1"; + reg = <0x60>; + gpio-controller; + #gpio-cells = <2>; + + buck10-in-supply = <&vsys_3v3>; + buck23-in-supply = <&vsys_3v3>; + + regulators: regulators { + buck10_reg: buck10 { + /* VDD_MPU */ + regulator-name = "buck10"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + buck23_reg: buck23 { + /* VDD_GPU */ + regulator-name = "buck23"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-boot-on; + regulator-always-on; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 708ff2504260c12b88ac7b749ea0badb3322d8e0..52cfd5f97b6b6d505f6411fb89dbac8d704dd738 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -29,6 +29,7 @@ andestech Andes Technology Corporation apm Applied Micro Circuits Corporation (APM) aptina Aptina Imaging arasan Arasan Chip Systems +arctic Arctic Sand aries Aries Embedded GmbH arm ARM Ltd. armadeus ARMadeus Systems SARL diff --git a/MAINTAINERS b/MAINTAINERS index cb79977dd0496bfb36d19e55fc049253e8f13066..a9795896323e88b55e301b5dfcffab44e5b80fda 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4048,7 +4048,10 @@ W: http://www.dialog-semiconductor.com/products S: Supported F: Documentation/hwmon/da90?? F: Documentation/devicetree/bindings/mfd/da90*.txt +F: Documentation/devicetree/bindings/input/da90??-onkey.txt +F: Documentation/devicetree/bindings/thermal/da90??-thermal.txt F: Documentation/devicetree/bindings/regulator/da92*.txt +F: Documentation/devicetree/bindings/watchdog/da92??-wdt.txt F: Documentation/devicetree/bindings/sound/da[79]*.txt F: drivers/gpio/gpio-da90??.c F: drivers/hwmon/da90??-hwmon.c @@ -4063,6 +4066,7 @@ F: drivers/power/supply/da9052-battery.c F: drivers/power/supply/da91??-*.c F: drivers/regulator/da903x.c F: drivers/regulator/da9???-regulator.[ch] +F: drivers/thermal/da90??-thermal.c F: drivers/rtc/rtc-da90??.c F: drivers/video/backlight/da90??_bl.c F: drivers/watchdog/da90??_wdt.c diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index 37c103e50ebfaa70078e3f74b1c801fe5ed8d526..85341eab795d1b5078d46e0e942d1deda33ef758 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -428,7 +428,7 @@ static int wcove_gpio_probe(struct platform_device *pdev) if (!wg) return -ENOMEM; - wg->regmap_irq_chip = pmic->irq_chip_data_level2; + wg->regmap_irq_chip = pmic->irq_chip_data; platform_set_drvdata(pdev, wg); @@ -476,6 +476,18 @@ static int wcove_gpio_probe(struct platform_device *pdev) gpiochip_set_nested_irqchip(&wg->chip, &wcove_irqchip, virq); + /* Enable GPIO0 interrupts */ + ret = regmap_update_bits(wg->regmap, IRQ_MASK_BASE, GPIO_IRQ0_MASK, + 0x00); + if (ret) + return ret; + + /* Enable GPIO1 interrupts */ + ret = regmap_update_bits(wg->regmap, IRQ_MASK_BASE + 1, GPIO_IRQ1_MASK, + 0x00); + if (ret) + return ret; + return 0; } diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 3eb5c93595f66f0311b73faf65b9c4716044ecff..94ad2c1c3d9055df0b245e58db6dc4c9e9d9c2b2 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -160,6 +160,11 @@ config MFD_AXP20X_I2C components like regulators or the PEK (Power Enable Key) under the corresponding menus. + Note on x86 this provides an ACPI OpRegion, so this must be 'y' + (builtin) and not a module, as the OpRegion must be available as + soon as possible. For the same reason the I2C bus driver options + I2C_DESIGNWARE_PLATFORM and I2C_DESIGNWARE_BAYTRAIL must be 'y' too. + config MFD_AXP20X_RSB tristate "X-Powers AXP series PMICs with RSB" select MFD_AXP20X @@ -448,17 +453,22 @@ config LPC_SCH config INTEL_SOC_PMIC bool "Support for Crystal Cove PMIC" - depends on GPIOLIB - depends on I2C=y + depends on HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK + depends on X86 || COMPILE_TEST select MFD_CORE select REGMAP_I2C select REGMAP_IRQ + select I2C_DESIGNWARE_PLATFORM if ACPI help Select this option to enable support for Crystal Cove PMIC on some Intel SoC systems. The PMIC provides ADC, GPIO, thermal, charger and related power management functions on these systems. + This option is a bool as it provides an ACPI OpRegion which must be + available before any devices using it are probed. This option also + causes the designware-i2c driver to be builtin for the same reason. + config INTEL_SOC_PMIC_BXTWC tristate "Support for Intel Broxton Whiskey Cove PMIC" depends on INTEL_PMC_IPC @@ -470,6 +480,22 @@ config INTEL_SOC_PMIC_BXTWC thermal, charger and related power management functions on these systems. +config INTEL_SOC_PMIC_CHTWC + tristate "Support for Intel Cherry Trail Whiskey Cove PMIC" + depends on ACPI && HAS_IOMEM && I2C=y && COMMON_CLK + depends on X86 || COMPILE_TEST + select MFD_CORE + select REGMAP_I2C + select REGMAP_IRQ + select I2C_DESIGNWARE_PLATFORM + help + Select this option to enable support for the Intel Cherry Trail + Whiskey Cove PMIC found on some Intel Cherry Trail systems. + + This option is a bool as it provides an ACPI OpRegion which must be + available before any devices using it are probed. This option also + causes the designware-i2c driver to be builtin for the same reason. + config MFD_INTEL_LPSS tristate select COMMON_CLK @@ -1325,6 +1351,20 @@ config MFD_TI_LP873X This driver can also be built as a module. If so, the module will be called lp873x. +config MFD_TI_LP87565 + tristate "TI LP87565 Power Management IC" + depends on I2C && OF + select MFD_CORE + select REGMAP_I2C + help + If you say yes here then you get support for the LP87565 series of + Power Management Integrated Circuits (PMIC). + These include voltage regulators, thermal protection, configurable + General Purpose Outputs (GPO) that are used in portable devices. + + This driver can also be built as a module. If so, the module + will be called lp87565. + config MFD_TPS65218 tristate "TI TPS65218 Power Management chips" depends on I2C diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index c16bf1ea0ea9b0a4432539b228a4a48744ac0599..080793b3fd0ed7dc8a903ebef3c1b05dbf5822c4 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o obj-$(CONFIG_MFD_TI_LP873X) += lp873x.o +obj-$(CONFIG_MFD_TI_LP87565) += lp87565.o obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o @@ -214,6 +215,7 @@ obj-$(CONFIG_MFD_SKY81452) += sky81452.o intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o +obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o obj-$(CONFIG_MFD_MT6397) += mt6397-core.o obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o diff --git a/drivers/mfd/atmel-flexcom.c b/drivers/mfd/atmel-flexcom.c index e8e67be6b493ac09d5a16959fd42edbe46fe272d..064bde9cff5af26fc9ba02ba65136bc814e6fc9e 100644 --- a/drivers/mfd/atmel-flexcom.c +++ b/drivers/mfd/atmel-flexcom.c @@ -80,7 +80,7 @@ static int atmel_flexcom_probe(struct platform_device *pdev) clk_disable_unprepare(clk); - return of_platform_populate(np, NULL, NULL, &pdev->dev); + return devm_of_platform_populate(&pdev->dev); } static const struct of_device_id atmel_flexcom_of_match[] = { diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 1dc6235778eb1e584845079f40962d181a4ac9f0..917b6ddc4f15a40a090bb3bfe318bcb6cc7cffe7 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -848,7 +848,8 @@ static struct mfd_cell axp803_cells[] = { .name = "axp20x-pek", .num_resources = ARRAY_SIZE(axp803_pek_resources), .resources = axp803_pek_resources, - } + }, + { .name = "axp20x-regulator" }, }; static struct mfd_cell axp806_cells[] = { diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index d4a407e466b5478465823c02cd8cfdd95f1b1748..dc6ce90916949d0821ca5d72f27d266a99294dab 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c @@ -147,7 +147,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) } if (IS_ENABLED(CONFIG_OF) && dev->of_node) { - err = of_platform_populate(dev->of_node, NULL, NULL, dev); + err = devm_of_platform_populate(dev); if (err) { mfd_remove_devices(dev); dev_err(dev, "Failed to register sub-devices\n"); @@ -183,6 +183,9 @@ int cros_ec_remove(struct cros_ec_device *ec_dev) cros_ec_acpi_remove_gpe_handler(); + if (ec_dev->irq) + free_irq(ec_dev->irq, ec_dev); + return 0; } EXPORT_SYMBOL(cros_ec_remove); diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c index 7f5e8be0a9ea42f9b7079cae2a5322ef2ed816cf..fbe0f245ce8ee50943340de1c05d6490a3a13ced 100644 --- a/drivers/mfd/da9062-core.c +++ b/drivers/mfd/da9062-core.c @@ -428,9 +428,6 @@ static const struct regmap_range da9061_aa_readable_ranges[] = { }, { .range_min = DA9062AA_VLDO1_B, .range_max = DA9062AA_VLDO4_B, - }, { - .range_min = DA9062AA_BBAT_CONT, - .range_max = DA9062AA_BBAT_CONT, }, { .range_min = DA9062AA_INTERFACE, .range_max = DA9062AA_CONFIG_E, @@ -513,9 +510,6 @@ static const struct regmap_range da9061_aa_writeable_ranges[] = { }, { .range_min = DA9062AA_VLDO1_B, .range_max = DA9062AA_VLDO4_B, - }, { - .range_min = DA9062AA_BBAT_CONT, - .range_max = DA9062AA_BBAT_CONT, }, { .range_min = DA9062AA_GP_ID_0, .range_max = DA9062AA_GP_ID_19, @@ -650,9 +644,6 @@ static const struct regmap_range da9062_aa_readable_ranges[] = { }, { .range_min = DA9062AA_VLDO1_B, .range_max = DA9062AA_VLDO4_B, - }, { - .range_min = DA9062AA_BBAT_CONT, - .range_max = DA9062AA_BBAT_CONT, }, { .range_min = DA9062AA_INTERFACE, .range_max = DA9062AA_CONFIG_E, @@ -729,9 +720,6 @@ static const struct regmap_range da9062_aa_writeable_ranges[] = { }, { .range_min = DA9062AA_VLDO1_B, .range_max = DA9062AA_VLDO4_B, - }, { - .range_min = DA9062AA_BBAT_CONT, - .range_max = DA9062AA_BBAT_CONT, }, { .range_min = DA9062AA_GP_ID_0, .range_max = DA9062AA_GP_ID_19, diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index 0bf3aebdac4507d79daa087397485183023dc446..ca829f85672f8f0663b6bc8b3d7dffe79cac8a05 100644 --- a/drivers/mfd/exynos-lpass.c +++ b/drivers/mfd/exynos-lpass.c @@ -138,7 +138,7 @@ static int exynos_lpass_probe(struct platform_device *pdev) pm_runtime_enable(dev); exynos_lpass_enable(lpass); - return of_platform_populate(dev->of_node, NULL, NULL, dev); + return devm_of_platform_populate(dev); } static int exynos_lpass_remove(struct platform_device *pdev) diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c index ac430a396a89945b0cad1542db8a11b68b497fa5..b3767c3141e58a0fd9af028ced1ad13f67726c77 100644 --- a/drivers/mfd/fsl-imx25-tsadc.c +++ b/drivers/mfd/fsl-imx25-tsadc.c @@ -59,7 +59,7 @@ static int mx25_tsadc_domain_map(struct irq_domain *d, unsigned int irq, return 0; } -static struct irq_domain_ops mx25_tsadc_domain_ops = { +static const struct irq_domain_ops mx25_tsadc_domain_ops = { .map = mx25_tsadc_domain_map, .xlate = irq_domain_xlate_onecell, }; @@ -129,7 +129,6 @@ static void mx25_tsadc_setup_clk(struct platform_device *pdev, static int mx25_tsadc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; struct mx25_tsadc *tsadc; struct resource *res; int ret; @@ -178,9 +177,7 @@ static int mx25_tsadc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tsadc); - of_platform_populate(np, NULL, NULL, dev); - - return 0; + return devm_of_platform_populate(dev); } static const struct of_device_id mx25_tsadc_ids[] = { diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 16ffeaeb1385826713cab38e444b86c6eef05277..ad388bb056cd795eff07b71016fb477c10a3ff9b 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -201,6 +201,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x9d64), (kernel_ulong_t)&spt_i2c_info }, { PCI_VDEVICE(INTEL, 0x9d65), (kernel_ulong_t)&spt_i2c_info }, { PCI_VDEVICE(INTEL, 0x9d66), (kernel_ulong_t)&spt_uart_info }, + /* CNL-LP */ + { PCI_VDEVICE(INTEL, 0x9da8), (kernel_ulong_t)&spt_uart_info }, + { PCI_VDEVICE(INTEL, 0x9da9), (kernel_ulong_t)&spt_uart_info }, + { PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&spt_info }, + { PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&spt_info }, + { PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&spt_info }, + { PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9dc7), (kernel_ulong_t)&spt_uart_info }, + { PCI_VDEVICE(INTEL, 0x9de8), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&spt_i2c_info }, /* SPT-H */ { PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info }, { PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info }, @@ -219,6 +232,17 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { { PCI_VDEVICE(INTEL, 0xa2e2), (kernel_ulong_t)&spt_i2c_info }, { PCI_VDEVICE(INTEL, 0xa2e3), (kernel_ulong_t)&spt_i2c_info }, { PCI_VDEVICE(INTEL, 0xa2e6), (kernel_ulong_t)&spt_uart_info }, + /* CNL-H */ + { PCI_VDEVICE(INTEL, 0xa328), (kernel_ulong_t)&spt_uart_info }, + { PCI_VDEVICE(INTEL, 0xa329), (kernel_ulong_t)&spt_uart_info }, + { PCI_VDEVICE(INTEL, 0xa32a), (kernel_ulong_t)&spt_info }, + { PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&spt_info }, + { PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&spt_info }, + { PCI_VDEVICE(INTEL, 0xa347), (kernel_ulong_t)&spt_uart_info }, + { PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&spt_i2c_info }, { } }; MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids); diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c index 7946d6e38b87201e3904f3247d2807c2ed174ca4..90e35dec8648f3235c41a0b380c16e686eb53fcc 100644 --- a/drivers/mfd/intel_quark_i2c_gpio.c +++ b/drivers/mfd/intel_quark_i2c_gpio.c @@ -58,19 +58,34 @@ struct intel_quark_mfd { struct clk_lookup *i2c_clk_lookup; }; -struct i2c_mode_info { - const char *name; - unsigned int i2c_scl_freq; -}; - -static const struct i2c_mode_info platform_i2c_mode_info[] = { +static const struct dmi_system_id dmi_platform_info[] = { + { + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"), + }, + .driver_data = (void *)100000, + }, { - .name = "Galileo", - .i2c_scl_freq = 100000, + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"), + }, + .driver_data = (void *)400000, }, { - .name = "GalileoGen2", - .i2c_scl_freq = 400000, + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"), + DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG, + "6ES7647-0AA00-0YA2"), + }, + .driver_data = (void *)400000, + }, + { + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"), + DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG, + "6ES7647-0AA00-1YA2"), + }, + .driver_data = (void *)400000, }, {} }; @@ -160,8 +175,7 @@ static void intel_quark_unregister_i2c_clk(struct device *dev) static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell) { - const char *board_name = dmi_get_system_info(DMI_BOARD_NAME); - const struct i2c_mode_info *info; + const struct dmi_system_id *dmi_id; struct dw_i2c_platform_data *pdata; struct resource *res = (struct resource *)cell->resources; struct device *dev = &pdev->dev; @@ -181,14 +195,9 @@ static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell) /* Normal mode by default */ pdata->i2c_scl_freq = 100000; - if (board_name) { - for (info = platform_i2c_mode_info; info->name; info++) { - if (!strcmp(board_name, info->name)) { - pdata->i2c_scl_freq = info->i2c_scl_freq; - break; - } - } - } + dmi_id = dmi_first_match(dmi_platform_info); + if (dmi_id) + pdata->i2c_scl_freq = (uintptr_t)dmi_id->driver_data; cell->platform_data = pdata; cell->pdata_size = sizeof(*pdata); diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c index 8c3cbf63c6ad0bdc117a9749824786389f6741ab..15bc052704a6d8ace919278db045c4ba189df156 100644 --- a/drivers/mfd/intel_soc_pmic_bxtwc.c +++ b/drivers/mfd/intel_soc_pmic_bxtwc.c @@ -82,20 +82,26 @@ enum bxtwc_irqs { BXTWC_PWRBTN_IRQ, }; -enum bxtwc_irqs_level2 { - /* Level 2 */ - BXTWC_THRM0_IRQ = 0, - BXTWC_THRM1_IRQ, - BXTWC_THRM2_IRQ, - BXTWC_BCU_IRQ, - BXTWC_ADC_IRQ, - BXTWC_USBC_IRQ, +enum bxtwc_irqs_bcu { + BXTWC_BCU_IRQ = 0, +}; + +enum bxtwc_irqs_adc { + BXTWC_ADC_IRQ = 0, +}; + +enum bxtwc_irqs_chgr { + BXTWC_USBC_IRQ = 0, BXTWC_CHGR0_IRQ, BXTWC_CHGR1_IRQ, - BXTWC_GPIO0_IRQ, - BXTWC_GPIO1_IRQ, - BXTWC_CRIT_IRQ, - BXTWC_TMU_IRQ, +}; + +enum bxtwc_irqs_tmu { + BXTWC_TMU_IRQ = 0, +}; + +enum bxtwc_irqs_crit { + BXTWC_CRIT_IRQ = 0, }; static const struct regmap_irq bxtwc_regmap_irqs[] = { @@ -110,24 +116,28 @@ static const struct regmap_irq bxtwc_regmap_irqs[] = { REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03), }; -static const struct regmap_irq bxtwc_regmap_irqs_level2[] = { - REGMAP_IRQ_REG(BXTWC_THRM0_IRQ, 0, 0xff), - REGMAP_IRQ_REG(BXTWC_THRM1_IRQ, 1, 0xbf), - REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff), - REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f), - REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff), - REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 5, BIT(5)), - REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f), - REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f), - REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff), - REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f), - REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03), +static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = { + REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, 0x1f), +}; + +static const struct regmap_irq bxtwc_regmap_irqs_adc[] = { + REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, 0xff), +}; + +static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = { + REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, BIT(5)), + REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f), + REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f), }; static const struct regmap_irq bxtwc_regmap_irqs_tmu[] = { REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, 0x06), }; +static const struct regmap_irq bxtwc_regmap_irqs_crit[] = { + REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, 0x03), +}; + static struct regmap_irq_chip bxtwc_regmap_irq_chip = { .name = "bxtwc_irq_chip", .status_base = BXTWC_IRQLVL1, @@ -137,15 +147,6 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip = { .num_regs = 2, }; -static struct regmap_irq_chip bxtwc_regmap_irq_chip_level2 = { - .name = "bxtwc_irq_chip_level2", - .status_base = BXTWC_THRM0IRQ, - .mask_base = BXTWC_MTHRM0IRQ, - .irqs = bxtwc_regmap_irqs_level2, - .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_level2), - .num_regs = 10, -}; - static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { .name = "bxtwc_irq_chip_tmu", .status_base = BXTWC_TMUIRQ, @@ -155,9 +156,44 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { .num_regs = 1, }; +static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = { + .name = "bxtwc_irq_chip_bcu", + .status_base = BXTWC_BCUIRQ, + .mask_base = BXTWC_MBCUIRQ, + .irqs = bxtwc_regmap_irqs_bcu, + .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_bcu), + .num_regs = 1, +}; + +static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = { + .name = "bxtwc_irq_chip_adc", + .status_base = BXTWC_ADCIRQ, + .mask_base = BXTWC_MADCIRQ, + .irqs = bxtwc_regmap_irqs_adc, + .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_adc), + .num_regs = 1, +}; + +static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = { + .name = "bxtwc_irq_chip_chgr", + .status_base = BXTWC_CHGR0IRQ, + .mask_base = BXTWC_MCHGR0IRQ, + .irqs = bxtwc_regmap_irqs_chgr, + .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_chgr), + .num_regs = 2, +}; + +static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = { + .name = "bxtwc_irq_chip_crit", + .status_base = BXTWC_CRITIRQ, + .mask_base = BXTWC_MCRITIRQ, + .irqs = bxtwc_regmap_irqs_crit, + .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_crit), + .num_regs = 1, +}; + static struct resource gpio_resources[] = { - DEFINE_RES_IRQ_NAMED(BXTWC_GPIO0_IRQ, "GPIO0"), - DEFINE_RES_IRQ_NAMED(BXTWC_GPIO1_IRQ, "GPIO1"), + DEFINE_RES_IRQ_NAMED(BXTWC_GPIO_LVL1_IRQ, "GPIO"), }; static struct resource adc_resources[] = { @@ -174,9 +210,7 @@ static struct resource charger_resources[] = { }; static struct resource thermal_resources[] = { - DEFINE_RES_IRQ(BXTWC_THRM0_IRQ), - DEFINE_RES_IRQ(BXTWC_THRM1_IRQ), - DEFINE_RES_IRQ(BXTWC_THRM2_IRQ), + DEFINE_RES_IRQ(BXTWC_THRM_LVL1_IRQ), }; static struct resource bcu_resources[] = { @@ -367,6 +401,26 @@ static const struct regmap_config bxtwc_regmap_config = { .reg_read = regmap_ipc_byte_reg_read, }; +static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic, + struct regmap_irq_chip_data *pdata, + int pirq, int irq_flags, + const struct regmap_irq_chip *chip, + struct regmap_irq_chip_data **data) +{ + int irq; + + irq = regmap_irq_get_virq(pdata, pirq); + if (irq < 0) { + dev_err(pmic->dev, + "Failed to get parent vIRQ(%d) for chip %s, ret:%d\n", + pirq, chip->name, irq); + return irq; + } + + return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags, + 0, chip, data); +} + static int bxtwc_probe(struct platform_device *pdev) { int ret; @@ -409,45 +463,88 @@ static int bxtwc_probe(struct platform_device *pdev) return ret; } - ret = regmap_add_irq_chip(pmic->regmap, pmic->irq, - IRQF_ONESHOT | IRQF_SHARED, - 0, &bxtwc_regmap_irq_chip, - &pmic->irq_chip_data); + ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq, + IRQF_ONESHOT | IRQF_SHARED, + 0, &bxtwc_regmap_irq_chip, + &pmic->irq_chip_data); if (ret) { dev_err(&pdev->dev, "Failed to add IRQ chip\n"); return ret; } - ret = regmap_add_irq_chip(pmic->regmap, pmic->irq, - IRQF_ONESHOT | IRQF_SHARED, - 0, &bxtwc_regmap_irq_chip_level2, - &pmic->irq_chip_data_level2); + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_TMU_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_tmu, + &pmic->irq_chip_data_tmu); if (ret) { - dev_err(&pdev->dev, "Failed to add secondary IRQ chip\n"); - goto err_irq_chip_level2; + dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n"); + return ret; } - ret = regmap_add_irq_chip(pmic->regmap, pmic->irq, - IRQF_ONESHOT | IRQF_SHARED, - 0, &bxtwc_regmap_irq_chip_tmu, - &pmic->irq_chip_data_tmu); + /* Add chained IRQ handler for BCU IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_BCU_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_bcu, + &pmic->irq_chip_data_bcu); + + if (ret) { - dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n"); - goto err_irq_chip_tmu; + dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n"); + return ret; + } + + /* Add chained IRQ handler for ADC IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_ADC_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_adc, + &pmic->irq_chip_data_adc); + + + if (ret) { + dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n"); + return ret; + } + + /* Add chained IRQ handler for CHGR IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_CHGR_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_chgr, + &pmic->irq_chip_data_chgr); + + + if (ret) { + dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n"); + return ret; + } + + /* Add chained IRQ handler for CRIT IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_CRIT_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_crit, + &pmic->irq_chip_data_crit); + + + if (ret) { + dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n"); + return ret; } - ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev, - ARRAY_SIZE(bxt_wc_dev), NULL, 0, - NULL); + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev, + ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL); if (ret) { dev_err(&pdev->dev, "Failed to add devices\n"); - goto err_mfd; + return ret; } ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group); if (ret) { dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret); - goto err_sysfs; + return ret; } /* @@ -461,28 +558,11 @@ static int bxtwc_probe(struct platform_device *pdev) BXTWC_MIRQLVL1_MCHGR, 0); return 0; - -err_sysfs: - mfd_remove_devices(&pdev->dev); -err_mfd: - regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_tmu); -err_irq_chip_tmu: - regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2); -err_irq_chip_level2: - regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); - - return ret; } static int bxtwc_remove(struct platform_device *pdev) { - struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev); - sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group); - mfd_remove_devices(&pdev->dev); - regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); - regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2); - regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_tmu); return 0; } diff --git a/drivers/mfd/intel_soc_pmic_chtwc.c b/drivers/mfd/intel_soc_pmic_chtwc.c new file mode 100644 index 0000000000000000000000000000000000000000..b35da01d5bcf084fc94fcb294aec03ab5da86cec --- /dev/null +++ b/drivers/mfd/intel_soc_pmic_chtwc.c @@ -0,0 +1,230 @@ +/* + * MFD core driver for Intel Cherrytrail Whiskey Cove PMIC + * + * Copyright (C) 2017 Hans de Goede + * + * Based on various non upstream patches to support the CHT Whiskey Cove PMIC: + * Copyright (C) 2013-2015 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PMIC device registers */ +#define REG_OFFSET_MASK GENMASK(7, 0) +#define REG_ADDR_MASK GENMASK(15, 8) +#define REG_ADDR_SHIFT 8 + +#define CHT_WC_IRQLVL1 0x6e02 +#define CHT_WC_IRQLVL1_MASK 0x6e0e + +/* Whiskey Cove PMIC share same ACPI ID between different platforms */ +#define CHT_WC_HRV 3 + +/* Level 1 IRQs (level 2 IRQs are handled in the child device drivers) */ +enum { + CHT_WC_PWRSRC_IRQ = 0, + CHT_WC_THRM_IRQ, + CHT_WC_BCU_IRQ, + CHT_WC_ADC_IRQ, + CHT_WC_EXT_CHGR_IRQ, + CHT_WC_GPIO_IRQ, + /* There is no irq 6 */ + CHT_WC_CRIT_IRQ = 7, +}; + +static struct resource cht_wc_pwrsrc_resources[] = { + DEFINE_RES_IRQ(CHT_WC_PWRSRC_IRQ), +}; + +static struct resource cht_wc_ext_charger_resources[] = { + DEFINE_RES_IRQ(CHT_WC_EXT_CHGR_IRQ), +}; + +static struct mfd_cell cht_wc_dev[] = { + { + .name = "cht_wcove_pwrsrc", + .num_resources = ARRAY_SIZE(cht_wc_pwrsrc_resources), + .resources = cht_wc_pwrsrc_resources, + }, { + .name = "cht_wcove_ext_chgr", + .num_resources = ARRAY_SIZE(cht_wc_ext_charger_resources), + .resources = cht_wc_ext_charger_resources, + }, + { .name = "cht_wcove_region", }, +}; + +/* + * The CHT Whiskey Cove covers multiple I2C addresses, with a 1 Byte + * register address space per I2C address, so we use 16 bit register + * addresses where the high 8 bits contain the I2C client address. + */ +static int cht_wc_byte_reg_read(void *context, unsigned int reg, + unsigned int *val) +{ + struct i2c_client *client = context; + int ret, orig_addr = client->addr; + + if (!(reg & REG_ADDR_MASK)) { + dev_err(&client->dev, "Error I2C address not specified\n"); + return -EINVAL; + } + + client->addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT; + ret = i2c_smbus_read_byte_data(client, reg & REG_OFFSET_MASK); + client->addr = orig_addr; + + if (ret < 0) + return ret; + + *val = ret; + return 0; +} + +static int cht_wc_byte_reg_write(void *context, unsigned int reg, + unsigned int val) +{ + struct i2c_client *client = context; + int ret, orig_addr = client->addr; + + if (!(reg & REG_ADDR_MASK)) { + dev_err(&client->dev, "Error I2C address not specified\n"); + return -EINVAL; + } + + client->addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT; + ret = i2c_smbus_write_byte_data(client, reg & REG_OFFSET_MASK, val); + client->addr = orig_addr; + + return ret; +} + +static const struct regmap_config cht_wc_regmap_cfg = { + .reg_bits = 16, + .val_bits = 8, + .reg_write = cht_wc_byte_reg_write, + .reg_read = cht_wc_byte_reg_read, +}; + +static const struct regmap_irq cht_wc_regmap_irqs[] = { + REGMAP_IRQ_REG(CHT_WC_PWRSRC_IRQ, 0, BIT(CHT_WC_PWRSRC_IRQ)), + REGMAP_IRQ_REG(CHT_WC_THRM_IRQ, 0, BIT(CHT_WC_THRM_IRQ)), + REGMAP_IRQ_REG(CHT_WC_BCU_IRQ, 0, BIT(CHT_WC_BCU_IRQ)), + REGMAP_IRQ_REG(CHT_WC_ADC_IRQ, 0, BIT(CHT_WC_ADC_IRQ)), + REGMAP_IRQ_REG(CHT_WC_EXT_CHGR_IRQ, 0, BIT(CHT_WC_EXT_CHGR_IRQ)), + REGMAP_IRQ_REG(CHT_WC_GPIO_IRQ, 0, BIT(CHT_WC_GPIO_IRQ)), + REGMAP_IRQ_REG(CHT_WC_CRIT_IRQ, 0, BIT(CHT_WC_CRIT_IRQ)), +}; + +static const struct regmap_irq_chip cht_wc_regmap_irq_chip = { + .name = "cht_wc_irq_chip", + .status_base = CHT_WC_IRQLVL1, + .mask_base = CHT_WC_IRQLVL1_MASK, + .irqs = cht_wc_regmap_irqs, + .num_irqs = ARRAY_SIZE(cht_wc_regmap_irqs), + .num_regs = 1, +}; + +static int cht_wc_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct intel_soc_pmic *pmic; + acpi_status status; + unsigned long long hrv; + int ret; + + status = acpi_evaluate_integer(ACPI_HANDLE(dev), "_HRV", NULL, &hrv); + if (ACPI_FAILURE(status)) { + dev_err(dev, "Failed to get PMIC hardware revision\n"); + return -ENODEV; + } + if (hrv != CHT_WC_HRV) { + dev_err(dev, "Invalid PMIC hardware revision: %llu\n", hrv); + return -ENODEV; + } + if (client->irq < 0) { + dev_err(dev, "Invalid IRQ\n"); + return -EINVAL; + } + + pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); + if (!pmic) + return -ENOMEM; + + pmic->irq = client->irq; + pmic->dev = dev; + i2c_set_clientdata(client, pmic); + + pmic->regmap = devm_regmap_init(dev, NULL, client, &cht_wc_regmap_cfg); + if (IS_ERR(pmic->regmap)) + return PTR_ERR(pmic->regmap); + + ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq, + IRQF_ONESHOT | IRQF_SHARED, 0, + &cht_wc_regmap_irq_chip, + &pmic->irq_chip_data); + if (ret) + return ret; + + return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, + cht_wc_dev, ARRAY_SIZE(cht_wc_dev), NULL, 0, + regmap_irq_get_domain(pmic->irq_chip_data)); +} + +static void cht_wc_shutdown(struct i2c_client *client) +{ + struct intel_soc_pmic *pmic = i2c_get_clientdata(client); + + disable_irq(pmic->irq); +} + +static int __maybe_unused cht_wc_suspend(struct device *dev) +{ + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); + + disable_irq(pmic->irq); + + return 0; +} + +static int __maybe_unused cht_wc_resume(struct device *dev) +{ + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); + + enable_irq(pmic->irq); + + return 0; +} +static SIMPLE_DEV_PM_OPS(cht_wc_pm_ops, cht_wc_suspend, cht_wc_resume); + +static const struct i2c_device_id cht_wc_i2c_id[] = { + { } +}; + +static const struct acpi_device_id cht_wc_acpi_ids[] = { + { "INT34D3", }, + { } +}; + +static struct i2c_driver cht_wc_driver = { + .driver = { + .name = "CHT Whiskey Cove PMIC", + .pm = &cht_wc_pm_ops, + .acpi_match_table = cht_wc_acpi_ids, + }, + .probe_new = cht_wc_probe, + .shutdown = cht_wc_shutdown, + .id_table = cht_wc_i2c_id, +}; +builtin_i2c_driver(cht_wc_driver); diff --git a/drivers/mfd/ipaq-micro.c b/drivers/mfd/ipaq-micro.c index 124aad2b1d02978155020a1042099a6e7e0b8072..cd762d08f116f1edfa18678ec24413e3eab078b3 100644 --- a/drivers/mfd/ipaq-micro.c +++ b/drivers/mfd/ipaq-micro.c @@ -53,8 +53,6 @@ static void ipaq_micro_trigger_tx(struct ipaq_micro *micro) tx->buf[bp++] = checksum; tx->len = bp; tx->index = 0; - print_hex_dump_debug("data: ", DUMP_PREFIX_OFFSET, 16, 1, - tx->buf, tx->len, true); /* Enable interrupt */ val = readl(micro->base + UTCR3); @@ -281,9 +279,6 @@ static void __init ipaq_micro_eeprom_dump(struct ipaq_micro *micro) dev_info(micro->dev, "RAM size: %u KiB\n", ipaq_micro_to_u16(dump+92)); dev_info(micro->dev, "screen: %u x %u\n", ipaq_micro_to_u16(dump+94), ipaq_micro_to_u16(dump+96)); - print_hex_dump_debug("eeprom: ", DUMP_PREFIX_OFFSET, 16, 1, - dump, 256, true); - } static void micro_tx_chars(struct ipaq_micro *micro) diff --git a/drivers/mfd/lp87565.c b/drivers/mfd/lp87565.c new file mode 100644 index 0000000000000000000000000000000000000000..340ad0c63744a4ac4ee56a1841f132bed8e16fd8 --- /dev/null +++ b/drivers/mfd/lp87565.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * Author: Keerthy + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + */ + +#include +#include +#include +#include +#include + +#include + +static const struct regmap_config lp87565_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = LP87565_REG_MAX, +}; + +static const struct mfd_cell lp87565_cells[] = { + { .name = "lp87565-q1-regulator", }, + { .name = "lp87565-q1-gpio", }, +}; + +static const struct of_device_id of_lp87565_match_table[] = { + { .compatible = "ti,lp87565", }, + { + .compatible = "ti,lp87565-q1", + .data = (void *)LP87565_DEVICE_TYPE_LP87565_Q1, + }, + {} +}; +MODULE_DEVICE_TABLE(of, of_lp87565_match_table); + +static int lp87565_probe(struct i2c_client *client, + const struct i2c_device_id *ids) +{ + struct lp87565 *lp87565; + const struct of_device_id *of_id; + int ret; + unsigned int otpid; + + lp87565 = devm_kzalloc(&client->dev, sizeof(*lp87565), GFP_KERNEL); + if (!lp87565) + return -ENOMEM; + + lp87565->dev = &client->dev; + + lp87565->regmap = devm_regmap_init_i2c(client, &lp87565_regmap_config); + if (IS_ERR(lp87565->regmap)) { + ret = PTR_ERR(lp87565->regmap); + dev_err(lp87565->dev, + "Failed to initialize register map: %d\n", ret); + return ret; + } + + ret = regmap_read(lp87565->regmap, LP87565_REG_OTP_REV, &otpid); + if (ret) { + dev_err(lp87565->dev, "Failed to read OTP ID\n"); + return ret; + } + + lp87565->rev = otpid & LP87565_OTP_REV_OTP_ID; + + of_id = of_match_device(of_lp87565_match_table, &client->dev); + if (of_id) + lp87565->dev_type = (enum lp87565_device_type)of_id->data; + + i2c_set_clientdata(client, lp87565); + + ret = mfd_add_devices(lp87565->dev, PLATFORM_DEVID_AUTO, lp87565_cells, + ARRAY_SIZE(lp87565_cells), NULL, 0, NULL); + + return ret; +} + +static const struct i2c_device_id lp87565_id_table[] = { + { "lp87565-q1", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, lp87565_id_table); + +static struct i2c_driver lp87565_driver = { + .driver = { + .name = "lp87565", + .of_match_table = of_lp87565_match_table, + }, + .probe = lp87565_probe, + .id_table = lp87565_id_table, +}; +module_i2c_driver(lp87565_driver); + +MODULE_AUTHOR("J Keerthy "); +MODULE_DESCRIPTION("lp87565 chip family Multi-Function Device driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c index 3cab58ab0b848232e16a514b14337817400c271b..d2cc1eabac05b26faaf76d21d6a18cce8ceccd68 100644 --- a/drivers/mfd/motorola-cpcap.c +++ b/drivers/mfd/motorola-cpcap.c @@ -260,17 +260,7 @@ static int cpcap_probe(struct spi_device *spi) if (ret) return ret; - return of_platform_populate(spi->dev.of_node, NULL, NULL, - &cpcap->spi->dev); -} - -static int cpcap_remove(struct spi_device *pdev) -{ - struct cpcap_ddata *cpcap = spi_get_drvdata(pdev); - - of_platform_depopulate(&cpcap->spi->dev); - - return 0; + return devm_of_platform_populate(&cpcap->spi->dev); } static struct spi_driver cpcap_driver = { @@ -279,7 +269,6 @@ static struct spi_driver cpcap_driver = { .of_match_table = cpcap_of_match, }, .probe = cpcap_probe, - .remove = cpcap_remove, }; module_spi_driver(cpcap_driver); diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index 9103affedcbc8f40765a3296238d6a39744d84ef..3922a93f9f92420ae9f81f0bcc9c514e80a1e726 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -676,7 +676,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c, * otherwise continue and add devices using mfd helpers. */ if (node) { - ret = of_platform_populate(node, NULL, NULL, &i2c->dev); + ret = devm_of_platform_populate(&i2c->dev); if (ret < 0) { goto err_irq; } else if (pdata->pm_off && !pm_power_off) { diff --git a/drivers/mfd/qcom-spmi-pmic.c b/drivers/mfd/qcom-spmi-pmic.c index 8653e8b9bb4fc29359a1b84e7dd676f7cf4b2d9b..2022bdfa7ab4221a544f3222217678671712bca7 100644 --- a/drivers/mfd/qcom-spmi-pmic.c +++ b/drivers/mfd/qcom-spmi-pmic.c @@ -120,7 +120,6 @@ static const struct regmap_config spmi_regmap_config = { static int pmic_spmi_probe(struct spmi_device *sdev) { - struct device_node *root = sdev->dev.of_node; struct regmap *regmap; regmap = devm_regmap_init_spmi_ext(sdev, &spmi_regmap_config); @@ -131,19 +130,13 @@ static int pmic_spmi_probe(struct spmi_device *sdev) if (sdev->usid % 2 == 0) pmic_spmi_show_revid(regmap, &sdev->dev); - return of_platform_populate(root, NULL, NULL, &sdev->dev); -} - -static void pmic_spmi_remove(struct spmi_device *sdev) -{ - of_platform_depopulate(&sdev->dev); + return devm_of_platform_populate(&sdev->dev); } MODULE_DEVICE_TABLE(of, pmic_spmi_id_table); static struct spmi_driver pmic_spmi_driver = { .probe = pmic_spmi_probe, - .remove = pmic_spmi_remove, .driver = { .name = "pmic-spmi", .of_match_table = pmic_spmi_id_table, diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c index 8131d1975745ec51a6219979f517827508c65497..f4037d42a60fa7bcc63f034e01779d0557597110 100644 --- a/drivers/mfd/rn5t618.c +++ b/drivers/mfd/rn5t618.c @@ -155,6 +155,8 @@ static int rn5t618_i2c_remove(struct i2c_client *i2c) pm_power_off = NULL; } + unregister_restart_handler(&rn5t618_restart_handler); + return 0; } diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 850590aac008261b526c797925a7ef330047c749..a0ac89dfdf0ff43dbadf13547f04154bcc4479af 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "rtsx_pcr.h" @@ -452,8 +453,12 @@ int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, } spin_lock_irqsave(&pcr->lock, flags); - if (pcr->trans_result == TRANS_RESULT_FAIL) - err = -EINVAL; + if (pcr->trans_result == TRANS_RESULT_FAIL) { + err = -EILSEQ; + if (pcr->dma_error_count < RTS_MAX_TIMES_FREQ_REDUCTION) + pcr->dma_error_count++; + } + else if (pcr->trans_result == TRANS_NO_DEVICE) err = -ENODEV; spin_unlock_irqrestore(&pcr->lock, flags); @@ -659,6 +664,13 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, if (err < 0) return err; + /* Reduce card clock by 20MHz each time a DMA transfer error occurs */ + if (card_clock == UHS_SDR104_MAX_DTR && + pcr->dma_error_count && + PCI_PID(pcr) == RTS5227_DEVICE_ID) + card_clock = UHS_SDR104_MAX_DTR - + (pcr->dma_error_count * 20000000); + card_clock /= 1000000; pcr_dbg(pcr, "Switch card clock to %dMHz\n", card_clock); @@ -894,6 +906,7 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) pcr->card_removed |= SD_EXIST; pcr->card_inserted &= ~SD_EXIST; } + pcr->dma_error_count = 0; } if (int_reg & MS_INT) { diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c index 1f40baf1234e3e053918e81805117027f7b40100..93a8297de52aab6a54acfbfe511a22b6273de1a1 100644 --- a/drivers/mfd/smsc-ece1099.c +++ b/drivers/mfd/smsc-ece1099.c @@ -69,8 +69,7 @@ static int smsc_i2c_probe(struct i2c_client *i2c, #ifdef CONFIG_OF if (i2c->dev.of_node) - ret = of_platform_populate(i2c->dev.of_node, - NULL, NULL, &i2c->dev); + ret = devm_of_platform_populate(&i2c->dev); #endif return ret; diff --git a/drivers/mfd/stm32-timers.c b/drivers/mfd/stm32-timers.c index 2182f00db101fd1144d8a7f9a9d80318827e6f7c..a6675a44940958cc47533c866a27681dc6a9bdcd 100644 --- a/drivers/mfd/stm32-timers.c +++ b/drivers/mfd/stm32-timers.c @@ -58,14 +58,7 @@ static int stm32_timers_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ddata); - return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); -} - -static int stm32_timers_remove(struct platform_device *pdev) -{ - of_platform_depopulate(&pdev->dev); - - return 0; + return devm_of_platform_populate(&pdev->dev); } static const struct of_device_id stm32_timers_of_match[] = { @@ -76,7 +69,6 @@ MODULE_DEVICE_TABLE(of, stm32_timers_of_match); static struct platform_driver stm32_timers_driver = { .probe = stm32_timers_probe, - .remove = stm32_timers_remove, .driver = { .name = "stm32-timers", .of_match_table = stm32_timers_of_match, diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index d16e71bd9482ab2ca005287c9fd9c72b07b4ebe3..0c9f0390e891949ff7c84d78f75a36fff168aecd 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -797,7 +797,9 @@ static int tc6393xb_resume(struct platform_device *dev) int ret; int i; - clk_prepare_enable(tc6393xb->clk); + ret = clk_prepare_enable(tc6393xb->clk); + if (ret) + return ret; ret = tcpd->resume(dev); if (ret) diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index b46c0cfc27d9586c946474853c1b3dd8eaaf1e92..378c02d43bf7771b0312e4cc3da6007e44500a2b 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -638,8 +638,10 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) } } - if (status < 0) + if (status < 0) { + dev_err(dev, "module to setup SIH for not found\n"); return status; + } agent = kzalloc(sizeof(*agent), GFP_KERNEL); if (!agent) diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 13a4c1190dca538082be9fe787b7c7d8ad23efcd..e70d35ef5c6d6cf5e01234d150a1f9a175f01df5 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1766,7 +1766,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq) } wm831x->locked = 1; - if (pdata && pdata->pre_init) { + if (pdata->pre_init) { ret = pdata->pre_init(wm831x); if (ret != 0) { dev_err(wm831x->dev, "pre_init() failed: %d\n", ret); @@ -1774,19 +1774,17 @@ int wm831x_device_init(struct wm831x *wm831x, int irq) } } - if (pdata) { - for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { - if (!pdata->gpio_defaults[i]) - continue; + for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { + if (!pdata->gpio_defaults[i]) + continue; - wm831x_reg_write(wm831x, - WM831X_GPIO1_CONTROL + i, - pdata->gpio_defaults[i] & 0xffff); - } + wm831x_reg_write(wm831x, + WM831X_GPIO1_CONTROL + i, + pdata->gpio_defaults[i] & 0xffff); } /* Multiply by 10 as we have many subdevices of the same type */ - if (pdata && pdata->wm831x_num) + if (pdata->wm831x_num) wm831x_num = pdata->wm831x_num * 10; else wm831x_num = -1; @@ -1809,7 +1807,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq) ret = mfd_add_devices(wm831x->dev, wm831x_num, wm8311_devs, ARRAY_SIZE(wm8311_devs), NULL, 0, NULL); - if (!pdata || !pdata->disable_touch) + if (!pdata->disable_touch) mfd_add_devices(wm831x->dev, wm831x_num, touch_devs, ARRAY_SIZE(touch_devs), NULL, 0, NULL); @@ -1819,7 +1817,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq) ret = mfd_add_devices(wm831x->dev, wm831x_num, wm8312_devs, ARRAY_SIZE(wm8312_devs), NULL, 0, NULL); - if (!pdata || !pdata->disable_touch) + if (!pdata->disable_touch) mfd_add_devices(wm831x->dev, wm831x_num, touch_devs, ARRAY_SIZE(touch_devs), NULL, 0, NULL); @@ -1865,7 +1863,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq) dev_info(wm831x->dev, "32.768kHz clock disabled, no RTC\n"); } - if (pdata && pdata->backlight) { + if (pdata->backlight) { /* Treat errors as non-critical */ ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, ARRAY_SIZE(backlight_devs), NULL, @@ -1877,7 +1875,7 @@ int wm831x_device_init(struct wm831x *wm831x, int irq) wm831x_otp_init(wm831x); - if (pdata && pdata->post_init) { + if (pdata->post_init) { ret = pdata->post_init(wm831x); if (ret != 0) { dev_err(wm831x->dev, "post_init() failed: %d\n", ret); diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c index 781af060f32d45312500139efab006ca391ac83c..22f7054d1b28633da6618d6ec7ab4158953876a8 100644 --- a/drivers/mfd/wm831x-i2c.c +++ b/drivers/mfd/wm831x-i2c.c @@ -37,6 +37,10 @@ static int wm831x_i2c_probe(struct i2c_client *i2c, if (i2c->dev.of_node) { of_id = of_match_device(wm831x_of_match, &i2c->dev); + if (!of_id) { + dev_err(&i2c->dev, "Failed to match device\n"); + return -ENODEV; + } type = (enum wm831x_parent)of_id->data; } else { type = (enum wm831x_parent)id->driver_data; diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c index c332e2885b26e2a5a1cbe50801149b6d48eca3ca..018ce652ae57d09e38e27315a265d7e5d96c5b5e 100644 --- a/drivers/mfd/wm831x-spi.c +++ b/drivers/mfd/wm831x-spi.c @@ -34,6 +34,10 @@ static int wm831x_spi_probe(struct spi_device *spi) if (spi->dev.of_node) { of_id = of_match_device(wm831x_of_match, &spi->dev); + if (!of_id) { + dev_err(&spi->dev, "Failed to match device\n"); + return -ENODEV; + } type = (enum wm831x_parent)of_id->data; } else { type = (enum wm831x_parent)id->driver_data; diff --git a/drivers/platform/x86/intel_bxtwc_tmu.c b/drivers/platform/x86/intel_bxtwc_tmu.c index e202abd5b0df2d61708d044ddeba090862cc98cb..ea865d4ca2209fb0b60de02c038b8eda7d229438 100644 --- a/drivers/platform/x86/intel_bxtwc_tmu.c +++ b/drivers/platform/x86/intel_bxtwc_tmu.c @@ -92,10 +92,6 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev) } wctmu->irq = virq; - /* Enable TMU interrupts */ - regmap_update_bits(wctmu->regmap, BXTWC_MIRQLVL1, - BXTWC_MIRQLVL1_MTMU, 0); - /* Unmask TMU second level Wake & System alarm */ regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG, BXTWC_TMU_ALRM_MASK, 0); diff --git a/drivers/thermal/intel_bxt_pmic_thermal.c b/drivers/thermal/intel_bxt_pmic_thermal.c index 0f19a393ddd88fec064951291c4c2db007fea8ec..ef6b32242ccbce8c7258a7531d3d82d637a48f8a 100644 --- a/drivers/thermal/intel_bxt_pmic_thermal.c +++ b/drivers/thermal/intel_bxt_pmic_thermal.c @@ -241,7 +241,7 @@ static int pmic_thermal_probe(struct platform_device *pdev) } regmap = pmic->regmap; - regmap_irq_chip = pmic->irq_chip_data_level2; + regmap_irq_chip = pmic->irq_chip_data; pmic_irq_count = 0; while ((irq = platform_get_irq(pdev, pmic_irq_count)) != -ENXIO) { diff --git a/drivers/usb/typec/typec_wcove.c b/drivers/usb/typec/typec_wcove.c index c2ce252890277464538a6139773a4ffb7b9bf65b..e9c4e784a9cb88494e2d6a862a902b8a9ae5c916 100644 --- a/drivers/usb/typec/typec_wcove.c +++ b/drivers/usb/typec/typec_wcove.c @@ -303,7 +303,7 @@ static int wcove_typec_probe(struct platform_device *pdev) wcove->dev = &pdev->dev; wcove->regmap = pmic->regmap; - ret = regmap_irq_get_virq(pmic->irq_chip_data_level2, + ret = regmap_irq_get_virq(pmic->irq_chip_data_chgr, platform_get_irq(pdev, 0)); if (ret < 0) return ret; diff --git a/include/linux/mfd/intel_soc_pmic.h b/include/linux/mfd/intel_soc_pmic.h index 956caa0628f5e4e6f2daf1fbf1b4c4c491b59c11..5aacdb017a9f68420ab710463fcb64ecf17b620f 100644 --- a/include/linux/mfd/intel_soc_pmic.h +++ b/include/linux/mfd/intel_soc_pmic.h @@ -25,8 +25,11 @@ struct intel_soc_pmic { int irq; struct regmap *regmap; struct regmap_irq_chip_data *irq_chip_data; - struct regmap_irq_chip_data *irq_chip_data_level2; struct regmap_irq_chip_data *irq_chip_data_tmu; + struct regmap_irq_chip_data *irq_chip_data_bcu; + struct regmap_irq_chip_data *irq_chip_data_adc; + struct regmap_irq_chip_data *irq_chip_data_chgr; + struct regmap_irq_chip_data *irq_chip_data_crit; struct device *dev; }; diff --git a/include/linux/mfd/lp87565.h b/include/linux/mfd/lp87565.h new file mode 100644 index 0000000000000000000000000000000000000000..d0c91ba655255b37808c62ef47116bf020c867c3 --- /dev/null +++ b/include/linux/mfd/lp87565.h @@ -0,0 +1,270 @@ +/* + * Functions to access LP87565 power management chip. + * + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + */ + +#ifndef __LINUX_MFD_LP87565_H +#define __LINUX_MFD_LP87565_H + +#include +#include +#include + +enum lp87565_device_type { + LP87565_DEVICE_TYPE_UNKNOWN = 0, + LP87565_DEVICE_TYPE_LP87565_Q1, +}; + +/* All register addresses */ +#define LP87565_REG_DEV_REV 0X00 +#define LP87565_REG_OTP_REV 0X01 +#define LP87565_REG_BUCK0_CTRL_1 0X02 +#define LP87565_REG_BUCK0_CTRL_2 0X03 + +#define LP87565_REG_BUCK1_CTRL_1 0X04 +#define LP87565_REG_BUCK1_CTRL_2 0X05 + +#define LP87565_REG_BUCK2_CTRL_1 0X06 +#define LP87565_REG_BUCK2_CTRL_2 0X07 + +#define LP87565_REG_BUCK3_CTRL_1 0X08 +#define LP87565_REG_BUCK3_CTRL_2 0X09 + +#define LP87565_REG_BUCK0_VOUT 0X0A +#define LP87565_REG_BUCK0_FLOOR_VOUT 0X0B + +#define LP87565_REG_BUCK1_VOUT 0X0C +#define LP87565_REG_BUCK1_FLOOR_VOUT 0X0D + +#define LP87565_REG_BUCK2_VOUT 0X0E +#define LP87565_REG_BUCK2_FLOOR_VOUT 0X0F + +#define LP87565_REG_BUCK3_VOUT 0X10 +#define LP87565_REG_BUCK3_FLOOR_VOUT 0X11 + +#define LP87565_REG_BUCK0_DELAY 0X12 +#define LP87565_REG_BUCK1_DELAY 0X13 + +#define LP87565_REG_BUCK2_DELAY 0X14 +#define LP87565_REG_BUCK3_DELAY 0X15 + +#define LP87565_REG_GPO2_DELAY 0X16 +#define LP87565_REG_GPO3_DELAY 0X17 +#define LP87565_REG_RESET 0X18 +#define LP87565_REG_CONFIG 0X19 + +#define LP87565_REG_INT_TOP_1 0X1A +#define LP87565_REG_INT_TOP_2 0X1B + +#define LP87565_REG_INT_BUCK_0_1 0X1C +#define LP87565_REG_INT_BUCK_2_3 0X1D +#define LP87565_REG_TOP_STAT 0X1E +#define LP87565_REG_BUCK_0_1_STAT 0X1F +#define LP87565_REG_BUCK_2_3_STAT 0x20 + +#define LP87565_REG_TOP_MASK_1 0x21 +#define LP87565_REG_TOP_MASK_2 0x22 + +#define LP87565_REG_BUCK_0_1_MASK 0x23 +#define LP87565_REG_BUCK_2_3_MASK 0x24 +#define LP87565_REG_SEL_I_LOAD 0x25 + +#define LP87565_REG_I_LOAD_2 0x26 +#define LP87565_REG_I_LOAD_1 0x27 + +#define LP87565_REG_PGOOD_CTRL1 0x28 +#define LP87565_REG_PGOOD_CTRL2 0x29 +#define LP87565_REG_PGOOD_FLT 0x2A +#define LP87565_REG_PLL_CTRL 0x2B +#define LP87565_REG_PIN_FUNCTION 0x2C +#define LP87565_REG_GPIO_CONFIG 0x2D +#define LP87565_REG_GPIO_IN 0x2E +#define LP87565_REG_GPIO_OUT 0x2F + +#define LP87565_REG_MAX LP87565_REG_GPIO_OUT + +/* Register field definitions */ +#define LP87565_DEV_REV_DEV_ID 0xC0 +#define LP87565_DEV_REV_ALL_LAYER 0x30 +#define LP87565_DEV_REV_METAL_LAYER 0x0F + +#define LP87565_OTP_REV_OTP_ID 0xFF + +#define LP87565_BUCK_CTRL_1_EN BIT(7) +#define LP87565_BUCK_CTRL_1_EN_PIN_CTRL BIT(6) +#define LP87565_BUCK_CTRL_1_PIN_SELECT_EN 0x30 + +#define LP87565_BUCK_CTRL_1_ROOF_FLOOR_EN BIT(3) +#define LP87565_BUCK_CTRL_1_RDIS_EN BIT(2) +#define LP87565_BUCK_CTRL_1_FPWM BIT(1) +/* Bit0 is reserved for BUCK1 and BUCK3 and valid only for BUCK0 and BUCK2 */ +#define LP87565_BUCK_CTRL_1_FPWM_MP_0_2 BIT(0) + +#define LP87565_BUCK_CTRL_2_ILIM 0x38 +#define LP87565_BUCK_CTRL_2_SLEW_RATE 0x07 + +#define LP87565_BUCK_VSET 0xFF +#define LP87565_BUCK_FLOOR_VSET 0xFF + +#define LP87565_BUCK_SHUTDOWN_DELAY 0xF0 +#define LP87565_BUCK_STARTUP_DELAY 0x0F + +#define LP87565_GPIO_SHUTDOWN_DELAY 0xF0 +#define LP87565_GPIO_STARTUP_DELAY 0x0F + +#define LP87565_RESET_SW_RESET BIT(0) + +#define LP87565_CONFIG_DOUBLE_DELAY BIT(7) +#define LP87565_CONFIG_CLKIN_PD BIT(6) +#define LP87565_CONFIG_EN4_PD BIT(5) +#define LP87565_CONFIG_EN3_PD BIT(4) +#define LP87565_CONFIG_TDIE_WARN_LEVEL BIT(3) +#define LP87565_CONFIG_EN2_PD BIT(2) +#define LP87565_CONFIG_EN1_PD BIT(1) + +#define LP87565_INT_GPIO BIT(7) +#define LP87565_INT_BUCK23 BIT(6) +#define LP87565_INT_BUCK01 BIT(5) +#define LP87565_NO_SYNC_CLK BIT(4) +#define LP87565_TDIE_SD BIT(3) +#define LP87565_TDIE_WARN BIT(2) +#define LP87565_INT_OVP BIT(1) +#define LP87565_I_LOAD_READY BIT(0) + +#define LP87565_INT_TOP2_RESET_REG BIT(0) + +#define LP87565_BUCK1_PG_INT BIT(6) +#define LP87565_BUCK1_SC_INT BIT(5) +#define LP87565_BUCK1_ILIM_INT BIT(4) +#define LP87565_BUCK0_PG_INT BIT(2) +#define LP87565_BUCK0_SC_INT BIT(1) +#define LP87565_BUCK0_ILIM_INT BIT(0) + +#define LP87565_BUCK3_PG_INT BIT(6) +#define LP87565_BUCK3_SC_INT BIT(5) +#define LP87565_BUCK3_ILIM_INT BIT(4) +#define LP87565_BUCK2_PG_INT BIT(2) +#define LP87565_BUCK2_SC_INT BIT(1) +#define LP87565_BUCK2_ILIM_INT BIT(0) + +#define LP87565_SYNC_CLK_STAT BIT(4) +#define LP87565_TDIE_SD_STAT BIT(3) +#define LP87565_TDIE_WARN_STAT BIT(2) +#define LP87565_OVP_STAT BIT(1) + +#define LP87565_BUCK1_STAT BIT(7) +#define LP87565_BUCK1_PG_STAT BIT(6) +#define LP87565_BUCK1_ILIM_STAT BIT(4) +#define LP87565_BUCK0_STAT BIT(3) +#define LP87565_BUCK0_PG_STAT BIT(2) +#define LP87565_BUCK0_ILIM_STAT BIT(0) + +#define LP87565_BUCK3_STAT BIT(7) +#define LP87565_BUCK3_PG_STAT BIT(6) +#define LP87565_BUCK3_ILIM_STAT BIT(4) +#define LP87565_BUCK2_STAT BIT(3) +#define LP87565_BUCK2_PG_STAT BIT(2) +#define LP87565_BUCK2_ILIM_STAT BIT(0) + +#define LPL87565_GPIO_MASK BIT(7) +#define LPL87565_SYNC_CLK_MASK BIT(4) +#define LPL87565_TDIE_WARN_MASK BIT(2) +#define LPL87565_I_LOAD_READY_MASK BIT(0) + +#define LPL87565_RESET_REG_MASK BIT(0) + +#define LPL87565_BUCK1_PG_MASK BIT(6) +#define LPL87565_BUCK1_ILIM_MASK BIT(4) +#define LPL87565_BUCK0_PG_MASK BIT(2) +#define LPL87565_BUCK0_ILIM_MASK BIT(0) + +#define LPL87565_BUCK3_PG_MASK BIT(6) +#define LPL87565_BUCK3_ILIM_MASK BIT(4) +#define LPL87565_BUCK2_PG_MASK BIT(2) +#define LPL87565_BUCK2_ILIM_MASK BIT(0) + +#define LP87565_LOAD_CURRENT_BUCK_SELECT 0x3 + +#define LP87565_I_LOAD2_BUCK_LOAD_CURRENT 0x3 +#define LP87565_I_LOAD1_BUCK_LOAD_CURRENT 0xFF + +#define LP87565_PG3_SEL 0xC0 +#define LP87565_PG2_SEL 0x30 +#define LP87565_PG1_SEL 0x0C +#define LP87565_PG0_SEL 0x03 + +#define LP87565_HALF_DAY BIT(7) +#define LP87565_EN_PG0_NINT BIT(6) +#define LP87565_PGOOD_SET_DELAY BIT(5) +#define LP87565_EN_PGFLT_STAT BIT(4) +#define LP87565_PGOOD_WINDOW BIT(2) +#define LP87565_PGOOD_OD BIT(1) +#define LP87565_PGOOD_POL BIT(0) + +#define LP87565_PG3_FLT BIT(3) +#define LP87565_PG2_FLT BIT(2) +#define LP87565_PG1_FLT BIT(1) +#define LP87565_PG0_FLT BIT(0) + +#define LP87565_PLL_MODE 0xC0 +#define LP87565_EXT_CLK_FREQ 0x1F + +#define LP87565_EN_SPREAD_SPEC BIT(7) +#define LP87565_EN_PIN_CTRL_GPIO3 BIT(6) +#define LP87565_EN_PIN_SELECT_GPIO3 BIT(5) +#define LP87565_EN_PIN_CTRL_GPIO2 BIT(4) +#define LP87565_EN_PIN_SELECT_GPIO2 BIT(3) +#define LP87565_GPIO3_SEL BIT(2) +#define LP87565_GPIO2_SEL BIT(1) +#define LP87565_GPIO1_SEL BIT(0) + +#define LP87565_GOIO3_OD BIT(6) +#define LP87565_GOIO2_OD BIT(5) +#define LP87565_GOIO1_OD BIT(4) +#define LP87565_GOIO3_DIR BIT(2) +#define LP87565_GOIO2_DIR BIT(1) +#define LP87565_GOIO1_DIR BIT(0) + +#define LP87565_GOIO3_IN BIT(2) +#define LP87565_GOIO2_IN BIT(1) +#define LP87565_GOIO1_IN BIT(0) + +#define LP87565_GOIO3_OUT BIT(2) +#define LP87565_GOIO2_OUT BIT(1) +#define LP87565_GOIO1_OUT BIT(0) + +/* Number of step-down converters available */ +#define LP87565_NUM_BUCK 6 + +enum LP87565_regulator_id { + /* BUCK's */ + LP87565_BUCK_0, + LP87565_BUCK_1, + LP87565_BUCK_2, + LP87565_BUCK_3, + LP87565_BUCK_10, + LP87565_BUCK_23, +}; + +/** + * struct LP87565 - state holder for the LP87565 driver + * @dev: struct device pointer for MFD device + * @rev: revision of the LP87565 + * @dev_type: The device type for example lp87565-q1 + * @lock: lock guarding the data structure + * @regmap: register map of the LP87565 PMIC + * + * Device data may be used to access the LP87565 chip + */ +struct lp87565 { + struct device *dev; + u8 rev; + u8 dev_type; + struct regmap *regmap; +}; +#endif /* __LINUX_MFD_LP87565_H */ diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 7eb7cbac0a9a39b2d0906816ff6391cc260ab69a..116816fb9110d20c0e86720a63a2a71b8c7615bf 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h @@ -850,6 +850,9 @@ #define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0) +#define RTS5227_DEVICE_ID 0x5227 +#define RTS_MAX_TIMES_FREQ_REDUCTION 8 + struct rtsx_pcr; struct pcr_handle { @@ -957,6 +960,8 @@ struct rtsx_pcr { int num_slots; struct rtsx_slot *slots; + + u8 dma_error_count; }; #define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid))