From 5a6ed99264c704e517ac312283c58204ee38fee5 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Sat, 13 Jun 2009 02:04:18 +0400 Subject: gta02: move debugging messages to the appropriate levels Clean up debugging messages so that we don't see any output with loglevel=4 (default for Qi). This avoids slowing down suspend/resume by slow fb output. Checkpatch barks on this patch but i guess most of that debugging would have to be changed prior to upstream submission anyway. Signed-off-by: Paul Fertser --- drivers/mfd/glamo/glamo-fb.c | 4 ++-- drivers/mfd/glamo/glamo-mci.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c index 1ebb87d1276..44ab9a39787 100644 --- a/drivers/mfd/glamo/glamo-fb.c +++ b/drivers/mfd/glamo/glamo-fb.c @@ -1061,7 +1061,7 @@ static int __init glamofb_probe(struct platform_device *pdev) glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD); glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD); - dev_info(&pdev->dev, "spin_lock_init\n"); + dev_dbg(&pdev->dev, "spin_lock_init\n"); spin_lock_init(&glamofb->lock_cmd); glamofb_init_regs(glamofb); #ifdef CONFIG_MFD_GLAMO_HWACCEL @@ -1148,7 +1148,7 @@ static int glamofb_resume(struct platform_device *pdev) glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD); glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD); - printk(KERN_ERR"spin_lock_init\n"); + dev_dbg(&pdev->dev, "spin_lock_init\n"); spin_lock_init(&gfb->lock_cmd); glamofb_init_regs(gfb); #ifdef CONFIG_MFD_GLAMO_HWACCEL diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c index bc3ed66d43c..acf16360cfd 100644 --- a/drivers/mfd/glamo/glamo-mci.c +++ b/drivers/mfd/glamo/glamo-mci.c @@ -616,7 +616,7 @@ static void glamo_mci_send_request(struct mmc_host *mmc) int insanity_timeout = 1000000; if (host->suspending) { - dev_err(&host->pdev->dev, "IGNORING glamo_mci_send_request while " + dev_dbg(&host->pdev->dev, "REFUSING glamo_mci_send_request while " "suspended\n"); cmd->error = -EIO; if (cmd->data) @@ -774,7 +774,7 @@ static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) static void glamo_mci_reset(struct glamo_mci_host *host) { if (host->suspending) { - dev_err(&host->pdev->dev, "IGNORING glamo_mci_reset while " + dev_info(&host->pdev->dev, "IGNORING glamo_mci_reset while " "suspended\n"); return; } -- cgit v1.2.3 From 21658522b00d047212d7a78cb749648ff3bfeb04 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Tue, 28 Jul 2009 00:41:15 +0400 Subject: pcf50633: use a dedicated workqueue for irq processing Using the default kernel "events" workqueue causes problems with synchronous adc readings if initiated from some task on the same workqueue. I had a deadlock trying to use pcf50633_adc_sync_read from a power_supply class driver because the reading was initiated from the workqueue and it waited for the irq processing to complete (to get the result) and that was put on the same workqueue. Signed-off-by: Paul Fertser --- drivers/mfd/pcf50633-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 29c9395d65f..5006746ff5c 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -448,7 +448,7 @@ static irqreturn_t pcf50633_irq(int irq, void *data) get_device(pcf->dev); disable_irq(pcf->irq); - schedule_work(&pcf->irq_work); + queue_work(pcf->work_queue, &pcf->irq_work); return IRQ_HANDLED; } @@ -579,6 +579,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client, pcf->dev = &client->dev; pcf->i2c_client = client; pcf->irq = client->irq; + pcf->work_queue = create_singlethread_workqueue("pcf50633"); INIT_WORK(&pcf->irq_work, pcf50633_irq_worker); @@ -656,6 +657,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client, return 0; err: + destroy_workqueue(pcf->work_queue); kfree(pcf); return ret; } @@ -666,6 +668,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client) int i; free_irq(pcf->irq, pcf); + destroy_workqueue(pcf->work_queue); platform_device_unregister(pcf->input_pdev); platform_device_unregister(pcf->rtc_pdev); -- cgit v1.2.3 From 1f0f8418cdbacc41ddf3adcce0b8552f075b26d7 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Tue, 28 Jul 2009 00:58:48 +0400 Subject: pcf50633: revise locking for ADC Current implementation is prone to races, this patch attempts to remove all but one (in pcf50633_adc_sync_read). The idea is that we need to guard the queue access only on inserting and removing items. If we insert and there're no more items in the queue it means that the last irq already happened and we need to trigger ADC manually. If not, then the next conversion will be triggered by the irq handler upon completion of the previous. Signed-off-by: Paul Fertser --- drivers/mfd/pcf50633-adc.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c index c2d05becfa9..3d31e97d6a4 100644 --- a/drivers/mfd/pcf50633-adc.c +++ b/drivers/mfd/pcf50633-adc.c @@ -73,15 +73,10 @@ static void trigger_next_adc_job_if_any(struct pcf50633 *pcf) struct pcf50633_adc *adc = __to_adc(pcf); int head; - mutex_lock(&adc->queue_mutex); - head = adc->queue_head; - if (!adc->queue[head]) { - mutex_unlock(&adc->queue_mutex); + if (!adc->queue[head]) return; - } - mutex_unlock(&adc->queue_mutex); adc_setup(pcf, adc->queue[head]->mux, adc->queue[head]->avg); } @@ -99,16 +94,17 @@ adc_enqueue_request(struct pcf50633 *pcf, struct pcf50633_adc_request *req) if (adc->queue[tail]) { mutex_unlock(&adc->queue_mutex); + dev_err(pcf->dev, "ADC queue is full, dropping request\n"); return -EBUSY; } adc->queue[tail] = req; + if (head == tail) + trigger_next_adc_job_if_any(pcf); adc->queue_tail = (tail + 1) & (PCF50633_MAX_ADC_FIFO_DEPTH - 1); mutex_unlock(&adc->queue_mutex); - trigger_next_adc_job_if_any(pcf); - return 0; } @@ -124,6 +120,7 @@ pcf50633_adc_sync_read_callback(struct pcf50633 *pcf, void *param, int result) int pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg) { struct pcf50633_adc_request *req; + int err; /* req is freed when the result is ready, in interrupt handler */ req = kzalloc(sizeof(*req), GFP_KERNEL); @@ -136,9 +133,13 @@ int pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg) req->callback_param = req; init_completion(&req->completion); - adc_enqueue_request(pcf, req); + err = adc_enqueue_request(pcf, req); + if (err) + return err; + wait_for_completion(&req->completion); + /* FIXME by this time req might be already freed */ return req->result; } EXPORT_SYMBOL_GPL(pcf50633_adc_sync_read); @@ -159,9 +160,7 @@ int pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg, req->callback = callback; req->callback_param = callback_param; - adc_enqueue_request(pcf, req); - - return 0; + return adc_enqueue_request(pcf, req); } EXPORT_SYMBOL_GPL(pcf50633_adc_async_read); @@ -184,7 +183,7 @@ static void pcf50633_adc_irq(int irq, void *data) struct pcf50633_adc *adc = data; struct pcf50633 *pcf = adc->pcf; struct pcf50633_adc_request *req; - int head; + int head, res; mutex_lock(&adc->queue_mutex); head = adc->queue_head; @@ -199,12 +198,13 @@ static void pcf50633_adc_irq(int irq, void *data) adc->queue_head = (head + 1) & (PCF50633_MAX_ADC_FIFO_DEPTH - 1); + res = adc_result(pcf); + trigger_next_adc_job_if_any(pcf); + mutex_unlock(&adc->queue_mutex); - req->callback(pcf, req->callback_param, adc_result(pcf)); + req->callback(pcf, req->callback_param, res); kfree(req); - - trigger_next_adc_job_if_any(pcf); } static int __devinit pcf50633_adc_probe(struct platform_device *pdev) -- cgit v1.2.3 From 05d6078079f605ea8740b9e7d87e421d1662222e Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 27 Aug 2009 11:37:49 +0400 Subject: pcf50606: move messages to appropriate log levels Signed-off-by: Arnaud Patard Signed-off-by: Paul Fertser --- drivers/mfd/pcf50606-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/pcf50606-core.c b/drivers/mfd/pcf50606-core.c index 7c4fb42b460..09ce70b9b79 100644 --- a/drivers/mfd/pcf50606-core.c +++ b/drivers/mfd/pcf50606-core.c @@ -282,7 +282,7 @@ out: int pcf50606_irq_mask(struct pcf50606 *pcf, int irq) { - dev_info(pcf->dev, "Masking IRQ %d\n", irq); + dev_dbg(pcf->dev, "Masking IRQ %d\n", irq); return __pcf50606_irq_mask_set(pcf, irq, 1); } @@ -290,7 +290,7 @@ EXPORT_SYMBOL_GPL(pcf50606_irq_mask); int pcf50606_irq_unmask(struct pcf50606 *pcf, int irq) { - dev_info(pcf->dev, "Unmasking IRQ %d\n", irq); + dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq); return __pcf50606_irq_mask_set(pcf, irq, 0); } @@ -330,7 +330,7 @@ static void pcf50606_irq_worker(struct work_struct *work) ret = pcf50606_read_block(pcf, PCF50606_REG_INT1, ARRAY_SIZE(pcf_int), pcf_int); if (ret != ARRAY_SIZE(pcf_int)) { - dev_info(pcf->dev, "Error reading INT registers\n"); + dev_err(pcf->dev, "Error reading INT registers\n"); /* * If this doesn't ACK the interrupt to the chip, we'll be -- cgit v1.2.3 From 4616eea5f3b3a603a03f31721de3eeb42dbd7711 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 27 Aug 2009 11:39:33 +0400 Subject: pcf50633: move messages to appropriate log levels Signed-off-by: Arnaud Patard Signed-off-by: Paul Fertser --- drivers/mfd/pcf50633-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 5006746ff5c..b3c96015600 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -291,7 +291,7 @@ out: int pcf50633_irq_mask(struct pcf50633 *pcf, int irq) { - dev_info(pcf->dev, "Masking IRQ %d\n", irq); + dev_dbg(pcf->dev, "Masking IRQ %d\n", irq); return __pcf50633_irq_mask_set(pcf, irq, 1); } @@ -299,7 +299,7 @@ EXPORT_SYMBOL_GPL(pcf50633_irq_mask); int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq) { - dev_info(pcf->dev, "Unmasking IRQ %d\n", irq); + dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq); return __pcf50633_irq_mask_set(pcf, irq, 0); } -- cgit v1.2.3