Date:2011-06-03 03:14:26 (9 years 3 months ago)
Author:Lars C.
Commit:7d98bd6ddb8dd0358044a7ccfe8ad46c638285e7
Message:mfd: Use generic irq chip for jz4740-adc

Use the generic irq chip framework for implementing the irq chip for
the jz4740-adc driver.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Files: drivers/mfd/Kconfig (1 diff)
drivers/mfd/jz4740-adc.c (6 diffs)

Change Details

drivers/mfd/Kconfig
656656      CAN and GPIO controllers.
657657
658658config MFD_JZ4740_ADC
659    tristate "Support for the JZ4740 SoC ADC core"
659    bool "Support for the JZ4740 SoC ADC core"
660660    select MFD_CORE
661    select GENERIC_IRQ_CHIP
661662    depends on MACH_JZ4740
662663    help
663664      Say yes here if you want support for the ADC unit in the JZ4740 SoC.
drivers/mfd/jz4740-adc.c
5656    void __iomem *base;
5757
5858    int irq;
59    int irq_base;
59    struct irq_chip_generic *gc;
6060
6161    struct clk *clk;
6262    atomic_t clk_ref;
...... 
6464    spinlock_t lock;
6565};
6666
67static inline void jz4740_adc_irq_set_masked(struct jz4740_adc *adc, int irq,
68    bool masked)
69{
70    unsigned long flags;
71    uint8_t val;
72
73    irq -= adc->irq_base;
74
75    spin_lock_irqsave(&adc->lock, flags);
76
77    val = readb(adc->base + JZ_REG_ADC_CTRL);
78    if (masked)
79        val |= BIT(irq);
80    else
81        val &= ~BIT(irq);
82    writeb(val, adc->base + JZ_REG_ADC_CTRL);
83
84    spin_unlock_irqrestore(&adc->lock, flags);
85}
86
87static void jz4740_adc_irq_mask(struct irq_data *data)
88{
89    struct jz4740_adc *adc = irq_data_get_irq_chip_data(data);
90    jz4740_adc_irq_set_masked(adc, data->irq, true);
91}
92
93static void jz4740_adc_irq_unmask(struct irq_data *data)
94{
95    struct jz4740_adc *adc = irq_data_get_irq_chip_data(data);
96    jz4740_adc_irq_set_masked(adc, data->irq, false);
97}
98
99static void jz4740_adc_irq_ack(struct irq_data *data)
100{
101    struct jz4740_adc *adc = irq_data_get_irq_chip_data(data);
102    unsigned int irq = data->irq - adc->irq_base;
103    writeb(BIT(irq), adc->base + JZ_REG_ADC_STATUS);
104}
105
106static struct irq_chip jz4740_adc_irq_chip = {
107    .name = "jz4740-adc",
108    .irq_mask = jz4740_adc_irq_mask,
109    .irq_unmask = jz4740_adc_irq_unmask,
110    .irq_ack = jz4740_adc_irq_ack,
111};
112
11367static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc)
11468{
115    struct jz4740_adc *adc = irq_desc_get_handler_data(desc);
69    struct irq_chip_generic *gc = irq_desc_get_handler_data(desc);
11670    uint8_t status;
11771    unsigned int i;
11872
119    status = readb(adc->base + JZ_REG_ADC_STATUS);
73    status = readb(gc->reg_base + JZ_REG_ADC_STATUS);
12074
12175    for (i = 0; i < 5; ++i) {
12276        if (status & BIT(i))
123            generic_handle_irq(adc->irq_base + i);
77            generic_handle_irq(gc->irq_base + i);
12478    }
12579}
12680
...... 
249203
250204static int __devinit jz4740_adc_probe(struct platform_device *pdev)
251205{
252    int ret;
206    struct irq_chip_generic *gc;
207    struct irq_chip_type *ct;
253208    struct jz4740_adc *adc;
254209    struct resource *mem_base;
255    int irq;
210    int ret;
211    int irq_base;
256212
257213    adc = kmalloc(sizeof(*adc), GFP_KERNEL);
258214    if (!adc) {
...... 
267223        goto err_free;
268224    }
269225
270    adc->irq_base = platform_get_irq(pdev, 1);
271    if (adc->irq_base < 0) {
272        ret = adc->irq_base;
226    irq_base = platform_get_irq(pdev, 1);
227    if (irq_base < 0) {
228        ret = irq_base;
273229        dev_err(&pdev->dev, "Failed to get irq base: %d\n", ret);
274230        goto err_free;
275231    }
...... 
309265
310266    platform_set_drvdata(pdev, adc);
311267
312    for (irq = adc->irq_base; irq < adc->irq_base + 5; ++irq) {
313        irq_set_chip_data(irq, adc);
314        irq_set_chip_and_handler(irq, &jz4740_adc_irq_chip,
315                     handle_level_irq);
316    }
268    gc = irq_alloc_generic_chip("INTC", 1, irq_base, adc->base,
269        handle_level_irq);
270
271    ct = gc->chip_types;
272    ct->regs.mask = JZ_REG_ADC_CTRL;
273    ct->regs.ack = JZ_REG_ADC_STATUS;
274    ct->chip.irq_mask = irq_gc_mask_set_bit;
275    ct->chip.irq_unmask = irq_gc_mask_clr_bit;
276    ct->chip.irq_ack = irq_gc_ack;
277
278    irq_setup_generic_chip(gc, IRQ_MSK(5), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
279
280    adc->gc = gc;
317281
318    irq_set_handler_data(adc->irq, adc);
282    irq_set_handler_data(adc->irq, gc);
319283    irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux);
320284
321285    writeb(0x00, adc->base + JZ_REG_ADC_ENABLE);
322286    writeb(0xff, adc->base + JZ_REG_ADC_CTRL);
323287
324288    ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells,
325        ARRAY_SIZE(jz4740_adc_cells), mem_base, adc->irq_base);
289        ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base);
326290    if (ret < 0)
327291        goto err_clk_put;
328292
...... 
347311
348312    mfd_remove_devices(&pdev->dev);
349313
314    irq_remove_generic_chip(adc->gc, IRQ_MSK(5), IRQ_NOPROBE | IRQ_LEVEL, 0);
315    kfree(adc->gc);
350316    irq_set_handler_data(adc->irq, NULL);
351317    irq_set_chained_handler(adc->irq, NULL);
352318

Archive Download the corresponding diff file



interactive