Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.2-rc5 176 lines 4.0 kB view raw
1#include <linux/kernel.h> 2#include <linux/init.h> 3#include <linux/gpio.h> 4#include <linux/of_gpio.h> 5#include <linux/io.h> 6#include <linux/platform_device.h> 7#include <linux/basic_mmio_gpio.h> 8 9#define ETRAX_FS_rw_pa_dout 0 10#define ETRAX_FS_r_pa_din 4 11#define ETRAX_FS_rw_pa_oe 8 12#define ETRAX_FS_rw_intr_cfg 12 13#define ETRAX_FS_rw_intr_mask 16 14#define ETRAX_FS_rw_ack_intr 20 15#define ETRAX_FS_r_intr 24 16#define ETRAX_FS_rw_pb_dout 32 17#define ETRAX_FS_r_pb_din 36 18#define ETRAX_FS_rw_pb_oe 40 19#define ETRAX_FS_rw_pc_dout 48 20#define ETRAX_FS_r_pc_din 52 21#define ETRAX_FS_rw_pc_oe 56 22#define ETRAX_FS_rw_pd_dout 64 23#define ETRAX_FS_r_pd_din 68 24#define ETRAX_FS_rw_pd_oe 72 25#define ETRAX_FS_rw_pe_dout 80 26#define ETRAX_FS_r_pe_din 84 27#define ETRAX_FS_rw_pe_oe 88 28 29struct etraxfs_gpio_port { 30 const char *label; 31 unsigned int oe; 32 unsigned int dout; 33 unsigned int din; 34 unsigned int ngpio; 35}; 36 37struct etraxfs_gpio_info { 38 unsigned int num_ports; 39 const struct etraxfs_gpio_port *ports; 40}; 41 42static const struct etraxfs_gpio_port etraxfs_gpio_etraxfs_ports[] = { 43 { 44 .label = "A", 45 .ngpio = 8, 46 .oe = ETRAX_FS_rw_pa_oe, 47 .dout = ETRAX_FS_rw_pa_dout, 48 .din = ETRAX_FS_r_pa_din, 49 }, 50 { 51 .label = "B", 52 .ngpio = 18, 53 .oe = ETRAX_FS_rw_pb_oe, 54 .dout = ETRAX_FS_rw_pb_dout, 55 .din = ETRAX_FS_r_pb_din, 56 }, 57 { 58 .label = "C", 59 .ngpio = 18, 60 .oe = ETRAX_FS_rw_pc_oe, 61 .dout = ETRAX_FS_rw_pc_dout, 62 .din = ETRAX_FS_r_pc_din, 63 }, 64 { 65 .label = "D", 66 .ngpio = 18, 67 .oe = ETRAX_FS_rw_pd_oe, 68 .dout = ETRAX_FS_rw_pd_dout, 69 .din = ETRAX_FS_r_pd_din, 70 }, 71 { 72 .label = "E", 73 .ngpio = 18, 74 .oe = ETRAX_FS_rw_pe_oe, 75 .dout = ETRAX_FS_rw_pe_dout, 76 .din = ETRAX_FS_r_pe_din, 77 }, 78}; 79 80static const struct etraxfs_gpio_info etraxfs_gpio_etraxfs = { 81 .num_ports = ARRAY_SIZE(etraxfs_gpio_etraxfs_ports), 82 .ports = etraxfs_gpio_etraxfs_ports, 83}; 84 85static int etraxfs_gpio_of_xlate(struct gpio_chip *gc, 86 const struct of_phandle_args *gpiospec, 87 u32 *flags) 88{ 89 /* 90 * Port numbers are A to E, and the properties are integers, so we 91 * specify them as 0xA - 0xE. 92 */ 93 if (gc->label[0] - 'A' + 0xA != gpiospec->args[2]) 94 return -EINVAL; 95 96 return of_gpio_simple_xlate(gc, gpiospec, flags); 97} 98 99static const struct of_device_id etraxfs_gpio_of_table[] = { 100 { 101 .compatible = "axis,etraxfs-gio", 102 .data = &etraxfs_gpio_etraxfs, 103 }, 104 {}, 105}; 106 107static int etraxfs_gpio_probe(struct platform_device *pdev) 108{ 109 struct device *dev = &pdev->dev; 110 const struct etraxfs_gpio_info *info; 111 const struct of_device_id *match; 112 struct bgpio_chip *chips; 113 struct resource *res; 114 void __iomem *regs; 115 int ret; 116 int i; 117 118 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 119 regs = devm_ioremap_resource(dev, res); 120 if (!regs) 121 return -ENOMEM; 122 123 match = of_match_node(etraxfs_gpio_of_table, dev->of_node); 124 if (!match) 125 return -EINVAL; 126 127 info = match->data; 128 129 chips = devm_kzalloc(dev, sizeof(*chips) * info->num_ports, GFP_KERNEL); 130 if (!chips) 131 return -ENOMEM; 132 133 for (i = 0; i < info->num_ports; i++) { 134 struct bgpio_chip *bgc = &chips[i]; 135 const struct etraxfs_gpio_port *port = &info->ports[i]; 136 137 ret = bgpio_init(bgc, dev, 4, 138 regs + port->din, /* dat */ 139 regs + port->dout, /* set */ 140 NULL, /* clr */ 141 regs + port->oe, /* dirout */ 142 NULL, /* dirin */ 143 BGPIOF_UNREADABLE_REG_SET); 144 if (ret) 145 return ret; 146 147 bgc->gc.ngpio = port->ngpio; 148 bgc->gc.label = port->label; 149 150 bgc->gc.of_node = dev->of_node; 151 bgc->gc.of_gpio_n_cells = 3; 152 bgc->gc.of_xlate = etraxfs_gpio_of_xlate; 153 154 ret = gpiochip_add(&bgc->gc); 155 if (ret) 156 dev_err(dev, "Unable to register port %s\n", 157 bgc->gc.label); 158 } 159 160 return 0; 161} 162 163static struct platform_driver etraxfs_gpio_driver = { 164 .driver = { 165 .name = "etraxfs-gpio", 166 .of_match_table = of_match_ptr(etraxfs_gpio_of_table), 167 }, 168 .probe = etraxfs_gpio_probe, 169}; 170 171static int __init etraxfs_gpio_init(void) 172{ 173 return platform_driver_register(&etraxfs_gpio_driver); 174} 175 176device_initcall(etraxfs_gpio_init);