Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 261867
b: refs/heads/master
c: 914e6d4
h: refs/heads/master
i:
  261865: cc15f2b
  261863: ed1f1c9
v: v3
  • Loading branch information
Lars-Peter Clausen authored and Samuel Ortiz committed Jul 31, 2011
1 parent f7b40c0 commit cd9097a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 64 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f85dbda076a11c18b396f8acfff929e53159e56d
refs/heads/master: 914e6d4e36015180bdcb6b99e96adc6293b7c2c6
3 changes: 2 additions & 1 deletion trunk/drivers/mfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -662,8 +662,9 @@ config MFD_JANZ_CMODIO
CAN and GPIO controllers.

config MFD_JZ4740_ADC
tristate "Support for the JZ4740 SoC ADC core"
bool "Support for the JZ4740 SoC ADC core"
select MFD_CORE
select GENERIC_IRQ_CHIP
depends on MACH_JZ4740
help
Say yes here if you want support for the ADC unit in the JZ4740 SoC.
Expand Down
90 changes: 28 additions & 62 deletions trunk/drivers/mfd/jz4740-adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,71 +56,25 @@ struct jz4740_adc {
void __iomem *base;

int irq;
int irq_base;
struct irq_chip_generic *gc;

struct clk *clk;
atomic_t clk_ref;

spinlock_t lock;
};

static inline void jz4740_adc_irq_set_masked(struct jz4740_adc *adc, int irq,
bool masked)
{
unsigned long flags;
uint8_t val;

irq -= adc->irq_base;

spin_lock_irqsave(&adc->lock, flags);

val = readb(adc->base + JZ_REG_ADC_CTRL);
if (masked)
val |= BIT(irq);
else
val &= ~BIT(irq);
writeb(val, adc->base + JZ_REG_ADC_CTRL);

spin_unlock_irqrestore(&adc->lock, flags);
}

static void jz4740_adc_irq_mask(struct irq_data *data)
{
struct jz4740_adc *adc = irq_data_get_irq_chip_data(data);
jz4740_adc_irq_set_masked(adc, data->irq, true);
}

static void jz4740_adc_irq_unmask(struct irq_data *data)
{
struct jz4740_adc *adc = irq_data_get_irq_chip_data(data);
jz4740_adc_irq_set_masked(adc, data->irq, false);
}

static void jz4740_adc_irq_ack(struct irq_data *data)
{
struct jz4740_adc *adc = irq_data_get_irq_chip_data(data);
unsigned int irq = data->irq - adc->irq_base;
writeb(BIT(irq), adc->base + JZ_REG_ADC_STATUS);
}

static struct irq_chip jz4740_adc_irq_chip = {
.name = "jz4740-adc",
.irq_mask = jz4740_adc_irq_mask,
.irq_unmask = jz4740_adc_irq_unmask,
.irq_ack = jz4740_adc_irq_ack,
};

static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc)
{
struct jz4740_adc *adc = irq_desc_get_handler_data(desc);
struct irq_chip_generic *gc = irq_desc_get_handler_data(desc);
uint8_t status;
unsigned int i;

status = readb(adc->base + JZ_REG_ADC_STATUS);
status = readb(gc->reg_base + JZ_REG_ADC_STATUS);

for (i = 0; i < 5; ++i) {
if (status & BIT(i))
generic_handle_irq(adc->irq_base + i);
generic_handle_irq(gc->irq_base + i);
}
}

Expand Down Expand Up @@ -249,10 +203,12 @@ const struct mfd_cell jz4740_adc_cells[] = {

static int __devinit jz4740_adc_probe(struct platform_device *pdev)
{
int ret;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
struct jz4740_adc *adc;
struct resource *mem_base;
int irq;
int ret;
int irq_base;

adc = kmalloc(sizeof(*adc), GFP_KERNEL);
if (!adc) {
Expand All @@ -267,9 +223,9 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev)
goto err_free;
}

adc->irq_base = platform_get_irq(pdev, 1);
if (adc->irq_base < 0) {
ret = adc->irq_base;
irq_base = platform_get_irq(pdev, 1);
if (irq_base < 0) {
ret = irq_base;
dev_err(&pdev->dev, "Failed to get irq base: %d\n", ret);
goto err_free;
}
Expand Down Expand Up @@ -309,20 +265,28 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, adc);

for (irq = adc->irq_base; irq < adc->irq_base + 5; ++irq) {
irq_set_chip_data(irq, adc);
irq_set_chip_and_handler(irq, &jz4740_adc_irq_chip,
handle_level_irq);
}
gc = irq_alloc_generic_chip("INTC", 1, irq_base, adc->base,
handle_level_irq);

ct = gc->chip_types;
ct->regs.mask = JZ_REG_ADC_CTRL;
ct->regs.ack = JZ_REG_ADC_STATUS;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
ct->chip.irq_ack = irq_gc_ack;

irq_setup_generic_chip(gc, IRQ_MSK(5), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);

adc->gc = gc;

irq_set_handler_data(adc->irq, adc);
irq_set_handler_data(adc->irq, gc);
irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux);

writeb(0x00, adc->base + JZ_REG_ADC_ENABLE);
writeb(0xff, adc->base + JZ_REG_ADC_CTRL);

ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells,
ARRAY_SIZE(jz4740_adc_cells), mem_base, adc->irq_base);
ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base);
if (ret < 0)
goto err_clk_put;

Expand All @@ -347,6 +311,8 @@ static int __devexit jz4740_adc_remove(struct platform_device *pdev)

mfd_remove_devices(&pdev->dev);

irq_remove_generic_chip(adc->gc, IRQ_MSK(5), IRQ_NOPROBE | IRQ_LEVEL, 0);
kfree(adc->gc);
irq_set_handler_data(adc->irq, NULL);
irq_set_chained_handler(adc->irq, NULL);

Expand Down

0 comments on commit cd9097a

Please sign in to comment.