gpio-mxs.c (6161715e3f1adecae9e7c160930add4040fa10e9) | gpio-mxs.c (498c17cf6a935335c8652165cae5dc196340b3e9) |
---|---|
1/* 2 * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> 3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de 4 * 5 * Based on code from Freescale, 6 * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. 7 * 8 * This program is free software; you can redistribute it and/or --- 45 unchanged lines hidden (view full) --- 54 int id; 55 int irq; 56 int virtual_irq_start; 57 struct bgpio_chip bgc; 58}; 59 60/* Note: This driver assumes 32 GPIOs are handled in one register */ 61 | 1/* 2 * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> 3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de 4 * 5 * Based on code from Freescale, 6 * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. 7 * 8 * This program is free software; you can redistribute it and/or --- 45 unchanged lines hidden (view full) --- 54 int id; 55 int irq; 56 int virtual_irq_start; 57 struct bgpio_chip bgc; 58}; 59 60/* Note: This driver assumes 32 GPIOs are handled in one register */ 61 |
62static void clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index) 63{ 64 writel(1 << index, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); 65} 66 67static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index, 68 int enable) 69{ 70 if (enable) { 71 writel(1 << index, 72 port->base + PINCTRL_IRQEN(port->id) + MXS_SET); 73 writel(1 << index, 74 port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET); 75 } else { 76 writel(1 << index, 77 port->base + PINCTRL_IRQEN(port->id) + MXS_CLR); 78 } 79} 80 81static void mxs_gpio_ack_irq(struct irq_data *d) 82{ 83 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d); 84 u32 gpio = irq_to_gpio(d->irq); 85 clear_gpio_irqstatus(port, gpio & 0x1f); 86} 87 88static void mxs_gpio_mask_irq(struct irq_data *d) 89{ 90 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d); 91 u32 gpio = irq_to_gpio(d->irq); 92 set_gpio_irqenable(port, gpio & 0x1f, 0); 93} 94 95static void mxs_gpio_unmask_irq(struct irq_data *d) 96{ 97 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d); 98 u32 gpio = irq_to_gpio(d->irq); 99 set_gpio_irqenable(port, gpio & 0x1f, 1); 100} 101 | |
102static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) 103{ 104 u32 gpio = irq_to_gpio(d->irq); 105 u32 pin_mask = 1 << (gpio & 31); | 62static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) 63{ 64 u32 gpio = irq_to_gpio(d->irq); 65 u32 pin_mask = 1 << (gpio & 31); |
106 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d); | 66 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 67 struct mxs_gpio_port *port = gc->private; |
107 void __iomem *pin_addr; 108 int edge; 109 110 switch (type) { 111 case IRQ_TYPE_EDGE_RISING: 112 edge = GPIO_INT_RISE_EDGE; 113 break; 114 case IRQ_TYPE_EDGE_FALLING: --- 18 unchanged lines hidden (view full) --- 133 134 /* set polarity */ 135 pin_addr = port->base + PINCTRL_IRQPOL(port->id); 136 if (edge & GPIO_INT_POL_MASK) 137 writel(pin_mask, pin_addr + MXS_SET); 138 else 139 writel(pin_mask, pin_addr + MXS_CLR); 140 | 68 void __iomem *pin_addr; 69 int edge; 70 71 switch (type) { 72 case IRQ_TYPE_EDGE_RISING: 73 edge = GPIO_INT_RISE_EDGE; 74 break; 75 case IRQ_TYPE_EDGE_FALLING: --- 18 unchanged lines hidden (view full) --- 94 95 /* set polarity */ 96 pin_addr = port->base + PINCTRL_IRQPOL(port->id); 97 if (edge & GPIO_INT_POL_MASK) 98 writel(pin_mask, pin_addr + MXS_SET); 99 else 100 writel(pin_mask, pin_addr + MXS_CLR); 101 |
141 clear_gpio_irqstatus(port, gpio & 0x1f); | 102 writel(1 << (gpio & 0x1f), 103 port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); |
142 143 return 0; 144} 145 146/* MXS has one interrupt *per* gpio port */ 147static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) 148{ 149 u32 irq_stat; --- 18 unchanged lines hidden (view full) --- 168 * wake-up enabled. When system is suspended, only selected GPIO interrupts 169 * need to have wake-up enabled. 170 * @param irq interrupt source number 171 * @param enable enable as wake-up if equal to non-zero 172 * @return This function returns 0 on success. 173 */ 174static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable) 175{ | 104 105 return 0; 106} 107 108/* MXS has one interrupt *per* gpio port */ 109static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) 110{ 111 u32 irq_stat; --- 18 unchanged lines hidden (view full) --- 130 * wake-up enabled. When system is suspended, only selected GPIO interrupts 131 * need to have wake-up enabled. 132 * @param irq interrupt source number 133 * @param enable enable as wake-up if equal to non-zero 134 * @return This function returns 0 on success. 135 */ 136static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable) 137{ |
176 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d); | 138 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 139 struct mxs_gpio_port *port = gc->private; |
177 178 if (enable) 179 enable_irq_wake(port->irq); 180 else 181 disable_irq_wake(port->irq); 182 183 return 0; 184} 185 | 140 141 if (enable) 142 enable_irq_wake(port->irq); 143 else 144 disable_irq_wake(port->irq); 145 146 return 0; 147} 148 |
186static struct irq_chip gpio_irq_chip = { 187 .name = "mxs gpio", 188 .irq_ack = mxs_gpio_ack_irq, 189 .irq_mask = mxs_gpio_mask_irq, 190 .irq_unmask = mxs_gpio_unmask_irq, 191 .irq_set_type = mxs_gpio_set_irq_type, 192 .irq_set_wake = mxs_gpio_set_wake_irq, 193}; | 149static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port) 150{ 151 struct irq_chip_generic *gc; 152 struct irq_chip_type *ct; |
194 | 153 |
154 gc = irq_alloc_generic_chip("gpio-mxs", 1, port->virtual_irq_start, 155 port->base, handle_level_irq); 156 gc->private = port; 157 158 ct = gc->chip_types; 159 ct->chip.irq_ack = irq_gc_ack, 160 ct->chip.irq_mask = irq_gc_mask_clr_bit; 161 ct->chip.irq_unmask = irq_gc_mask_set_bit; 162 ct->chip.irq_set_type = mxs_gpio_set_irq_type; 163 ct->chip.irq_set_wake = mxs_gpio_set_wake_irq, 164 ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR; 165 ct->regs.mask = PINCTRL_IRQEN(port->id); 166 167 irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0); 168} 169 |
|
195static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset) 196{ 197 struct bgpio_chip *bgc = to_bgpio_chip(gc); 198 struct mxs_gpio_port *port = 199 container_of(bgc, struct mxs_gpio_port, bgc); 200 201 return port->virtual_irq_start + offset; 202} 203 204static int __devinit mxs_gpio_probe(struct platform_device *pdev) 205{ 206 static void __iomem *base; 207 struct mxs_gpio_port *port; 208 struct resource *iores = NULL; | 170static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset) 171{ 172 struct bgpio_chip *bgc = to_bgpio_chip(gc); 173 struct mxs_gpio_port *port = 174 container_of(bgc, struct mxs_gpio_port, bgc); 175 176 return port->virtual_irq_start + offset; 177} 178 179static int __devinit mxs_gpio_probe(struct platform_device *pdev) 180{ 181 static void __iomem *base; 182 struct mxs_gpio_port *port; 183 struct resource *iores = NULL; |
209 int err, i; | 184 int err; |
210 211 port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL); 212 if (!port) 213 return -ENOMEM; 214 215 port->id = pdev->id; 216 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; 217 --- 23 unchanged lines hidden (view full) --- 241 port->base = base; 242 243 port->irq = platform_get_irq(pdev, 0); 244 if (port->irq < 0) { 245 err = -EINVAL; 246 goto out_iounmap; 247 } 248 | 185 186 port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL); 187 if (!port) 188 return -ENOMEM; 189 190 port->id = pdev->id; 191 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; 192 --- 23 unchanged lines hidden (view full) --- 216 port->base = base; 217 218 port->irq = platform_get_irq(pdev, 0); 219 if (port->irq < 0) { 220 err = -EINVAL; 221 goto out_iounmap; 222 } 223 |
249 /* disable the interrupt and clear the status */ 250 writel(0, port->base + PINCTRL_PIN2IRQ(port->id)); | 224 /* 225 * select the pin interrupt functionality but initially 226 * disable the interrupts 227 */ 228 writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id)); |
251 writel(0, port->base + PINCTRL_IRQEN(port->id)); 252 253 /* clear address has to be used to clear IRQSTAT bits */ 254 writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); 255 | 229 writel(0, port->base + PINCTRL_IRQEN(port->id)); 230 231 /* clear address has to be used to clear IRQSTAT bits */ 232 writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); 233 |
256 for (i = port->virtual_irq_start; 257 i < port->virtual_irq_start + 32; i++) { 258 irq_set_chip_and_handler(i, &gpio_irq_chip, 259 handle_level_irq); 260 set_irq_flags(i, IRQF_VALID); 261 irq_set_chip_data(i, port); 262 } | 234 /* gpio-mxs can be a generic irq chip */ 235 mxs_gpio_init_gc(port); |
263 264 /* setup one handler for each entry */ 265 irq_set_chained_handler(port->irq, mxs_gpio_irq_handler); 266 irq_set_handler_data(port->irq, port); 267 268 err = bgpio_init(&port->bgc, &pdev->dev, 4, 269 port->base + PINCTRL_DIN(port->id), 270 port->base + PINCTRL_DOUT(port->id), NULL, --- 46 unchanged lines hidden --- | 236 237 /* setup one handler for each entry */ 238 irq_set_chained_handler(port->irq, mxs_gpio_irq_handler); 239 irq_set_handler_data(port->irq, port); 240 241 err = bgpio_init(&port->bgc, &pdev->dev, 4, 242 port->base + PINCTRL_DIN(port->id), 243 port->base + PINCTRL_DOUT(port->id), NULL, --- 46 unchanged lines hidden --- |