342604a4bb
* [Mellanox] Don't populate arm64 Kconfig when integrating hw-mgmt
Signed-off-by: Vivek Reddy <vkarri@nvidia.com>
* Intgerate HW-MGMT 7.0030.2008 Changes
## Patch List
* 0285-UBUNTU-SAUCE-mlxbf-gige-Fix-intermittent-no-ip-issue.patch :
* 0286-pinctrl-Introduce-struct-pinfunction-and-PINCTRL_PIN.patch :
* 0287-pinctrl-mlxbf3-Add-pinctrl-driver-support.patch :
* 0288-UBUNTU-SAUCE-gpio-mmio-handle-ngpios-properly-in-bgp.patch :
* 0289-UBUNTU-SAUCE-gpio-mlxbf3-Add-gpio-driver-support.patch :
* 0291-mlxsw-core_hwmon-Align-modules-label-name-assignment.patch :
* 0292-mlxsw-i2c-Limit-single-transaction-buffer-size.patch :
* 0293-mlxsw-reg-Limit-MTBR-register-records-buffer-by-one-.patch :
* 0296-UBUNTU-SAUCE-mmc-sdhci-of-dwcmshc-Add-runtime-PM-ope.patch :
* 0298-UBUNTU-SAUCE-mlxbf-ptm-use-0444-instead-of-S_IRUGO.patch :
* 0299-UBUNTU-SAUCE-mlxbf-ptm-add-atx-debugfs-nodes.patch :
* 0300-UBUNTU-SAUCE-mlxbf-ptm-update-module-version.patch :
* 0301-UBUNTU-SAUCE-mlxbf-gige-Fix-kernel-panic-at-shutdown.patch :
* 0302-UBUNTU-SAUCE-mlxbf-bootctl-support-SMC-call-for-sett.patch :
* 0303-UBUNTU-SAUCE-Add-BF3-related-ACPI-config-and-Ring-de.patch :
* 0306-dt-bindings-trivial-devices-Add-infineon-xdpe1a2g7.patch :
* 0307-leds-mlxreg-Add-support-for-new-flavour-of-capabilit.patch :
* 0308-leds-mlxreg-Remove-code-for-amber-LED-colour.patch :
* 0308-platform_data-mlxreg-Add-capability-bit-and-mask-fie.patch :
* 0309-hwmon-mlxreg-fan-Add-support-for-new-flavour-of-capa.patch :
* 0310-hwmon-mlxreg-fan-Extend-number-of-supporetd-fans.patch :
* 0317-platform-mellanox-Introduce-support-for-switches-equ.patch :
* 0318-mellanox-Relocate-mlx-platform-driver.patch :
* 0319-UBUNTU-SAUCE-mlxbf-tmfifo-fix-potential-race.patch :
* 0320-UBUNTU-SAUCE-mlxbf-tmfifo-Drop-the-Rx-packet-if-no-m.patch :
* 0321-UBUNTU-SAUCE-mlxbf-tmfifo-Drop-jumbo-frames.patch :
* 0322-UBUNTU-SAUCE-mlxbf-tmfifo.c-Amend-previous-tmfifo-pa.patch :
* 0323-mlxbf_gige-add-set_link_ksettings-ethtool-callback.patch :
* 0324-mlxbf_gige-fix-white-space-in-mlxbf_gige_eth_ioctl.patch :
* 0325-UBUNTU-SAUCE-mlxbf-bootctl-Fix-kernel-panic-due-to-b.patch :
* 0326-platform-mellanox-mlxreg-hotplug-Add-support-for-new.patch :
* 0327-platform-mellanox-mlx-platform-Change-register-name.patch :
* 0328-platform-mellanox-mlx-platform-Add-support-for-new-X.patch :
* [Mellanox] Remove thermal zone related code and replace with new one
* Revert "Revert "[Mellanox] Align PSU temperature sysfs node name with hw-management change (#16820)" (#16956)"
This reverts commit c2edc6f9d5
.
---------
Signed-off-by: Vivek Reddy <vkarri@nvidia.com>
Co-authored-by: Junchao-Mellanox <junchao@nvidia.com>
Co-authored-by: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com>
489 lines
15 KiB
Diff
489 lines
15 KiB
Diff
From d189171aa3b9e01b2e2d022f375f999a4a68d525 Mon Sep 17 00:00:00 2001
|
|
From: Asmaa Mnebhi <asmaa@nvidia.com>
|
|
Date: Thu, 30 Mar 2023 12:38:19 -0400
|
|
Subject: [PATCH 77/77] UBUNTU: SAUCE: gpio: mlxbf3: Add gpio driver support
|
|
X-NVConfidentiality: public
|
|
|
|
BugLink: https://bugs.launchpad.net/bugs/2012743
|
|
|
|
Add support for the BlueField-3 SoC GPIO driver.
|
|
This driver configures and handles GPIO interrupts. It also enables
|
|
a user to manipulate certain GPIO pins via libgpiod tools or other kernel drivers.
|
|
|
|
The gpio-mlxbf3.c driver has already been approved for upstreaming
|
|
but is not yet available for cherry-picking.
|
|
|
|
Signed-off-by: Asmaa Mnebhi <asmaa@nvidia.com>
|
|
Acked-by: Tim Gardner <tim.gardner@canonical.com>
|
|
Acked-by: Bartlomiej Zolnierkiewicz <bartlomiej.zolnierkiewicz@canonical.com>
|
|
Signed-off-by: Bartlomiej Zolnierkiewicz <bartlomiej.zolnierkiewicz@canonical.com>
|
|
---
|
|
drivers/gpio/Kconfig | 10 +-
|
|
drivers/gpio/gpio-mlxbf3.c | 285 +++++++++++++++++----------------------------
|
|
2 files changed, 116 insertions(+), 179 deletions(-)
|
|
|
|
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
|
|
index bf1b2b787..a31b7ffea 100644
|
|
--- a/drivers/gpio/Kconfig
|
|
+++ b/drivers/gpio/Kconfig
|
|
@@ -1461,10 +1461,16 @@ config GPIO_MLXBF2
|
|
|
|
config GPIO_MLXBF3
|
|
tristate "Mellanox BlueField 3 SoC GPIO"
|
|
- depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || (64BIT && COMPILE_TEST)
|
|
+ depends on (MELLANOX_PLATFORM && ARM64) || COMPILE_TEST
|
|
select GPIO_GENERIC
|
|
+ select GPIOLIB_IRQCHIP
|
|
help
|
|
- Say Y here if you want GPIO support on Mellanox BlueField 3 SoC.
|
|
+ Say Y if you want GPIO support on Mellanox BlueField 3 SoC.
|
|
+ This GPIO controller supports interrupt handling and enables the
|
|
+ manipulation of certain GPIO pins.
|
|
+ This controller should be used in parallel with pinctrl-mlxbf3 to
|
|
+ control the desired GPIOs.
|
|
+ This driver can also be built as a module called mlxbf3-gpio.
|
|
|
|
config GPIO_ML_IOH
|
|
tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
|
|
diff --git a/drivers/gpio/gpio-mlxbf3.c b/drivers/gpio/gpio-mlxbf3.c
|
|
index 45f0946ac..51dce3ae1 100644
|
|
--- a/drivers/gpio/gpio-mlxbf3.c
|
|
+++ b/drivers/gpio/gpio-mlxbf3.c
|
|
@@ -1,27 +1,20 @@
|
|
// SPDX-License-Identifier: GPL-2.0-only or BSD-3-Clause
|
|
+/* Copyright (C) 2021-2023 NVIDIA CORPORATION & AFFILIATES */
|
|
|
|
-/*
|
|
- * Copyright (C) 2020-2021 NVIDIA CORPORATION & AFFILIATES
|
|
- */
|
|
-
|
|
-#include <linux/acpi.h>
|
|
#include <linux/bitfield.h>
|
|
#include <linux/bitops.h>
|
|
#include <linux/device.h>
|
|
+#include <linux/err.h>
|
|
#include <linux/gpio/driver.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/io.h>
|
|
-#include <linux/ioport.h>
|
|
-#include <linux/kernel.h>
|
|
-#include <linux/mod_devicetable.h>
|
|
#include <linux/module.h>
|
|
#include <linux/platform_device.h>
|
|
-#include <linux/pm.h>
|
|
-#include <linux/resource.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/types.h>
|
|
+#include <linux/version.h>
|
|
|
|
-#define DRV_VERSION "1.0"
|
|
+#define DRV_VERSION "2.0"
|
|
|
|
/*
|
|
* There are 2 YU GPIO blocks:
|
|
@@ -33,103 +26,51 @@
|
|
/*
|
|
* fw_gpio[x] block registers and their offset
|
|
*/
|
|
-#define YU_GPIO_FW_CONTROL_SET 0x00
|
|
-#define YU_GPIO_FW_OUTPUT_ENABLE_SET 0x04
|
|
-#define YU_GPIO_FW_DATA_OUT_SET 0x08
|
|
-#define YU_GPIO_FW_CONTROL_CLEAR 0x14
|
|
-#define YU_GPIO_FW_OUTPUT_ENABLE_CLEAR 0x18
|
|
-#define YU_GPIO_FW_DATA_OUT_CLEAR 0x1c
|
|
-#define YU_GPIO_CAUSE_RISE_EN 0x28
|
|
-#define YU_GPIO_CAUSE_FALL_EN 0x2c
|
|
-#define YU_GPIO_READ_DATA_IN 0x30
|
|
-#define YU_GPIO_READ_OUTPUT_ENABLE 0x34
|
|
-#define YU_GPIO_READ_DATA_OUT 0x38
|
|
-#define YU_GPIO_READ_FW_CONTROL 0x44
|
|
-
|
|
-#define YU_GPIO_CAUSE_OR_CAUSE_EVTEN0 0x00
|
|
-#define YU_GPIO_CAUSE_OR_EVTEN0 0x14
|
|
-#define YU_GPIO_CAUSE_OR_CLRCAUSE 0x18
|
|
-
|
|
-/* BlueField-3 gpio block context structure. */
|
|
+#define MLXBF_GPIO_FW_OUTPUT_ENABLE_SET 0x00
|
|
+#define MLXBF_GPIO_FW_DATA_OUT_SET 0x04
|
|
+
|
|
+#define MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR 0x00
|
|
+#define MLXBF_GPIO_FW_DATA_OUT_CLEAR 0x04
|
|
+
|
|
+#define MLXBF_GPIO_CAUSE_RISE_EN 0x00
|
|
+#define MLXBF_GPIO_CAUSE_FALL_EN 0x04
|
|
+#define MLXBF_GPIO_READ_DATA_IN 0x08
|
|
+
|
|
+#define MLXBF_GPIO_CAUSE_OR_CAUSE_EVTEN0 0x00
|
|
+#define MLXBF_GPIO_CAUSE_OR_EVTEN0 0x14
|
|
+#define MLXBF_GPIO_CAUSE_OR_CLRCAUSE 0x18
|
|
+
|
|
struct mlxbf3_gpio_context {
|
|
struct gpio_chip gc;
|
|
- struct irq_chip irq_chip;
|
|
|
|
- /* YU GPIO blocks address */
|
|
+ /* YU GPIO block address */
|
|
+ void __iomem *gpio_set_io;
|
|
+ void __iomem *gpio_clr_io;
|
|
void __iomem *gpio_io;
|
|
|
|
/* YU GPIO cause block address */
|
|
void __iomem *gpio_cause_io;
|
|
|
|
- uint32_t ctrl_gpio_mask;
|
|
+ /* Mask of valid gpios that can be accessed by software */
|
|
+ unsigned int valid_mask;
|
|
};
|
|
|
|
-static void mlxbf3_gpio_set(struct gpio_chip *chip, unsigned int offset, int val)
|
|
-{
|
|
- struct mlxbf3_gpio_context *gs = gpiochip_get_data(chip);
|
|
-
|
|
- /* Software can only control GPIO pins defined by ctrl_gpio_mask */
|
|
- if (!(BIT(offset) & gs->ctrl_gpio_mask))
|
|
- return;
|
|
-
|
|
- if (val) {
|
|
- writel(BIT(offset), gs->gpio_io + YU_GPIO_FW_DATA_OUT_SET);
|
|
- } else {
|
|
- writel(BIT(offset), gs->gpio_io + YU_GPIO_FW_DATA_OUT_CLEAR);
|
|
- }
|
|
-
|
|
- wmb();
|
|
-
|
|
- /* This needs to be done last to avoid glitches */
|
|
- writel(BIT(offset), gs->gpio_io + YU_GPIO_FW_CONTROL_SET);
|
|
-}
|
|
-
|
|
-static int mlxbf3_gpio_direction_input(struct gpio_chip *chip,
|
|
- unsigned int offset)
|
|
-{
|
|
- struct mlxbf3_gpio_context *gs = gpiochip_get_data(chip);
|
|
- unsigned long flags;
|
|
-
|
|
- spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
|
|
-
|
|
- writel(BIT(offset), gs->gpio_io + YU_GPIO_FW_OUTPUT_ENABLE_CLEAR);
|
|
- writel(BIT(offset), gs->gpio_io + YU_GPIO_FW_CONTROL_CLEAR);
|
|
-
|
|
- spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static int mlxbf3_gpio_direction_output(struct gpio_chip *chip,
|
|
- unsigned int offset,
|
|
- int value)
|
|
-{
|
|
- struct mlxbf3_gpio_context *gs = gpiochip_get_data(chip);
|
|
- unsigned long flags;
|
|
-
|
|
- spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
|
|
-
|
|
- writel(BIT(offset), gs->gpio_io + YU_GPIO_FW_OUTPUT_ENABLE_SET);
|
|
-
|
|
- spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
static void mlxbf3_gpio_irq_enable(struct irq_data *irqd)
|
|
{
|
|
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
|
|
struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
|
|
- int offset = irqd_to_hwirq(irqd);
|
|
+ irq_hw_number_t offset = irqd_to_hwirq(irqd);
|
|
unsigned long flags;
|
|
u32 val;
|
|
|
|
+ gpiochip_enable_irq(gc, offset);
|
|
+
|
|
spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
|
|
- writel(BIT(offset), gs->gpio_cause_io + YU_GPIO_CAUSE_OR_CLRCAUSE);
|
|
+ writel(BIT(offset), gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
|
|
|
|
- val = readl(gs->gpio_cause_io + YU_GPIO_CAUSE_OR_EVTEN0);
|
|
+ val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
|
|
val |= BIT(offset);
|
|
- writel(val, gs->gpio_cause_io + YU_GPIO_CAUSE_OR_EVTEN0);
|
|
+ writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
|
|
spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
|
|
}
|
|
|
|
@@ -137,15 +78,17 @@ static void mlxbf3_gpio_irq_disable(struct irq_data *irqd)
|
|
{
|
|
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
|
|
struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
|
|
- int offset = irqd_to_hwirq(irqd);
|
|
+ irq_hw_number_t offset = irqd_to_hwirq(irqd);
|
|
unsigned long flags;
|
|
u32 val;
|
|
|
|
spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
|
|
- val = readl(gs->gpio_cause_io + YU_GPIO_CAUSE_OR_EVTEN0);
|
|
+ val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
|
|
val &= ~BIT(offset);
|
|
- writel(val, gs->gpio_cause_io + YU_GPIO_CAUSE_OR_EVTEN0);
|
|
+ writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
|
|
spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
|
|
+
|
|
+ gpiochip_disable_irq(gc, offset);
|
|
}
|
|
|
|
static irqreturn_t mlxbf3_gpio_irq_handler(int irq, void *ptr)
|
|
@@ -155,8 +98,8 @@ static irqreturn_t mlxbf3_gpio_irq_handler(int irq, void *ptr)
|
|
unsigned long pending;
|
|
u32 level;
|
|
|
|
- pending = readl(gs->gpio_cause_io + YU_GPIO_CAUSE_OR_CAUSE_EVTEN0);
|
|
- writel(pending, gs->gpio_cause_io + YU_GPIO_CAUSE_OR_CLRCAUSE);
|
|
+ pending = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CAUSE_EVTEN0);
|
|
+ writel(pending, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
|
|
|
|
for_each_set_bit(level, &pending, gc->ngpio) {
|
|
int gpio_irq = irq_find_mapping(gc->irq.domain, level);
|
|
@@ -171,155 +114,145 @@ mlxbf3_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
|
|
{
|
|
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
|
|
struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
|
|
- int offset = irqd_to_hwirq(irqd);
|
|
+ irq_hw_number_t offset = irqd_to_hwirq(irqd);
|
|
unsigned long flags;
|
|
- bool fall = false;
|
|
- bool rise = false;
|
|
u32 val;
|
|
|
|
+ spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
|
|
+
|
|
switch (type & IRQ_TYPE_SENSE_MASK) {
|
|
case IRQ_TYPE_EDGE_BOTH:
|
|
- fall = true;
|
|
- rise = true;
|
|
+ val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
|
|
+ val |= BIT(offset);
|
|
+ writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
|
|
+ val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
|
|
+ val |= BIT(offset);
|
|
+ writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
|
|
break;
|
|
case IRQ_TYPE_EDGE_RISING:
|
|
- rise = true;
|
|
+ val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
|
|
+ val |= BIT(offset);
|
|
+ writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
|
|
break;
|
|
case IRQ_TYPE_EDGE_FALLING:
|
|
- fall = true;
|
|
+ val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
|
|
+ val |= BIT(offset);
|
|
+ writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
|
|
break;
|
|
default:
|
|
+ spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
|
|
return -EINVAL;
|
|
}
|
|
|
|
- spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
|
|
- if (fall) {
|
|
- val = readl(gs->gpio_io + YU_GPIO_CAUSE_FALL_EN);
|
|
- val |= BIT(offset);
|
|
- writel(val, gs->gpio_io + YU_GPIO_CAUSE_FALL_EN);
|
|
- }
|
|
-
|
|
- if (rise) {
|
|
- val = readl(gs->gpio_io + YU_GPIO_CAUSE_RISE_EN);
|
|
- val |= BIT(offset);
|
|
- writel(val, gs->gpio_io + YU_GPIO_CAUSE_RISE_EN);
|
|
- }
|
|
spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
|
|
|
|
+ irq_set_handler_locked(irqd, handle_edge_irq);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
-/* BlueField-3 GPIO driver initialization routine. */
|
|
-static int
|
|
-mlxbf3_gpio_probe(struct platform_device *pdev)
|
|
+/* This function needs to be defined for handle_edge_irq() */
|
|
+static void mlxbf3_gpio_irq_ack(struct irq_data *data)
|
|
+{
|
|
+}
|
|
+
|
|
+static int mlxbf3_gpio_init_valid_mask(struct gpio_chip *gc,
|
|
+ unsigned long *valid_mask,
|
|
+ unsigned int ngpios)
|
|
+{
|
|
+ struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
|
|
+
|
|
+ *valid_mask = gs->valid_mask;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct irq_chip gpio_mlxbf3_irqchip = {
|
|
+ .name = "MLNXBF33",
|
|
+ .irq_ack = mlxbf3_gpio_irq_ack,
|
|
+ .irq_set_type = mlxbf3_gpio_irq_set_type,
|
|
+ .irq_enable = mlxbf3_gpio_irq_enable,
|
|
+ .irq_disable = mlxbf3_gpio_irq_disable,
|
|
+};
|
|
+
|
|
+static int mlxbf3_gpio_probe(struct platform_device *pdev)
|
|
{
|
|
- struct mlxbf3_gpio_context *gs;
|
|
struct device *dev = &pdev->dev;
|
|
+ struct mlxbf3_gpio_context *gs;
|
|
struct gpio_irq_chip *girq;
|
|
struct gpio_chip *gc;
|
|
- unsigned int npins;
|
|
- const char *name;
|
|
int ret, irq;
|
|
|
|
- name = dev_name(dev);
|
|
-
|
|
gs = devm_kzalloc(dev, sizeof(*gs), GFP_KERNEL);
|
|
if (!gs)
|
|
return -ENOMEM;
|
|
|
|
- /* YU GPIO block address */
|
|
gs->gpio_io = devm_platform_ioremap_resource(pdev, 0);
|
|
if (IS_ERR(gs->gpio_io))
|
|
return PTR_ERR(gs->gpio_io);
|
|
|
|
- /* YU GPIO block address */
|
|
gs->gpio_cause_io = devm_platform_ioremap_resource(pdev, 1);
|
|
if (IS_ERR(gs->gpio_cause_io))
|
|
return PTR_ERR(gs->gpio_cause_io);
|
|
|
|
- if (device_property_read_u32(dev, "npins", &npins))
|
|
- npins = MLXBF3_GPIO_MAX_PINS_PER_BLOCK;
|
|
+ gs->gpio_set_io = devm_platform_ioremap_resource(pdev, 2);
|
|
+ if (IS_ERR(gs->gpio_set_io))
|
|
+ return PTR_ERR(gs->gpio_set_io);
|
|
|
|
- if (device_property_read_u32(dev, "ctrl_gpio_mask", &gs->ctrl_gpio_mask))
|
|
- gs->ctrl_gpio_mask = 0x0;
|
|
+ gs->gpio_clr_io = devm_platform_ioremap_resource(pdev, 3);
|
|
+ if (IS_ERR(gs->gpio_clr_io))
|
|
+ return PTR_ERR(gs->gpio_clr_io);
|
|
+
|
|
+ gs->valid_mask = 0x0;
|
|
+ device_property_read_u32(dev, "valid_mask", &gs->valid_mask);
|
|
|
|
gc = &gs->gc;
|
|
|
|
- /* To set the direction to input, just give control to HW by setting
|
|
- * YU_GPIO_FW_CONTROL_CLEAR.
|
|
- * If the GPIO is controlled by HW, read its value via read_data_in register.
|
|
- *
|
|
- * When the direction = output, the GPIO is controlled by SW and
|
|
- * datain=dataout. If software modifies the value of the GPIO pin,
|
|
- * the value can be read from read_data_in without changing the direction.
|
|
- */
|
|
ret = bgpio_init(gc, dev, 4,
|
|
- gs->gpio_io + YU_GPIO_READ_DATA_IN,
|
|
- NULL,
|
|
- NULL,
|
|
- NULL,
|
|
- NULL,
|
|
- 0);
|
|
-
|
|
- gc->set = mlxbf3_gpio_set;
|
|
- gc->direction_input = mlxbf3_gpio_direction_input;
|
|
- gc->direction_output = mlxbf3_gpio_direction_output;
|
|
-
|
|
- gc->ngpio = npins;
|
|
+ gs->gpio_io + MLXBF_GPIO_READ_DATA_IN,
|
|
+ gs->gpio_set_io + MLXBF_GPIO_FW_DATA_OUT_SET,
|
|
+ gs->gpio_clr_io + MLXBF_GPIO_FW_DATA_OUT_CLEAR,
|
|
+ gs->gpio_set_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_SET,
|
|
+ gs->gpio_clr_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR, 0);
|
|
+
|
|
+ gc->request = gpiochip_generic_request;
|
|
+ gc->free = gpiochip_generic_free;
|
|
gc->owner = THIS_MODULE;
|
|
+ gc->init_valid_mask = mlxbf3_gpio_init_valid_mask;
|
|
|
|
irq = platform_get_irq(pdev, 0);
|
|
if (irq >= 0) {
|
|
- gs->irq_chip.name = name;
|
|
- gs->irq_chip.irq_set_type = mlxbf3_gpio_irq_set_type;
|
|
- gs->irq_chip.irq_enable = mlxbf3_gpio_irq_enable;
|
|
- gs->irq_chip.irq_disable = mlxbf3_gpio_irq_disable;
|
|
-
|
|
girq = &gs->gc.irq;
|
|
- girq->chip = &gs->irq_chip;
|
|
- girq->handler = handle_simple_irq;
|
|
+ girq->chip = &gpio_mlxbf3_irqchip;
|
|
girq->default_type = IRQ_TYPE_NONE;
|
|
/* This will let us handle the parent IRQ in the driver */
|
|
girq->num_parents = 0;
|
|
girq->parents = NULL;
|
|
girq->parent_handler = NULL;
|
|
+ girq->handler = handle_bad_irq;
|
|
|
|
/*
|
|
* Directly request the irq here instead of passing
|
|
* a flow-handler because the irq is shared.
|
|
*/
|
|
ret = devm_request_irq(dev, irq, mlxbf3_gpio_irq_handler,
|
|
- IRQF_SHARED, name, gs);
|
|
- if (ret) {
|
|
- dev_err(dev, "failed to request IRQ");
|
|
- return ret;
|
|
- }
|
|
+ IRQF_SHARED, dev_name(dev), gs);
|
|
+ if (ret)
|
|
+ return dev_err_probe(dev, ret, "failed to request IRQ");
|
|
}
|
|
|
|
platform_set_drvdata(pdev, gs);
|
|
|
|
ret = devm_gpiochip_add_data(dev, &gs->gc, gs);
|
|
- if (ret) {
|
|
- dev_err(dev, "Failed adding memory mapped gpiochip\n");
|
|
- return ret;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static int mlxbf3_gpio_remove(struct platform_device *pdev)
|
|
-{
|
|
- struct mlxbf3_gpio_context *gs = platform_get_drvdata(pdev);
|
|
-
|
|
- /* Set the GPIO control back to HW */
|
|
- writel(gs->ctrl_gpio_mask, gs->gpio_io + YU_GPIO_FW_CONTROL_CLEAR);
|
|
+ if (ret)
|
|
+ dev_err_probe(dev, ret, "Failed adding memory mapped gpiochip\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
-static const struct acpi_device_id __maybe_unused mlxbf3_gpio_acpi_match[] = {
|
|
+static const struct acpi_device_id mlxbf3_gpio_acpi_match[] = {
|
|
{ "MLNXBF33", 0 },
|
|
- {},
|
|
+ {}
|
|
};
|
|
MODULE_DEVICE_TABLE(acpi, mlxbf3_gpio_acpi_match);
|
|
|
|
@@ -329,12 +262,10 @@ static struct platform_driver mlxbf3_gpio_driver = {
|
|
.acpi_match_table = mlxbf3_gpio_acpi_match,
|
|
},
|
|
.probe = mlxbf3_gpio_probe,
|
|
- .remove = mlxbf3_gpio_remove,
|
|
};
|
|
-
|
|
module_platform_driver(mlxbf3_gpio_driver);
|
|
|
|
-MODULE_DESCRIPTION("Mellanox BlueField-3 GPIO Driver");
|
|
+MODULE_DESCRIPTION("NVIDIA BlueField-3 GPIO Driver");
|
|
MODULE_AUTHOR("Asmaa Mnebhi <asmaa@nvidia.com>");
|
|
MODULE_LICENSE("Dual BSD/GPL");
|
|
MODULE_VERSION(DRV_VERSION);
|
|
--
|
|
2.14.1
|
|
|