aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-28 11:28:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-28 11:28:50 -0400
commit9ffc1699e36abd5baee188c8e36b1bb27d0d4278 (patch)
treece07bb773305b38ec672e1e37f48bd6ecfdc8dc4
parenta01386924874c4d6d67f8a34e66f04452c2abb69 (diff)
parent958585f58f675a3c2855c7d91b6fdd2875552d0b (diff)
Merge branch 'i2c-for-linus' of git://aeryn.fluff.org.uk/bjdooks/linux
* 'i2c-for-linus' of git://aeryn.fluff.org.uk/bjdooks/linux: i2c: Blackfin I2C Driver: Functional power management support i2c: Documentation: upgrading clients HOWTO i2c: S3C24XX I2C frequency scaling support. i2c: i2c_gpio: keep probe resident for hotplugged devices. i2c: S3C2410: Pass the I2C bus number via drivers platform data
-rw-r--r--Documentation/i2c/upgrading-clients281
-rw-r--r--drivers/i2c/busses/i2c-bfin-twi.c35
-rw-r--r--drivers/i2c/busses/i2c-gpio.c9
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c129
-rw-r--r--include/asm-arm/plat-s3c/iic.h1
5 files changed, 426 insertions, 29 deletions
diff --git a/Documentation/i2c/upgrading-clients b/Documentation/i2c/upgrading-clients
new file mode 100644
index 000000000000..9a45f9bb6a25
--- /dev/null
+++ b/Documentation/i2c/upgrading-clients
@@ -0,0 +1,281 @@
1Upgrading I2C Drivers to the new 2.6 Driver Model
2=================================================
3
4Ben Dooks <ben-linux@fluff.org>
5
6Introduction
7------------
8
9This guide outlines how to alter existing Linux 2.6 client drivers from
10the old to the new new binding methods.
11
12
13Example old-style driver
14------------------------
15
16
17struct example_state {
18 struct i2c_client client;
19 ....
20};
21
22static struct i2c_driver example_driver;
23
24static unsigned short ignore[] = { I2C_CLIENT_END };
25static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
26
27I2C_CLIENT_INSMOD;
28
29static int example_attach(struct i2c_adapter *adap, int addr, int kind)
30{
31 struct example_state *state;
32 struct device *dev = &adap->dev; /* to use for dev_ reports */
33 int ret;
34
35 state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
36 if (state == NULL) {
37 dev_err(dev, "failed to create our state\n");
38 return -ENOMEM;
39 }
40
41 example->client.addr = addr;
42 example->client.flags = 0;
43 example->client.adapter = adap;
44
45 i2c_set_clientdata(&state->i2c_client, state);
46 strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
47
48 ret = i2c_attach_client(&state->i2c_client);
49 if (ret < 0) {
50 dev_err(dev, "failed to attach client\n");
51 kfree(state);
52 return ret;
53 }
54
55 dev = &state->i2c_client.dev;
56
57 /* rest of the initialisation goes here. */
58
59 dev_info(dev, "example client created\n");
60
61 return 0;
62}
63
64static int __devexit example_detach(struct i2c_client *client)
65{
66 struct example_state *state = i2c_get_clientdata(client);
67
68 i2c_detach_client(client);
69 kfree(state);
70 return 0;
71}
72
73static int example_attach_adapter(struct i2c_adapter *adap)
74{
75 return i2c_probe(adap, &addr_data, example_attach);
76}
77
78static struct i2c_driver example_driver = {
79 .driver = {
80 .owner = THIS_MODULE,
81 .name = "example",
82 },
83 .attach_adapter = example_attach_adapter,
84 .detach_client = __devexit_p(example_detach),
85 .suspend = example_suspend,
86 .resume = example_resume,
87};
88
89
90Updating the client
91-------------------
92
93The new style binding model will check against a list of supported
94devices and their associated address supplied by the code registering
95the busses. This means that the driver .attach_adapter and
96.detach_adapter methods can be removed, along with the addr_data,
97as follows:
98
99- static struct i2c_driver example_driver;
100
101- static unsigned short ignore[] = { I2C_CLIENT_END };
102- static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
103
104- I2C_CLIENT_INSMOD;
105
106- static int example_attach_adapter(struct i2c_adapter *adap)
107- {
108- return i2c_probe(adap, &addr_data, example_attach);
109- }
110
111 static struct i2c_driver example_driver = {
112- .attach_adapter = example_attach_adapter,
113- .detach_client = __devexit_p(example_detach),
114 }
115
116Add the probe and remove methods to the i2c_driver, as so:
117
118 static struct i2c_driver example_driver = {
119+ .probe = example_probe,
120+ .remove = __devexit_p(example_remove),
121 }
122
123Change the example_attach method to accept the new parameters
124which include the i2c_client that it will be working with:
125
126- static int example_attach(struct i2c_adapter *adap, int addr, int kind)
127+ static int example_probe(struct i2c_client *client,
128+ const struct i2c_device_id *id)
129
130Change the name of example_attach to example_probe to align it with the
131i2c_driver entry names. The rest of the probe routine will now need to be
132changed as the i2c_client has already been setup for use.
133
134The necessary client fields have already been setup before
135the probe function is called, so the following client setup
136can be removed:
137
138- example->client.addr = addr;
139- example->client.flags = 0;
140- example->client.adapter = adap;
141-
142- strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE);
143
144The i2c_set_clientdata is now:
145
146- i2c_set_clientdata(&state->client, state);
147+ i2c_set_clientdata(client, state);
148
149The call to i2c_attach_client is no longer needed, if the probe
150routine exits successfully, then the driver will be automatically
151attached by the core. Change the probe routine as so:
152
153- ret = i2c_attach_client(&state->i2c_client);
154- if (ret < 0) {
155- dev_err(dev, "failed to attach client\n");
156- kfree(state);
157- return ret;
158- }
159
160
161Remove the storage of 'struct i2c_client' from the 'struct example_state'
162as we are provided with the i2c_client in our example_probe. Instead we
163store a pointer to it for when it is needed.
164
165struct example_state {
166- struct i2c_client client;
167+ struct i2c_client *client;
168
169the new i2c client as so:
170
171- struct device *dev = &adap->dev; /* to use for dev_ reports */
172+ struct device *dev = &i2c_client->dev; /* to use for dev_ reports */
173
174And remove the change after our client is attached, as the driver no
175longer needs to register a new client structure with the core:
176
177- dev = &state->i2c_client.dev;
178
179In the probe routine, ensure that the new state has the client stored
180in it:
181
182static int example_probe(struct i2c_client *i2c_client,
183 const struct i2c_device_id *id)
184{
185 struct example_state *state;
186 struct device *dev = &i2c_client->dev;
187 int ret;
188
189 state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
190 if (state == NULL) {
191 dev_err(dev, "failed to create our state\n");
192 return -ENOMEM;
193 }
194
195+ state->client = i2c_client;
196
197Update the detach method, by changing the name to _remove and
198to delete the i2c_detach_client call. It is possible that you
199can also remove the ret variable as it is not not needed for
200any of the core functions.
201
202- static int __devexit example_detach(struct i2c_client *client)
203+ static int __devexit example_remove(struct i2c_client *client)
204{
205 struct example_state *state = i2c_get_clientdata(client);
206
207- i2c_detach_client(client);
208
209And finally ensure that we have the correct ID table for the i2c-core
210and other utilities:
211
212+ struct i2c_device_id example_idtable[] = {
213+ { "example", 0 },
214+ { }
215+};
216+
217+MODULE_DEVICE_TABLE(i2c, example_idtable);
218
219static struct i2c_driver example_driver = {
220 .driver = {
221 .owner = THIS_MODULE,
222 .name = "example",
223 },
224+ .id_table = example_ids,
225
226
227Our driver should now look like this:
228
229struct example_state {
230 struct i2c_client *client;
231 ....
232};
233
234static int example_probe(struct i2c_client *client,
235 const struct i2c_device_id *id)
236{
237 struct example_state *state;
238 struct device *dev = &client->dev;
239
240 state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
241 if (state == NULL) {
242 dev_err(dev, "failed to create our state\n");
243 return -ENOMEM;
244 }
245
246 state->client = client;
247 i2c_set_clientdata(client, state);
248
249 /* rest of the initialisation goes here. */
250
251 dev_info(dev, "example client created\n");
252
253 return 0;
254}
255
256static int __devexit example_remove(struct i2c_client *client)
257{
258 struct example_state *state = i2c_get_clientdata(client);
259
260 kfree(state);
261 return 0;
262}
263
264static struct i2c_device_id example_idtable[] = {
265 { "example", 0 },
266 { }
267};
268
269MODULE_DEVICE_TABLE(i2c, example_idtable);
270
271static struct i2c_driver example_driver = {
272 .driver = {
273 .owner = THIS_MODULE,
274 .name = "example",
275 },
276 .id_table = example_idtable,
277 .probe = example_probe,
278 .remove = __devexit_p(example_remove),
279 .suspend = example_suspend,
280 .resume = example_resume,
281};
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
index 48d084bdf7c8..3c855ff2992f 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
@@ -49,6 +49,8 @@ struct bfin_twi_iface {
49 struct i2c_msg *pmsg; 49 struct i2c_msg *pmsg;
50 int msg_num; 50 int msg_num;
51 int cur_msg; 51 int cur_msg;
52 u16 saved_clkdiv;
53 u16 saved_control;
52 void __iomem *regs_base; 54 void __iomem *regs_base;
53}; 55};
54 56
@@ -565,32 +567,43 @@ static u32 bfin_twi_functionality(struct i2c_adapter *adap)
565 I2C_FUNC_I2C; 567 I2C_FUNC_I2C;
566} 568}
567 569
568
569static struct i2c_algorithm bfin_twi_algorithm = { 570static struct i2c_algorithm bfin_twi_algorithm = {
570 .master_xfer = bfin_twi_master_xfer, 571 .master_xfer = bfin_twi_master_xfer,
571 .smbus_xfer = bfin_twi_smbus_xfer, 572 .smbus_xfer = bfin_twi_smbus_xfer,
572 .functionality = bfin_twi_functionality, 573 .functionality = bfin_twi_functionality,
573}; 574};
574 575
575 576static int i2c_bfin_twi_suspend(struct platform_device *pdev, pm_message_t state)
576static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
577{ 577{
578 struct bfin_twi_iface *iface = platform_get_drvdata(dev); 578 struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
579
580 iface->saved_clkdiv = read_CLKDIV(iface);
581 iface->saved_control = read_CONTROL(iface);
582
583 free_irq(iface->irq, iface);
579 584
580 /* Disable TWI */ 585 /* Disable TWI */
581 write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA); 586 write_CONTROL(iface, iface->saved_control & ~TWI_ENA);
582 SSYNC();
583 587
584 return 0; 588 return 0;
585} 589}
586 590
587static int i2c_bfin_twi_resume(struct platform_device *dev) 591static int i2c_bfin_twi_resume(struct platform_device *pdev)
588{ 592{
589 struct bfin_twi_iface *iface = platform_get_drvdata(dev); 593 struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
590 594
591 /* Enable TWI */ 595 int rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
592 write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA); 596 IRQF_DISABLED, pdev->name, iface);
593 SSYNC(); 597 if (rc) {
598 dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
599 return -ENODEV;
600 }
601
602 /* Resume TWI interface clock as specified */
603 write_CLKDIV(iface, iface->saved_clkdiv);
604
605 /* Resume TWI */
606 write_CONTROL(iface, iface->saved_control);
594 607
595 return 0; 608 return 0;
596} 609}
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 79b455a1f090..32104eac8d3d 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -77,7 +77,7 @@ static int i2c_gpio_getscl(void *data)
77 return gpio_get_value(pdata->scl_pin); 77 return gpio_get_value(pdata->scl_pin);
78} 78}
79 79
80static int __init i2c_gpio_probe(struct platform_device *pdev) 80static int __devinit i2c_gpio_probe(struct platform_device *pdev)
81{ 81{
82 struct i2c_gpio_platform_data *pdata; 82 struct i2c_gpio_platform_data *pdata;
83 struct i2c_algo_bit_data *bit_data; 83 struct i2c_algo_bit_data *bit_data;
@@ -174,7 +174,7 @@ err_alloc_adap:
174 return ret; 174 return ret;
175} 175}
176 176
177static int __exit i2c_gpio_remove(struct platform_device *pdev) 177static int __devexit i2c_gpio_remove(struct platform_device *pdev)
178{ 178{
179 struct i2c_gpio_platform_data *pdata; 179 struct i2c_gpio_platform_data *pdata;
180 struct i2c_adapter *adap; 180 struct i2c_adapter *adap;
@@ -196,14 +196,15 @@ static struct platform_driver i2c_gpio_driver = {
196 .name = "i2c-gpio", 196 .name = "i2c-gpio",
197 .owner = THIS_MODULE, 197 .owner = THIS_MODULE,
198 }, 198 },
199 .remove = __exit_p(i2c_gpio_remove), 199 .probe = i2c_gpio_probe,
200 .remove = __devexit_p(i2c_gpio_remove),
200}; 201};
201 202
202static int __init i2c_gpio_init(void) 203static int __init i2c_gpio_init(void)
203{ 204{
204 int ret; 205 int ret;
205 206
206 ret = platform_driver_probe(&i2c_gpio_driver, i2c_gpio_probe); 207 ret = platform_driver_register(&i2c_gpio_driver);
207 if (ret) 208 if (ret)
208 printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); 209 printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret);
209 210
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 007390ad9810..4864723c7425 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -33,6 +33,7 @@
33#include <linux/err.h> 33#include <linux/err.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/clk.h> 35#include <linux/clk.h>
36#include <linux/cpufreq.h>
36 37
37#include <asm/hardware.h> 38#include <asm/hardware.h>
38#include <asm/irq.h> 39#include <asm/irq.h>
@@ -64,6 +65,7 @@ struct s3c24xx_i2c {
64 unsigned int tx_setup; 65 unsigned int tx_setup;
65 66
66 enum s3c24xx_i2c_state state; 67 enum s3c24xx_i2c_state state;
68 unsigned long clkrate;
67 69
68 void __iomem *regs; 70 void __iomem *regs;
69 struct clk *clk; 71 struct clk *clk;
@@ -71,6 +73,10 @@ struct s3c24xx_i2c {
71 struct resource *irq; 73 struct resource *irq;
72 struct resource *ioarea; 74 struct resource *ioarea;
73 struct i2c_adapter adap; 75 struct i2c_adapter adap;
76
77#ifdef CONFIG_CPU_FREQ
78 struct notifier_block freq_transition;
79#endif
74}; 80};
75 81
76/* default platform data to use if not supplied in the platform_device 82/* default platform data to use if not supplied in the platform_device
@@ -501,6 +507,9 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int
501 unsigned long timeout; 507 unsigned long timeout;
502 int ret; 508 int ret;
503 509
510 if (!readl(i2c->regs + S3C2410_IICCON) & S3C2410_IICCON_IRQEN)
511 return -EIO;
512
504 ret = s3c24xx_i2c_set_master(i2c); 513 ret = s3c24xx_i2c_set_master(i2c);
505 if (ret != 0) { 514 if (ret != 0) {
506 dev_err(i2c->dev, "cannot get bus (error %d)\n", ret); 515 dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
@@ -636,27 +645,28 @@ static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
636 return (diff >= -2 && diff <= 2); 645 return (diff >= -2 && diff <= 2);
637} 646}
638 647
639/* s3c24xx_i2c_getdivisor 648/* s3c24xx_i2c_clockrate
640 * 649 *
641 * work out a divisor for the user requested frequency setting, 650 * work out a divisor for the user requested frequency setting,
642 * either by the requested frequency, or scanning the acceptable 651 * either by the requested frequency, or scanning the acceptable
643 * range of frequencies until something is found 652 * range of frequencies until something is found
644*/ 653*/
645 654
646static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c, 655static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
647 struct s3c2410_platform_i2c *pdata,
648 unsigned long *iicon,
649 unsigned int *got)
650{ 656{
657 struct s3c2410_platform_i2c *pdata;
651 unsigned long clkin = clk_get_rate(i2c->clk); 658 unsigned long clkin = clk_get_rate(i2c->clk);
652
653 unsigned int divs, div1; 659 unsigned int divs, div1;
660 u32 iiccon;
654 int freq; 661 int freq;
655 int start, end; 662 int start, end;
656 663
664 i2c->clkrate = clkin;
665
666 pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent);
657 clkin /= 1000; /* clkin now in KHz */ 667 clkin /= 1000; /* clkin now in KHz */
658 668
659 dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n", 669 dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
660 pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq); 670 pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq);
661 671
662 if (pdata->bus_freq != 0) { 672 if (pdata->bus_freq != 0) {
@@ -688,11 +698,79 @@ static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c,
688 698
689 found: 699 found:
690 *got = freq; 700 *got = freq;
691 *iicon |= (divs-1); 701
692 *iicon |= (div1 == 512) ? S3C2410_IICCON_TXDIV_512 : 0; 702 iiccon = readl(i2c->regs + S3C2410_IICCON);
703 iiccon &= ~(S3C2410_IICCON_SCALEMASK | S3C2410_IICCON_TXDIV_512);
704 iiccon |= (divs-1);
705
706 if (div1 == 512)
707 iiccon |= S3C2410_IICCON_TXDIV_512;
708
709 writel(iiccon, i2c->regs + S3C2410_IICCON);
710
711 return 0;
712}
713
714#ifdef CONFIG_CPU_FREQ
715
716#define freq_to_i2c(_n) container_of(_n, struct s3c24xx_i2c, freq_transition)
717
718static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
719 unsigned long val, void *data)
720{
721 struct s3c24xx_i2c *i2c = freq_to_i2c(nb);
722 unsigned long flags;
723 unsigned int got;
724 int delta_f;
725 int ret;
726
727 delta_f = clk_get_rate(i2c->clk) - i2c->clkrate;
728
729 /* if we're post-change and the input clock has slowed down
730 * or at pre-change and the clock is about to speed up, then
731 * adjust our clock rate. <0 is slow, >0 speedup.
732 */
733
734 if ((val == CPUFREQ_POSTCHANGE && delta_f < 0) ||
735 (val == CPUFREQ_PRECHANGE && delta_f > 0)) {
736 spin_lock_irqsave(&i2c->lock, flags);
737 ret = s3c24xx_i2c_clockrate(i2c, &got);
738 spin_unlock_irqrestore(&i2c->lock, flags);
739
740 if (ret < 0)
741 dev_err(i2c->dev, "cannot find frequency\n");
742 else
743 dev_info(i2c->dev, "setting freq %d\n", got);
744 }
745
746 return 0;
747}
748
749static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
750{
751 i2c->freq_transition.notifier_call = s3c24xx_i2c_cpufreq_transition;
752
753 return cpufreq_register_notifier(&i2c->freq_transition,
754 CPUFREQ_TRANSITION_NOTIFIER);
755}
756
757static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
758{
759 cpufreq_unregister_notifier(&i2c->freq_transition,
760 CPUFREQ_TRANSITION_NOTIFIER);
761}
762
763#else
764static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
765{
693 return 0; 766 return 0;
694} 767}
695 768
769static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
770{
771}
772#endif
773
696/* s3c24xx_i2c_init 774/* s3c24xx_i2c_init
697 * 775 *
698 * initialise the controller, set the IO lines and frequency 776 * initialise the controller, set the IO lines and frequency
@@ -719,9 +797,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
719 797
720 dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr); 798 dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
721 799
800 writel(iicon, i2c->regs + S3C2410_IICCON);
801
722 /* we need to work out the divisors for the clock... */ 802 /* we need to work out the divisors for the clock... */
723 803
724 if (s3c24xx_i2c_getdivisor(i2c, pdata, &iicon, &freq) != 0) { 804 if (s3c24xx_i2c_clockrate(i2c, &freq) != 0) {
805 writel(0, i2c->regs + S3C2410_IICCON);
725 dev_err(i2c->dev, "cannot meet bus frequency required\n"); 806 dev_err(i2c->dev, "cannot meet bus frequency required\n");
726 return -EINVAL; 807 return -EINVAL;
727 } 808 }
@@ -730,8 +811,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
730 811
731 dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq); 812 dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
732 dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); 813 dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon);
733
734 writel(iicon, i2c->regs + S3C2410_IICCON);
735 814
736 /* check for s3c2440 i2c controller */ 815 /* check for s3c2440 i2c controller */
737 816
@@ -752,9 +831,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
752static int s3c24xx_i2c_probe(struct platform_device *pdev) 831static int s3c24xx_i2c_probe(struct platform_device *pdev)
753{ 832{
754 struct s3c24xx_i2c *i2c = &s3c24xx_i2c; 833 struct s3c24xx_i2c *i2c = &s3c24xx_i2c;
834 struct s3c2410_platform_i2c *pdata;
755 struct resource *res; 835 struct resource *res;
756 int ret; 836 int ret;
757 837
838 pdata = s3c24xx_i2c_get_platformdata(&pdev->dev);
839
758 /* find the clock and enable it */ 840 /* find the clock and enable it */
759 841
760 i2c->dev = &pdev->dev; 842 i2c->dev = &pdev->dev;
@@ -832,17 +914,34 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
832 dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res, 914 dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res,
833 (unsigned long)res->start); 915 (unsigned long)res->start);
834 916
835 ret = i2c_add_adapter(&i2c->adap); 917 ret = s3c24xx_i2c_register_cpufreq(i2c);
836 if (ret < 0) { 918 if (ret < 0) {
837 dev_err(&pdev->dev, "failed to add bus to i2c core\n"); 919 dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
838 goto err_irq; 920 goto err_irq;
839 } 921 }
840 922
923 /* Note, previous versions of the driver used i2c_add_adapter()
924 * to add the bus at any number. We now pass the bus number via
925 * the platform data, so if unset it will now default to always
926 * being bus 0.
927 */
928
929 i2c->adap.nr = pdata->bus_num;
930
931 ret = i2c_add_numbered_adapter(&i2c->adap);
932 if (ret < 0) {
933 dev_err(&pdev->dev, "failed to add bus to i2c core\n");
934 goto err_cpufreq;
935 }
936
841 platform_set_drvdata(pdev, i2c); 937 platform_set_drvdata(pdev, i2c);
842 938
843 dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id); 939 dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
844 return 0; 940 return 0;
845 941
942 err_cpufreq:
943 s3c24xx_i2c_deregister_cpufreq(i2c);
944
846 err_irq: 945 err_irq:
847 free_irq(i2c->irq->start, i2c); 946 free_irq(i2c->irq->start, i2c);
848 947
@@ -870,6 +969,8 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
870{ 969{
871 struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); 970 struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
872 971
972 s3c24xx_i2c_deregister_cpufreq(i2c);
973
873 i2c_del_adapter(&i2c->adap); 974 i2c_del_adapter(&i2c->adap);
874 free_irq(i2c->irq->start, i2c); 975 free_irq(i2c->irq->start, i2c);
875 976
diff --git a/include/asm-arm/plat-s3c/iic.h b/include/asm-arm/plat-s3c/iic.h
index 71211c8b5384..d08a1f2863e4 100644
--- a/include/asm-arm/plat-s3c/iic.h
+++ b/include/asm-arm/plat-s3c/iic.h
@@ -21,6 +21,7 @@
21*/ 21*/
22 22
23struct s3c2410_platform_i2c { 23struct s3c2410_platform_i2c {
24 int bus_num; /* bus number to use */
24 unsigned int flags; 25 unsigned int flags;
25 unsigned int slave_addr; /* slave address for controller */ 26 unsigned int slave_addr; /* slave address for controller */
26 unsigned long bus_freq; /* standard bus frequency */ 27 unsigned long bus_freq; /* standard bus frequency */