11// SPDX-License-Identifier: GPL-2.0
22
3+ /*
4+ * Copyright (C) 2020-2021 NVIDIA CORPORATION & AFFILIATES
5+ */
6+
37#include <linux/bitfield.h>
48#include <linux/bitops.h>
59#include <linux/device.h>
610#include <linux/gpio/driver.h>
11+ #include <linux/interrupt.h>
712#include <linux/io.h>
813#include <linux/ioport.h>
914#include <linux/kernel.h>
4348#define YU_GPIO_MODE0 0x0c
4449#define YU_GPIO_DATASET 0x14
4550#define YU_GPIO_DATACLEAR 0x18
51+ #define YU_GPIO_CAUSE_RISE_EN 0x44
52+ #define YU_GPIO_CAUSE_FALL_EN 0x48
4653#define YU_GPIO_MODE1_CLEAR 0x50
4754#define YU_GPIO_MODE0_SET 0x54
4855#define YU_GPIO_MODE0_CLEAR 0x58
56+ #define YU_GPIO_CAUSE_OR_CAUSE_EVTEN0 0x80
57+ #define YU_GPIO_CAUSE_OR_EVTEN0 0x94
58+ #define YU_GPIO_CAUSE_OR_CLRCAUSE 0x98
4959
5060struct mlxbf2_gpio_context_save_regs {
5161 u32 gpio_mode0 ;
@@ -55,6 +65,7 @@ struct mlxbf2_gpio_context_save_regs {
5565/* BlueField-2 gpio block context structure. */
5666struct mlxbf2_gpio_context {
5767 struct gpio_chip gc ;
68+ struct irq_chip irq_chip ;
5869
5970 /* YU GPIO blocks address */
6071 void __iomem * gpio_io ;
@@ -218,15 +229,114 @@ static int mlxbf2_gpio_direction_output(struct gpio_chip *chip,
218229 return ret ;
219230}
220231
232+ static void mlxbf2_gpio_irq_enable (struct irq_data * irqd )
233+ {
234+ struct gpio_chip * gc = irq_data_get_irq_chip_data (irqd );
235+ struct mlxbf2_gpio_context * gs = gpiochip_get_data (gc );
236+ int offset = irqd_to_hwirq (irqd );
237+ unsigned long flags ;
238+ u32 val ;
239+
240+ spin_lock_irqsave (& gs -> gc .bgpio_lock , flags );
241+ val = readl (gs -> gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE );
242+ val |= BIT (offset );
243+ writel (val , gs -> gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE );
244+
245+ val = readl (gs -> gpio_io + YU_GPIO_CAUSE_OR_EVTEN0 );
246+ val |= BIT (offset );
247+ writel (val , gs -> gpio_io + YU_GPIO_CAUSE_OR_EVTEN0 );
248+ spin_unlock_irqrestore (& gs -> gc .bgpio_lock , flags );
249+ }
250+
251+ static void mlxbf2_gpio_irq_disable (struct irq_data * irqd )
252+ {
253+ struct gpio_chip * gc = irq_data_get_irq_chip_data (irqd );
254+ struct mlxbf2_gpio_context * gs = gpiochip_get_data (gc );
255+ int offset = irqd_to_hwirq (irqd );
256+ unsigned long flags ;
257+ u32 val ;
258+
259+ spin_lock_irqsave (& gs -> gc .bgpio_lock , flags );
260+ val = readl (gs -> gpio_io + YU_GPIO_CAUSE_OR_EVTEN0 );
261+ val &= ~BIT (offset );
262+ writel (val , gs -> gpio_io + YU_GPIO_CAUSE_OR_EVTEN0 );
263+ spin_unlock_irqrestore (& gs -> gc .bgpio_lock , flags );
264+ }
265+
266+ static irqreturn_t mlxbf2_gpio_irq_handler (int irq , void * ptr )
267+ {
268+ struct mlxbf2_gpio_context * gs = ptr ;
269+ struct gpio_chip * gc = & gs -> gc ;
270+ unsigned long pending ;
271+ u32 level ;
272+
273+ pending = readl (gs -> gpio_io + YU_GPIO_CAUSE_OR_CAUSE_EVTEN0 );
274+ writel (pending , gs -> gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE );
275+
276+ for_each_set_bit (level , & pending , gc -> ngpio ) {
277+ int gpio_irq = irq_find_mapping (gc -> irq .domain , level );
278+ generic_handle_irq (gpio_irq );
279+ }
280+
281+ return IRQ_RETVAL (pending );
282+ }
283+
284+ static int
285+ mlxbf2_gpio_irq_set_type (struct irq_data * irqd , unsigned int type )
286+ {
287+ struct gpio_chip * gc = irq_data_get_irq_chip_data (irqd );
288+ struct mlxbf2_gpio_context * gs = gpiochip_get_data (gc );
289+ int offset = irqd_to_hwirq (irqd );
290+ unsigned long flags ;
291+ bool fall = false;
292+ bool rise = false;
293+ u32 val ;
294+
295+ switch (type & IRQ_TYPE_SENSE_MASK ) {
296+ case IRQ_TYPE_EDGE_BOTH :
297+ fall = true;
298+ rise = true;
299+ break ;
300+ case IRQ_TYPE_EDGE_RISING :
301+ rise = true;
302+ break ;
303+ case IRQ_TYPE_EDGE_FALLING :
304+ fall = true;
305+ break ;
306+ default :
307+ return - EINVAL ;
308+ }
309+
310+ spin_lock_irqsave (& gs -> gc .bgpio_lock , flags );
311+ if (fall ) {
312+ val = readl (gs -> gpio_io + YU_GPIO_CAUSE_FALL_EN );
313+ val |= BIT (offset );
314+ writel (val , gs -> gpio_io + YU_GPIO_CAUSE_FALL_EN );
315+ }
316+
317+ if (rise ) {
318+ val = readl (gs -> gpio_io + YU_GPIO_CAUSE_RISE_EN );
319+ val |= BIT (offset );
320+ writel (val , gs -> gpio_io + YU_GPIO_CAUSE_RISE_EN );
321+ }
322+ spin_unlock_irqrestore (& gs -> gc .bgpio_lock , flags );
323+
324+ return 0 ;
325+ }
326+
221327/* BlueField-2 GPIO driver initialization routine. */
222328static int
223329mlxbf2_gpio_probe (struct platform_device * pdev )
224330{
225331 struct mlxbf2_gpio_context * gs ;
226332 struct device * dev = & pdev -> dev ;
333+ struct gpio_irq_chip * girq ;
227334 struct gpio_chip * gc ;
228335 unsigned int npins ;
229- int ret ;
336+ const char * name ;
337+ int ret , irq ;
338+
339+ name = dev_name (dev );
230340
231341 gs = devm_kzalloc (dev , sizeof (* gs ), GFP_KERNEL );
232342 if (!gs )
@@ -261,6 +371,34 @@ mlxbf2_gpio_probe(struct platform_device *pdev)
261371 gc -> ngpio = npins ;
262372 gc -> owner = THIS_MODULE ;
263373
374+ irq = platform_get_irq (pdev , 0 );
375+ if (irq >= 0 ) {
376+ gs -> irq_chip .name = name ;
377+ gs -> irq_chip .irq_set_type = mlxbf2_gpio_irq_set_type ;
378+ gs -> irq_chip .irq_enable = mlxbf2_gpio_irq_enable ;
379+ gs -> irq_chip .irq_disable = mlxbf2_gpio_irq_disable ;
380+
381+ girq = & gs -> gc .irq ;
382+ girq -> chip = & gs -> irq_chip ;
383+ girq -> handler = handle_simple_irq ;
384+ girq -> default_type = IRQ_TYPE_NONE ;
385+ /* This will let us handle the parent IRQ in the driver */
386+ girq -> num_parents = 0 ;
387+ girq -> parents = NULL ;
388+ girq -> parent_handler = NULL ;
389+
390+ /*
391+ * Directly request the irq here instead of passing
392+ * a flow-handler because the irq is shared.
393+ */
394+ ret = devm_request_irq (dev , irq , mlxbf2_gpio_irq_handler ,
395+ IRQF_SHARED , name , gs );
396+ if (ret ) {
397+ dev_err (dev , "failed to request IRQ" );
398+ return ret ;
399+ }
400+ }
401+
264402 platform_set_drvdata (pdev , gs );
265403
266404 ret = devm_gpiochip_add_data (dev , & gs -> gc , gs );
@@ -315,5 +453,5 @@ static struct platform_driver mlxbf2_gpio_driver = {
315453module_platform_driver (mlxbf2_gpio_driver );
316454
317455MODULE_DESCRIPTION ("Mellanox BlueField-2 GPIO Driver" );
318- MODULE_AUTHOR ("Mellanox Technologies " );
456+ MODULE_AUTHOR ("Asmaa Mnebhi <asmaa@nvidia.com> " );
319457MODULE_LICENSE ("GPL v2" );
0 commit comments