diff options
Diffstat (limited to 'drivers/usb/host/ohci-pnx4008.c')
-rw-r--r-- | drivers/usb/host/ohci-pnx4008.c | 85 |
1 files changed, 36 insertions, 49 deletions
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index e306ca6aef3d..100bf3d8437c 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -106,65 +106,34 @@ extern int ocpi_enable(void); | |||
106 | 106 | ||
107 | static struct clk *usb_clk; | 107 | static struct clk *usb_clk; |
108 | 108 | ||
109 | static int isp1301_probe(struct i2c_adapter *adap); | ||
110 | static int isp1301_detach(struct i2c_client *client); | ||
111 | |||
112 | static const unsigned short normal_i2c[] = | 109 | static const unsigned short normal_i2c[] = |
113 | { ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END }; | 110 | { ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END }; |
114 | static const unsigned short dummy_i2c_addrlist[] = { I2C_CLIENT_END }; | ||
115 | |||
116 | static struct i2c_client_address_data addr_data = { | ||
117 | .normal_i2c = normal_i2c, | ||
118 | .probe = dummy_i2c_addrlist, | ||
119 | .ignore = dummy_i2c_addrlist, | ||
120 | }; | ||
121 | |||
122 | struct i2c_driver isp1301_driver = { | ||
123 | .driver = { | ||
124 | .name = "isp1301_pnx", | ||
125 | }, | ||
126 | .attach_adapter = isp1301_probe, | ||
127 | .detach_client = isp1301_detach, | ||
128 | }; | ||
129 | 111 | ||
130 | static int isp1301_attach(struct i2c_adapter *adap, int addr, int kind) | 112 | static int isp1301_probe(struct i2c_client *client, |
113 | const struct i2c_device_id *id) | ||
131 | { | 114 | { |
132 | struct i2c_client *c; | ||
133 | int err; | ||
134 | |||
135 | c = kzalloc(sizeof(*c), GFP_KERNEL); | ||
136 | if (!c) | ||
137 | return -ENOMEM; | ||
138 | |||
139 | strlcpy(c->name, "isp1301_pnx", I2C_NAME_SIZE); | ||
140 | c->flags = 0; | ||
141 | c->addr = addr; | ||
142 | c->adapter = adap; | ||
143 | c->driver = &isp1301_driver; | ||
144 | |||
145 | err = i2c_attach_client(c); | ||
146 | if (err) { | ||
147 | kfree(c); | ||
148 | return err; | ||
149 | } | ||
150 | |||
151 | isp1301_i2c_client = c; | ||
152 | |||
153 | return 0; | 115 | return 0; |
154 | } | 116 | } |
155 | 117 | ||
156 | static int isp1301_probe(struct i2c_adapter *adap) | 118 | static int isp1301_remove(struct i2c_client *client) |
157 | { | 119 | { |
158 | return i2c_probe(adap, &addr_data, isp1301_attach); | ||
159 | } | ||
160 | |||
161 | static int isp1301_detach(struct i2c_client *client) | ||
162 | { | ||
163 | i2c_detach_client(client); | ||
164 | kfree(isp1301_i2c_client); | ||
165 | return 0; | 120 | return 0; |
166 | } | 121 | } |
167 | 122 | ||
123 | const struct i2c_device_id isp1301_id[] = { | ||
124 | { "isp1301_pnx", 0 }, | ||
125 | { } | ||
126 | }; | ||
127 | |||
128 | struct i2c_driver isp1301_driver = { | ||
129 | .driver = { | ||
130 | .name = "isp1301_pnx", | ||
131 | }, | ||
132 | .probe = isp1301_probe, | ||
133 | .remove = isp1301_remove, | ||
134 | .id_table = isp1301_id, | ||
135 | }; | ||
136 | |||
168 | static void i2c_write(u8 buf, u8 subaddr) | 137 | static void i2c_write(u8 buf, u8 subaddr) |
169 | { | 138 | { |
170 | char tmpbuf[2]; | 139 | char tmpbuf[2]; |
@@ -328,6 +297,8 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) | |||
328 | struct usb_hcd *hcd = 0; | 297 | struct usb_hcd *hcd = 0; |
329 | struct ohci_hcd *ohci; | 298 | struct ohci_hcd *ohci; |
330 | const struct hc_driver *driver = &ohci_pnx4008_hc_driver; | 299 | const struct hc_driver *driver = &ohci_pnx4008_hc_driver; |
300 | struct i2c_adapter *i2c_adap; | ||
301 | struct i2c_board_info i2c_info; | ||
331 | 302 | ||
332 | int ret = 0, irq; | 303 | int ret = 0, irq; |
333 | 304 | ||
@@ -351,9 +322,20 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) | |||
351 | 322 | ||
352 | ret = i2c_add_driver(&isp1301_driver); | 323 | ret = i2c_add_driver(&isp1301_driver); |
353 | if (ret < 0) { | 324 | if (ret < 0) { |
354 | err("failed to connect I2C to ISP1301 USB Transceiver"); | 325 | err("failed to add ISP1301 driver"); |
355 | goto out; | 326 | goto out; |
356 | } | 327 | } |
328 | i2c_adap = i2c_get_adapter(2); | ||
329 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); | ||
330 | strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE); | ||
331 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, | ||
332 | normal_i2c); | ||
333 | i2c_put_adapter(i2c_adap); | ||
334 | if (!isp1301_i2c_client) { | ||
335 | err("failed to connect I2C to ISP1301 USB Transceiver"); | ||
336 | ret = -ENODEV; | ||
337 | goto out_i2c_driver; | ||
338 | } | ||
357 | 339 | ||
358 | isp1301_configure(); | 340 | isp1301_configure(); |
359 | 341 | ||
@@ -429,6 +411,9 @@ out3: | |||
429 | out2: | 411 | out2: |
430 | clk_put(usb_clk); | 412 | clk_put(usb_clk); |
431 | out1: | 413 | out1: |
414 | i2c_unregister_client(isp1301_i2c_client); | ||
415 | isp1301_i2c_client = NULL; | ||
416 | out_i2c_driver: | ||
432 | i2c_del_driver(&isp1301_driver); | 417 | i2c_del_driver(&isp1301_driver); |
433 | out: | 418 | out: |
434 | return ret; | 419 | return ret; |
@@ -445,6 +430,8 @@ static int usb_hcd_pnx4008_remove(struct platform_device *pdev) | |||
445 | pnx4008_unset_usb_bits(); | 430 | pnx4008_unset_usb_bits(); |
446 | clk_disable(usb_clk); | 431 | clk_disable(usb_clk); |
447 | clk_put(usb_clk); | 432 | clk_put(usb_clk); |
433 | i2c_unregister_client(isp1301_i2c_client); | ||
434 | isp1301_i2c_client = NULL; | ||
448 | i2c_del_driver(&isp1301_driver); | 435 | i2c_del_driver(&isp1301_driver); |
449 | 436 | ||
450 | platform_set_drvdata(pdev, NULL); | 437 | platform_set_drvdata(pdev, NULL); |