aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/jz4740-adc.c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2011-06-02 21:14:26 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-07-31 17:28:21 -0400
commit914e6d4e36015180bdcb6b99e96adc6293b7c2c6 (patch)
treefc2f37fcb8ab369a5bcbdcb5c4a8877e01111f16 /drivers/mfd/jz4740-adc.c
parentf85dbda076a11c18b396f8acfff929e53159e56d (diff)
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>
Diffstat (limited to 'drivers/mfd/jz4740-adc.c')
-rw-r--r--drivers/mfd/jz4740-adc.c90
1 files changed, 28 insertions, 62 deletions
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c
index a0bd0cf05af3..21131c7b0f1e 100644
--- a/drivers/mfd/jz4740-adc.c
+++ b/drivers/mfd/jz4740-adc.c
@@ -56,7 +56,7 @@ struct jz4740_adc {
56 void __iomem *base; 56 void __iomem *base;
57 57
58 int irq; 58 int irq;
59 int irq_base; 59 struct irq_chip_generic *gc;
60 60
61 struct clk *clk; 61 struct clk *clk;
62 atomic_t clk_ref; 62 atomic_t clk_ref;
@@ -64,63 +64,17 @@ struct jz4740_adc {
64 spinlock_t lock; 64 spinlock_t lock;
65}; 65};
66 66
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
113static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) 67static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc)
114{ 68{
115 struct jz4740_adc *adc = irq_desc_get_handler_data(desc); 69 struct irq_chip_generic *gc = irq_desc_get_handler_data(desc);
116 uint8_t status; 70 uint8_t status;
117 unsigned int i; 71 unsigned int i;
118 72
119 status = readb(adc->base + JZ_REG_ADC_STATUS); 73 status = readb(gc->reg_base + JZ_REG_ADC_STATUS);
120 74
121 for (i = 0; i < 5; ++i) { 75 for (i = 0; i < 5; ++i) {
122 if (status & BIT(i)) 76 if (status & BIT(i))
123 generic_handle_irq(adc->irq_base + i); 77 generic_handle_irq(gc->irq_base + i);
124 } 78 }
125} 79}
126 80
@@ -249,10 +203,12 @@ const struct mfd_cell jz4740_adc_cells[] = {
249 203
250static int __devinit jz4740_adc_probe(struct platform_device *pdev) 204static int __devinit jz4740_adc_probe(struct platform_device *pdev)
251{ 205{
252 int ret; 206 struct irq_chip_generic *gc;
207 struct irq_chip_type *ct;
253 struct jz4740_adc *adc; 208 struct jz4740_adc *adc;
254 struct resource *mem_base; 209 struct resource *mem_base;
255 int irq; 210 int ret;
211 int irq_base;
256 212
257 adc = kmalloc(sizeof(*adc), GFP_KERNEL); 213 adc = kmalloc(sizeof(*adc), GFP_KERNEL);
258 if (!adc) { 214 if (!adc) {
@@ -267,9 +223,9 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev)
267 goto err_free; 223 goto err_free;
268 } 224 }
269 225
270 adc->irq_base = platform_get_irq(pdev, 1); 226 irq_base = platform_get_irq(pdev, 1);
271 if (adc->irq_base < 0) { 227 if (irq_base < 0) {
272 ret = adc->irq_base; 228 ret = irq_base;
273 dev_err(&pdev->dev, "Failed to get irq base: %d\n", ret); 229 dev_err(&pdev->dev, "Failed to get irq base: %d\n", ret);
274 goto err_free; 230 goto err_free;
275 } 231 }
@@ -309,20 +265,28 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev)
309 265
310 platform_set_drvdata(pdev, adc); 266 platform_set_drvdata(pdev, adc);
311 267
312 for (irq = adc->irq_base; irq < adc->irq_base + 5; ++irq) { 268 gc = irq_alloc_generic_chip("INTC", 1, irq_base, adc->base,
313 irq_set_chip_data(irq, adc); 269 handle_level_irq);
314 irq_set_chip_and_handler(irq, &jz4740_adc_irq_chip, 270
315 handle_level_irq); 271 ct = gc->chip_types;
316 } 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;
317 281
318 irq_set_handler_data(adc->irq, adc); 282 irq_set_handler_data(adc->irq, gc);
319 irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux); 283 irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux);
320 284
321 writeb(0x00, adc->base + JZ_REG_ADC_ENABLE); 285 writeb(0x00, adc->base + JZ_REG_ADC_ENABLE);
322 writeb(0xff, adc->base + JZ_REG_ADC_CTRL); 286 writeb(0xff, adc->base + JZ_REG_ADC_CTRL);
323 287
324 ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, 288 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);
326 if (ret < 0) 290 if (ret < 0)
327 goto err_clk_put; 291 goto err_clk_put;
328 292
@@ -347,6 +311,8 @@ static int __devexit jz4740_adc_remove(struct platform_device *pdev)
347 311
348 mfd_remove_devices(&pdev->dev); 312 mfd_remove_devices(&pdev->dev);
349 313
314 irq_remove_generic_chip(adc->gc, IRQ_MSK(5), IRQ_NOPROBE | IRQ_LEVEL, 0);
315 kfree(adc->gc);
350 irq_set_handler_data(adc->irq, NULL); 316 irq_set_handler_data(adc->irq, NULL);
351 irq_set_chained_handler(adc->irq, NULL); 317 irq_set_chained_handler(adc->irq, NULL);
352 318