Date:2011-03-04 13:14:01 (13 years 24 days ago)
Author:Lars C.
Commit:1a111cf8ee655cf85a71cb4723ec0b8a6a1d1de8
Message:Generalize gpio support

Make GPIO-chip IRQ and GPIO IRQ base configurable and move GPIO-chip
initialization to the sub-archs.
Files: arch/mips/include/asm/mach-jz47xx/gpio.h (2 diffs)
arch/mips/jz47xx/gpiov2.c (12 diffs)
arch/mips/jz47xx/jz4740/Makefile (1 diff)
arch/mips/jz47xx/jz4740/gpio.c (1 diff)

Change Details

arch/mips/include/asm/mach-jz47xx/gpio.h
1717#define __ASM_MACH_JZ47XX_GPIO_H__
1818
1919#include <linux/types.h>
20#include <linux/spinlock.h>
21#include <linux/sysdev.h>
2022
2123enum jz_gpio_function {
2224    JZ_GPIO_FUNC_NONE,
...... 
8082#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
8183#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
8284
85struct jz_gpio_chip {
86    unsigned int id;
87
88    unsigned int irq;
89
90    uint32_t wakeup;
91    uint32_t suspend_mask;
92    uint32_t edge_trigger_both;
93
94    void __iomem *base;
95
96    spinlock_t lock;
97
98    struct gpio_chip gpio_chip;
99    struct sys_device sysdev;
100};
101
102#define JZ47XX_GPIO_CHIP(_bank, _ngpio, _irq) { \
103    .irq = _irq, \
104    .gpio_chip = { \
105        .label = "Bank " _bank, \
106        .owner = THIS_MODULE, \
107        .ngpio = _ngpio, \
108    }, \
109}
110
111int __init jz47xx_gpio_init(struct jz_gpio_chip *chips, size_t num,
112    unsigned int irq_base);
113
83114#endif
arch/mips/jz47xx/gpiov2.c
11/*
22 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 platform GPIO support
3 * JZ47XX platform GPIO support
44 *
55 * This program is free software; you can redistribute it and/or modify it
66 * under the terms of the GNU General Public License as published by the
...... 
2828#include <linux/debugfs.h>
2929#include <linux/seq_file.h>
3030
31#include <jz4740/base.h>
32#include <jz4740/irq.h>
33#include <jz4740/gpio.h>
34
35#define JZ4740_GPIO_BASE_A (32*0)
36#define JZ4740_GPIO_BASE_B (32*1)
37#define JZ4740_GPIO_BASE_C (32*2)
38#define JZ4740_GPIO_BASE_D (32*3)
39
40#define JZ4740_GPIO_NUM_A 32
41#define JZ4740_GPIO_NUM_B 32
42#define JZ4740_GPIO_NUM_C 31
43#define JZ4740_GPIO_NUM_D 32
44
45#define JZ4740_IRQ_GPIO_BASE_A (JZ47XX_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A)
46#define JZ4740_IRQ_GPIO_BASE_B (JZ47XX_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B)
47#define JZ4740_IRQ_GPIO_BASE_C (JZ47XX_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C)
48#define JZ4740_IRQ_GPIO_BASE_D (JZ47XX_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D)
31#include <asm/mach-jz47xx/jz4740/base.h>
32#include <asm/mach-jz47xx/gpio.h>
4933
5034#define JZ_REG_GPIO_PIN 0x00
5135#define JZ_REG_GPIO_DATA 0x10
...... 
7660#define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg))
7761#define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg))
7862
79struct jz_gpio_chip {
80    unsigned int irq;
81    unsigned int irq_base;
82    uint32_t wakeup;
83    uint32_t suspend_mask;
84    uint32_t edge_trigger_both;
85
86    void __iomem *base;
87
88    spinlock_t lock;
89
90    struct gpio_chip gpio_chip;
91    struct sys_device sysdev;
92};
93
94static struct jz_gpio_chip jz4740_gpio_chips[];
63static struct jz_gpio_chip *jz_gpio_chips;
64static size_t jz_gpio_num_chips;
65static unsigned int jz_gpio_irq_base;
9566
9667static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
9768{
98    return &jz4740_gpio_chips[gpio >> 5];
69    return &jz_gpio_chips[gpio >> 5];
9970}
10071
10172static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip)
...... 
271242
272243int gpio_to_irq(unsigned gpio)
273244{
274    return JZ47XX_IRQ_GPIO(0) + gpio;
245    return jz_gpio_irq_base + gpio;
275246}
276247EXPORT_SYMBOL_GPL(gpio_to_irq);
277248
278249int irq_to_gpio(unsigned irq)
279250{
280    return irq - JZ47XX_IRQ_GPIO(0);
251    return irq - jz_gpio_irq_base;
281252}
282253EXPORT_SYMBOL_GPL(irq_to_gpio);
283254
...... 
307278{
308279    uint32_t flag;
309280    unsigned int gpio_irq;
310    unsigned int gpio_bank;
311281    struct jz_gpio_chip *chip = get_irq_desc_data(desc);
312282
313    gpio_bank = JZ47XX_IRQ_GPIO(0) - irq;
314
315283    flag = readl(chip->base + JZ_REG_GPIO_FLAG);
316284
317285    if (!flag)
...... 
321289
322290    jz_gpio_check_trigger_both(chip, irq);
323291
324    gpio_irq += (gpio_bank << 5) + JZ47XX_IRQ_GPIO(0);
292    gpio_irq += (chip->id << 5) + JZ47XX_IRQ_GPIO(0);
325293
326294    generic_handle_irq(gpio_irq);
327295};
...... 
453421 */
454422static struct lock_class_key gpio_lock_class;
455423
456#define JZ4740_GPIO_CHIP(_bank) { \
457    .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
458    .gpio_chip = { \
459        .label = "Bank " # _bank, \
460        .owner = THIS_MODULE, \
461        .set = jz_gpio_set_value, \
462        .get = jz_gpio_get_value, \
463        .direction_output = jz_gpio_direction_output, \
464        .direction_input = jz_gpio_direction_input, \
465        .base = JZ4740_GPIO_BASE_ ## _bank, \
466        .ngpio = JZ4740_GPIO_NUM_ ## _bank, \
467    }, \
468}
469
470static struct jz_gpio_chip jz4740_gpio_chips[] = {
471    JZ4740_GPIO_CHIP(A),
472    JZ4740_GPIO_CHIP(B),
473    JZ4740_GPIO_CHIP(C),
474    JZ4740_GPIO_CHIP(D),
475};
476
477424static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev)
478425{
479426    return container_of(dev, struct jz_gpio_chip, sysdev);
480427}
481428
482static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state)
429static int jz_gpio_suspend(struct sys_device *dev, pm_message_t state)
483430{
484431    struct jz_gpio_chip *chip = sysdev_to_chip(dev);
485432
...... 
490437    return 0;
491438}
492439
493static int jz4740_gpio_resume(struct sys_device *dev)
440static int jz_gpio_resume(struct sys_device *dev)
494441{
495442    struct jz_gpio_chip *chip = sysdev_to_chip(dev);
496443    uint32_t mask = chip->suspend_mask;
...... 
501448    return 0;
502449}
503450
504static struct sysdev_class jz4740_gpio_sysdev_class = {
451static struct sysdev_class jz_gpio_sysdev_class = {
505452    .name = "gpio",
506    .suspend = jz4740_gpio_suspend,
507    .resume = jz4740_gpio_resume,
453    .suspend = jz_gpio_suspend,
454    .resume = jz_gpio_resume,
508455};
509456
510static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
457static int __init jz47xx_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
511458{
512459    int ret, irq;
460    unsigned int chip_irq_base, chip_irq_end;
513461
514462    chip->sysdev.id = id;
515    chip->sysdev.cls = &jz4740_gpio_sysdev_class;
463    chip->sysdev.cls = &jz_gpio_sysdev_class;
516464    ret = sysdev_register(&chip->sysdev);
517465
518466    if (ret)
...... 
521469    spin_lock_init(&chip->lock);
522470
523471    chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);
472    chip->gpio_chip.base = 32 * id;
473
474    chip->gpio_chip.set = jz_gpio_set_value;
475    chip->gpio_chip.get = jz_gpio_get_value;
476    chip->gpio_chip.direction_output = jz_gpio_direction_output;
477    chip->gpio_chip.direction_input = jz_gpio_direction_input;
524478
525479    gpiochip_add(&chip->gpio_chip);
526480
527    chip->irq = JZ47XX_IRQ_INTC_GPIO(id);
528481    set_irq_data(chip->irq, chip);
529482    set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
530483
531    for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
484    chip_irq_base = jz_gpio_irq_base + id * 32;
485    chip_irq_end = chip_irq_base + chip->gpio_chip.ngpio;
486
487    for (irq = chip_irq_base; irq < chip_irq_end; ++irq) {
532488        lockdep_set_class(&irq_desc[irq].lock, &gpio_lock_class);
533489        set_irq_chip_data(irq, chip);
534490        set_irq_chip_and_handler(irq, &jz_gpio_irq_chip, handle_level_irq);
...... 
537493    return 0;
538494}
539495
540static int __init jz4740_gpio_init(void)
496int __init jz47xx_gpio_init(struct jz_gpio_chip *chips, size_t num,
497    unsigned int irq_base)
541498{
542499    unsigned int i;
543500    int ret;
544501
545    ret = sysdev_class_register(&jz4740_gpio_sysdev_class);
502    ret = sysdev_class_register(&jz_gpio_sysdev_class);
546503    if (ret)
547504        return ret;
548505
549    for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i)
550        jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
506    jz_gpio_num_chips = num;
507    jz_gpio_irq_base = irq_base;
508
509    for (i = 0; i < num; ++i)
510        jz47xx_gpio_chip_init(&chips[i], i);
551511
552    printk(KERN_INFO "JZ4740 GPIO initalized\n");
512    printk(KERN_INFO "JZ47XX GPIO initalized\n");
553513
554514    return 0;
555515}
556arch_initcall(jz4740_gpio_init);
557516
558517#ifdef CONFIG_DEBUG_FS
559518
...... 
565524
566525static int gpio_regs_show(struct seq_file *s, void *unused)
567526{
568    struct jz_gpio_chip *chip = jz4740_gpio_chips;
527    struct jz_gpio_chip *chip = jz_gpio_chips;
569528    int i;
570529
571    for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i, ++chip) {
530    for (i = 0; i < jz_gpio_num_chips; ++i, ++chip) {
572531        seq_printf(s, "==GPIO %d==\n", i);
573532        gpio_seq_reg(s, chip, "Pin", JZ_REG_GPIO_PIN);
574533        gpio_seq_reg(s, chip, "Data", JZ_REG_GPIO_DATA);
arch/mips/jz47xx/jz4740/Makefile
11
2obj-y += clock.o platform.o time.o
2obj-y += clock.o platform.o time.o gpio.o
33
44obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
55obj-$(CONFIG_JZ4740_N516) += board-n516.o board-n516-display.o
arch/mips/jz47xx/jz4740/gpio.c
1#include <linux/init.h>
2
3#include <asm/mach-jz47xx/jz4740/irq.h>
4#include <asm/mach-jz47xx/gpio.h>
5
6
7static struct jz_gpio_chip jz4740_gpio_chips[] = {
8    JZ47XX_GPIO_CHIP("A", 32, JZ4740_IRQ_GPIO0),
9    JZ47XX_GPIO_CHIP("B", 32, JZ4740_IRQ_GPIO1),
10    JZ47XX_GPIO_CHIP("C", 31, JZ4740_IRQ_GPIO2),
11    JZ47XX_GPIO_CHIP("D", 32, JZ4740_IRQ_GPIO3),
12};
13
14static int __init jz4740_gpio_init(void)
15{
16    jz47xx_gpio_init(jz4740_gpio_chips, ARRAY_SIZE(jz4740_gpio_chips),
17            JZ4740_IRQ_GPIO(0));
18    return 0;
19}
20arch_initcall(jz4740_gpio_init);
21
22

Archive Download the corresponding diff file



interactive