diff options
author | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2015-07-24 09:59:43 -0400 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2015-09-05 07:19:11 -0400 |
commit | b6a57c955c362cb9d6ace991cdd77376849abb44 (patch) | |
tree | 1f72fceecc5dc2b7a307563a30ff1095a49d6705 | |
parent | 15d3bdc23eb54c50b2a5f143325fe83c3ab0dd27 (diff) |
rtc: rx8025: Convert to threaded IRQ
The driver currently emulates the concept of threaded IRQ using a
workqueue, switch to threaded IRQ instead.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
-rw-r--r-- | drivers/rtc/rtc-rx8025.c | 37 |
1 files changed, 4 insertions, 33 deletions
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index a943e1c08263..d8737713135d 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c | |||
@@ -71,9 +71,7 @@ MODULE_DEVICE_TABLE(i2c, rx8025_id); | |||
71 | struct rx8025_data { | 71 | struct rx8025_data { |
72 | struct i2c_client *client; | 72 | struct i2c_client *client; |
73 | struct rtc_device *rtc; | 73 | struct rtc_device *rtc; |
74 | struct work_struct work; | ||
75 | u8 ctrl1; | 74 | u8 ctrl1; |
76 | unsigned exiting:1; | ||
77 | }; | 75 | }; |
78 | 76 | ||
79 | static int rx8025_read_reg(struct i2c_client *client, int number, u8 *value) | 77 | static int rx8025_read_reg(struct i2c_client *client, int number, u8 *value) |
@@ -128,26 +126,12 @@ static int rx8025_write_regs(struct i2c_client *client, | |||
128 | return ret; | 126 | return ret; |
129 | } | 127 | } |
130 | 128 | ||
131 | static irqreturn_t rx8025_irq(int irq, void *dev_id) | 129 | static irqreturn_t rx8025_handle_irq(int irq, void *dev_id) |
132 | { | 130 | { |
133 | struct i2c_client *client = dev_id; | 131 | struct i2c_client *client = dev_id; |
134 | struct rx8025_data *rx8025 = i2c_get_clientdata(client); | 132 | struct rx8025_data *rx8025 = i2c_get_clientdata(client); |
135 | |||
136 | disable_irq_nosync(irq); | ||
137 | schedule_work(&rx8025->work); | ||
138 | return IRQ_HANDLED; | ||
139 | } | ||
140 | |||
141 | static void rx8025_work(struct work_struct *work) | ||
142 | { | ||
143 | struct rx8025_data *rx8025 = container_of(work, struct rx8025_data, | ||
144 | work); | ||
145 | struct i2c_client *client = rx8025->client; | ||
146 | struct mutex *lock = &rx8025->rtc->ops_lock; | ||
147 | u8 status; | 133 | u8 status; |
148 | 134 | ||
149 | mutex_lock(lock); | ||
150 | |||
151 | if (rx8025_read_reg(client, RX8025_REG_CTRL2, &status)) | 135 | if (rx8025_read_reg(client, RX8025_REG_CTRL2, &status)) |
152 | goto out; | 136 | goto out; |
153 | 137 | ||
@@ -175,10 +159,7 @@ static void rx8025_work(struct work_struct *work) | |||
175 | status | RX8025_BIT_CTRL2_XST); | 159 | status | RX8025_BIT_CTRL2_XST); |
176 | 160 | ||
177 | out: | 161 | out: |
178 | if (!rx8025->exiting) | 162 | return IRQ_HANDLED; |
179 | enable_irq(client->irq); | ||
180 | |||
181 | mutex_unlock(lock); | ||
182 | } | 163 | } |
183 | 164 | ||
184 | static int rx8025_get_time(struct device *dev, struct rtc_time *dt) | 165 | static int rx8025_get_time(struct device *dev, struct rtc_time *dt) |
@@ -550,7 +531,6 @@ static int rx8025_probe(struct i2c_client *client, | |||
550 | 531 | ||
551 | rx8025->client = client; | 532 | rx8025->client = client; |
552 | i2c_set_clientdata(client, rx8025); | 533 | i2c_set_clientdata(client, rx8025); |
553 | INIT_WORK(&rx8025->work, rx8025_work); | ||
554 | 534 | ||
555 | err = rx8025_init_client(client, &need_reset); | 535 | err = rx8025_init_client(client, &need_reset); |
556 | if (err) | 536 | if (err) |
@@ -574,7 +554,7 @@ static int rx8025_probe(struct i2c_client *client, | |||
574 | 554 | ||
575 | if (client->irq > 0) { | 555 | if (client->irq > 0) { |
576 | dev_info(&client->dev, "IRQ %d supplied\n", client->irq); | 556 | dev_info(&client->dev, "IRQ %d supplied\n", client->irq); |
577 | err = request_irq(client->irq, rx8025_irq, | 557 | err = request_threaded_irq(client->irq, NULL, rx8025_handle_irq, |
578 | 0, "rx8025", client); | 558 | 0, "rx8025", client); |
579 | if (err) { | 559 | if (err) { |
580 | dev_err(&client->dev, "unable to request IRQ\n"); | 560 | dev_err(&client->dev, "unable to request IRQ\n"); |
@@ -602,17 +582,8 @@ errout: | |||
602 | 582 | ||
603 | static int rx8025_remove(struct i2c_client *client) | 583 | static int rx8025_remove(struct i2c_client *client) |
604 | { | 584 | { |
605 | struct rx8025_data *rx8025 = i2c_get_clientdata(client); | 585 | if (client->irq > 0) |
606 | struct mutex *lock = &rx8025->rtc->ops_lock; | ||
607 | |||
608 | if (client->irq > 0) { | ||
609 | mutex_lock(lock); | ||
610 | rx8025->exiting = 1; | ||
611 | mutex_unlock(lock); | ||
612 | |||
613 | free_irq(client->irq, client); | 586 | free_irq(client->irq, client); |
614 | cancel_work_sync(&rx8025->work); | ||
615 | } | ||
616 | 587 | ||
617 | rx8025_sysfs_unregister(&client->dev); | 588 | rx8025_sysfs_unregister(&client->dev); |
618 | return 0; | 589 | return 0; |