2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 2011, 2012 Cavium Inc.
9 #include <linux/platform_device.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/gpio/driver.h>
15 #include <asm/octeon/octeon.h>
16 #include <asm/octeon/cvmx-gpio-defs.h>
22 * The address offset of the GPIO configuration register for a given
25 static unsigned int bit_cfg_reg(unsigned int offset
)
28 * The register stride is 8, with a discontinuity after the
34 return 8 * (offset
- 16) + 0x100;
38 struct gpio_chip chip
;
42 static int octeon_gpio_dir_in(struct gpio_chip
*chip
, unsigned offset
)
44 struct octeon_gpio
*gpio
= gpiochip_get_data(chip
);
46 cvmx_write_csr(gpio
->register_base
+ bit_cfg_reg(offset
), 0);
50 static void octeon_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
52 struct octeon_gpio
*gpio
= gpiochip_get_data(chip
);
53 u64 mask
= 1ull << offset
;
54 u64 reg
= gpio
->register_base
+ (value
? TX_SET
: TX_CLEAR
);
55 cvmx_write_csr(reg
, mask
);
58 static int octeon_gpio_dir_out(struct gpio_chip
*chip
, unsigned offset
,
61 struct octeon_gpio
*gpio
= gpiochip_get_data(chip
);
62 union cvmx_gpio_bit_cfgx cfgx
;
64 octeon_gpio_set(chip
, offset
, value
);
69 cvmx_write_csr(gpio
->register_base
+ bit_cfg_reg(offset
), cfgx
.u64
);
73 static int octeon_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
75 struct octeon_gpio
*gpio
= gpiochip_get_data(chip
);
76 u64 read_bits
= cvmx_read_csr(gpio
->register_base
+ RX_DAT
);
78 return ((1ull << offset
) & read_bits
) != 0;
81 static int octeon_gpio_probe(struct platform_device
*pdev
)
83 struct octeon_gpio
*gpio
;
84 struct gpio_chip
*chip
;
85 struct resource
*res_mem
;
86 void __iomem
*reg_base
;
89 gpio
= devm_kzalloc(&pdev
->dev
, sizeof(*gpio
), GFP_KERNEL
);
94 res_mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
95 reg_base
= devm_ioremap_resource(&pdev
->dev
, res_mem
);
97 return PTR_ERR(reg_base
);
99 gpio
->register_base
= (u64
)reg_base
;
100 pdev
->dev
.platform_data
= chip
;
101 chip
->label
= "octeon-gpio";
102 chip
->parent
= &pdev
->dev
;
103 chip
->owner
= THIS_MODULE
;
105 chip
->can_sleep
= false;
107 chip
->direction_input
= octeon_gpio_dir_in
;
108 chip
->get
= octeon_gpio_get
;
109 chip
->direction_output
= octeon_gpio_dir_out
;
110 chip
->set
= octeon_gpio_set
;
111 err
= devm_gpiochip_add_data(&pdev
->dev
, chip
, gpio
);
115 dev_info(&pdev
->dev
, "OCTEON GPIO driver probed.\n");
119 static const struct of_device_id octeon_gpio_match
[] = {
121 .compatible
= "cavium,octeon-3860-gpio",
125 MODULE_DEVICE_TABLE(of
, octeon_gpio_match
);
127 static struct platform_driver octeon_gpio_driver
= {
129 .name
= "octeon_gpio",
130 .of_match_table
= octeon_gpio_match
,
132 .probe
= octeon_gpio_probe
,
135 module_platform_driver(octeon_gpio_driver
);
137 MODULE_DESCRIPTION("Cavium Inc. OCTEON GPIO Driver");
138 MODULE_AUTHOR("David Daney");
139 MODULE_LICENSE("GPL");