diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-07-20 18:44:45 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-18 10:46:19 -0400 |
commit | f899fc64cda8569d0529452aafc0da31c042df2e (patch) | |
tree | 61b6d32abe3524b83abc9d8b9382e3f82225cd64 /drivers/gpu/drm/i915/intel_i2c.c | |
parent | 373a3cf744c774478f44921c50011b896ab08f9d (diff) |
drm/i915: use GMBUS to manage i2c links
Use the GMBUS interface rather than direct bit banging to grab the EDID
over DDC (and for other forms of auxiliary communication with external
display controllers). The hope is that this method will be much faster
and more reliable than bit banging for fetching EDIDs from buggy monitors
or through switches, though we still preserve the bit banging as a
fallback in case GMBUS fails.
Based on an original patch by Jesse Barnes.
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_i2c.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 381 |
1 files changed, 268 insertions, 113 deletions
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index d3d65a9cfba1..6f4d128935ac 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> | 2 | * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> |
3 | * Copyright © 2006-2008 Intel Corporation | 3 | * Copyright © 2006-2008,2010 Intel Corporation |
4 | * Jesse Barnes <jesse.barnes@intel.com> | 4 | * Jesse Barnes <jesse.barnes@intel.com> |
5 | * | 5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
@@ -24,10 +24,9 @@ | |||
24 | * | 24 | * |
25 | * Authors: | 25 | * Authors: |
26 | * Eric Anholt <eric@anholt.net> | 26 | * Eric Anholt <eric@anholt.net> |
27 | * Chris Wilson <chris@chris-wilson.co.uk> | ||
27 | */ | 28 | */ |
28 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
29 | #include <linux/slab.h> | ||
30 | #include <linux/i2c-id.h> | ||
31 | #include <linux/i2c-algo-bit.h> | 30 | #include <linux/i2c-algo-bit.h> |
32 | #include "drmP.h" | 31 | #include "drmP.h" |
33 | #include "drm.h" | 32 | #include "drm.h" |
@@ -35,13 +34,33 @@ | |||
35 | #include "i915_drm.h" | 34 | #include "i915_drm.h" |
36 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
37 | 36 | ||
38 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable) | 37 | /* Intel GPIO access functions */ |
38 | |||
39 | #define I2C_RISEFALL_TIME 20 | ||
40 | |||
41 | struct intel_gpio { | ||
42 | struct i2c_adapter adapter; | ||
43 | struct i2c_algo_bit_data algo; | ||
44 | struct drm_i915_private *dev_priv; | ||
45 | u32 reg; | ||
46 | }; | ||
47 | |||
48 | void | ||
49 | intel_i2c_reset(struct drm_device *dev) | ||
39 | { | 50 | { |
40 | struct drm_i915_private *dev_priv = dev->dev_private; | 51 | struct drm_i915_private *dev_priv = dev->dev_private; |
52 | if (HAS_PCH_SPLIT(dev)) | ||
53 | I915_WRITE(PCH_GMBUS0, 0); | ||
54 | else | ||
55 | I915_WRITE(GMBUS0, 0); | ||
56 | } | ||
57 | |||
58 | static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable) | ||
59 | { | ||
41 | u32 val; | 60 | u32 val; |
42 | 61 | ||
43 | /* When using bit bashing for I2C, this bit needs to be set to 1 */ | 62 | /* When using bit bashing for I2C, this bit needs to be set to 1 */ |
44 | if (!IS_PINEVIEW(dev)) | 63 | if (!IS_PINEVIEW(dev_priv->dev)) |
45 | return; | 64 | return; |
46 | 65 | ||
47 | val = I915_READ(DSPCLK_GATE_D); | 66 | val = I915_READ(DSPCLK_GATE_D); |
@@ -52,42 +71,30 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable) | |||
52 | I915_WRITE(DSPCLK_GATE_D, val); | 71 | I915_WRITE(DSPCLK_GATE_D, val); |
53 | } | 72 | } |
54 | 73 | ||
55 | /* | ||
56 | * Intel GPIO access functions | ||
57 | */ | ||
58 | |||
59 | #define I2C_RISEFALL_TIME 20 | ||
60 | |||
61 | static inline struct drm_i915_private * | ||
62 | get_dev_priv(struct intel_i2c_chan *chan) | ||
63 | { | ||
64 | return chan->encoder->base.dev->dev_private; | ||
65 | } | ||
66 | |||
67 | static int get_clock(void *data) | 74 | static int get_clock(void *data) |
68 | { | 75 | { |
69 | struct intel_i2c_chan *chan = data; | 76 | struct intel_gpio *gpio = data; |
70 | struct drm_i915_private *dev_priv = get_dev_priv(chan); | 77 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
71 | return (I915_READ(chan->reg) & GPIO_CLOCK_VAL_IN) != 0; | 78 | return (I915_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; |
72 | } | 79 | } |
73 | 80 | ||
74 | static int get_data(void *data) | 81 | static int get_data(void *data) |
75 | { | 82 | { |
76 | struct intel_i2c_chan *chan = data; | 83 | struct intel_gpio *gpio = data; |
77 | struct drm_i915_private *dev_priv = get_dev_priv(chan); | 84 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
78 | return (I915_READ(chan->reg) & GPIO_DATA_VAL_IN) != 0; | 85 | return (I915_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; |
79 | } | 86 | } |
80 | 87 | ||
81 | static void set_clock(void *data, int state_high) | 88 | static void set_clock(void *data, int state_high) |
82 | { | 89 | { |
83 | struct intel_i2c_chan *chan = data; | 90 | struct intel_gpio *gpio = data; |
84 | struct drm_i915_private *dev_priv = get_dev_priv(chan); | 91 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
85 | struct drm_device *dev = dev_priv->dev; | 92 | struct drm_device *dev = dev_priv->dev; |
86 | u32 reserved = 0, clock_bits; | 93 | u32 reserved = 0, clock_bits; |
87 | 94 | ||
88 | /* On most chips, these bits must be preserved in software. */ | 95 | /* On most chips, these bits must be preserved in software. */ |
89 | if (!IS_I830(dev) && !IS_845G(dev)) | 96 | if (!IS_I830(dev) && !IS_845G(dev)) |
90 | reserved = I915_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | | 97 | reserved = I915_READ(gpio->reg) & (GPIO_DATA_PULLUP_DISABLE | |
91 | GPIO_CLOCK_PULLUP_DISABLE); | 98 | GPIO_CLOCK_PULLUP_DISABLE); |
92 | 99 | ||
93 | if (state_high) | 100 | if (state_high) |
@@ -95,20 +102,21 @@ static void set_clock(void *data, int state_high) | |||
95 | else | 102 | else |
96 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | | 103 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | |
97 | GPIO_CLOCK_VAL_MASK; | 104 | GPIO_CLOCK_VAL_MASK; |
98 | I915_WRITE(chan->reg, reserved | clock_bits); | 105 | |
99 | POSTING_READ(chan->reg); | 106 | I915_WRITE(gpio->reg, reserved | clock_bits); |
107 | POSTING_READ(gpio->reg); | ||
100 | } | 108 | } |
101 | 109 | ||
102 | static void set_data(void *data, int state_high) | 110 | static void set_data(void *data, int state_high) |
103 | { | 111 | { |
104 | struct intel_i2c_chan *chan = data; | 112 | struct intel_gpio *gpio = data; |
105 | struct drm_i915_private *dev_priv = get_dev_priv(chan); | 113 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
106 | struct drm_device *dev = dev_priv->dev; | 114 | struct drm_device *dev = dev_priv->dev; |
107 | u32 reserved = 0, data_bits; | 115 | u32 reserved = 0, data_bits; |
108 | 116 | ||
109 | /* On most chips, these bits must be preserved in software. */ | 117 | /* On most chips, these bits must be preserved in software. */ |
110 | if (!IS_I830(dev) && !IS_845G(dev)) | 118 | if (!IS_I830(dev) && !IS_845G(dev)) |
111 | reserved = I915_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | | 119 | reserved = I915_READ(gpio->reg) & (GPIO_DATA_PULLUP_DISABLE | |
112 | GPIO_CLOCK_PULLUP_DISABLE); | 120 | GPIO_CLOCK_PULLUP_DISABLE); |
113 | 121 | ||
114 | if (state_high) | 122 | if (state_high) |
@@ -117,111 +125,258 @@ static void set_data(void *data, int state_high) | |||
117 | data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | | 125 | data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | |
118 | GPIO_DATA_VAL_MASK; | 126 | GPIO_DATA_VAL_MASK; |
119 | 127 | ||
120 | I915_WRITE(chan->reg, reserved | data_bits); | 128 | I915_WRITE(gpio->reg, reserved | data_bits); |
121 | POSTING_READ(chan->reg); | 129 | POSTING_READ(gpio->reg); |
122 | } | 130 | } |
123 | 131 | ||
124 | /* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C | 132 | static struct i2c_adapter * |
125 | * engine, but if the BIOS leaves it enabled, then that can break our use | 133 | intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin) |
126 | * of the bit-banging I2C interfaces. This is notably the case with the | ||
127 | * Mac Mini in EFI mode. | ||
128 | */ | ||
129 | void | ||
130 | intel_i2c_reset_gmbus(struct drm_device *dev) | ||
131 | { | 134 | { |
132 | struct drm_i915_private *dev_priv = dev->dev_private; | 135 | static const int map_pin_to_reg[] = { |
136 | 0, | ||
137 | GPIOB, | ||
138 | GPIOA, | ||
139 | GPIOC, | ||
140 | GPIOD, | ||
141 | GPIOE, | ||
142 | GPIOF, | ||
143 | }; | ||
144 | struct intel_gpio *gpio; | ||
133 | 145 | ||
134 | if (HAS_PCH_SPLIT(dev)) | 146 | if (pin < 1 || pin > 7) |
135 | I915_WRITE(PCH_GMBUS0, 0); | 147 | return NULL; |
136 | else | ||
137 | I915_WRITE(GMBUS0, 0); | ||
138 | } | ||
139 | 148 | ||
140 | /** | 149 | gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL); |
141 | * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg | 150 | if (gpio == NULL) |
142 | * @dev: DRM device | 151 | return NULL; |
143 | * @output: driver specific output device | ||
144 | * @reg: GPIO reg to use | ||
145 | * @name: name for this bus | ||
146 | * @slave_addr: slave address (if fixed) | ||
147 | * | ||
148 | * Creates and registers a new i2c bus with the Linux i2c layer, for use | ||
149 | * in output probing and control (e.g. DDC or SDVO control functions). | ||
150 | * | ||
151 | * Possible values for @reg include: | ||
152 | * %GPIOA | ||
153 | * %GPIOB | ||
154 | * %GPIOC | ||
155 | * %GPIOD | ||
156 | * %GPIOE | ||
157 | * %GPIOF | ||
158 | * %GPIOG | ||
159 | * %GPIOH | ||
160 | * see PRM for details on how these different busses are used. | ||
161 | */ | ||
162 | struct i2c_adapter *intel_i2c_create(struct intel_encoder *encoder, | ||
163 | const u32 reg, | ||
164 | const char *name) | ||
165 | { | ||
166 | struct intel_i2c_chan *chan; | ||
167 | struct drm_device *dev = encoder->base.dev; | ||
168 | 152 | ||
169 | chan = kzalloc(sizeof(struct intel_i2c_chan), GFP_KERNEL); | 153 | gpio->reg = map_pin_to_reg[pin]; |
170 | if (!chan) | 154 | if (HAS_PCH_SPLIT(dev_priv->dev)) |
171 | goto out_free; | 155 | gpio->reg += PCH_GPIOA - GPIOA; |
156 | gpio->dev_priv = dev_priv; | ||
172 | 157 | ||
173 | chan->encoder = encoder; | 158 | snprintf(gpio->adapter.name, I2C_NAME_SIZE, "GPIO %d", pin); |
174 | chan->reg = reg; | 159 | gpio->adapter.owner = THIS_MODULE; |
175 | snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name); | 160 | gpio->adapter.algo_data = &gpio->algo; |
176 | chan->adapter.owner = THIS_MODULE; | 161 | gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev; |
177 | chan->adapter.algo_data = &chan->algo; | 162 | gpio->algo.setsda = set_data; |
178 | chan->adapter.dev.parent = &dev->pdev->dev; | 163 | gpio->algo.setscl = set_clock; |
179 | chan->algo.setsda = set_data; | 164 | gpio->algo.getsda = get_data; |
180 | chan->algo.setscl = set_clock; | 165 | gpio->algo.getscl = get_clock; |
181 | chan->algo.getsda = get_data; | 166 | gpio->algo.udelay = I2C_RISEFALL_TIME; |
182 | chan->algo.getscl = get_clock; | 167 | gpio->algo.timeout = usecs_to_jiffies(2200); |
183 | chan->algo.udelay = I2C_RISEFALL_TIME; | 168 | gpio->algo.data = gpio; |
184 | chan->algo.timeout = usecs_to_jiffies(2200); | 169 | |
185 | chan->algo.data = chan; | 170 | if (i2c_bit_add_bus(&gpio->adapter)) |
186 | |||
187 | i2c_set_adapdata(&chan->adapter, chan); | ||
188 | |||
189 | if (i2c_bit_add_bus(&chan->adapter)) | ||
190 | goto out_free; | 171 | goto out_free; |
191 | 172 | ||
192 | intel_i2c_reset_gmbus(dev); | 173 | intel_i2c_reset(dev_priv->dev); |
193 | 174 | ||
194 | /* JJJ: raise SCL and SDA? */ | 175 | /* JJJ: raise SCL and SDA? */ |
195 | intel_i2c_quirk_set(dev, true); | 176 | intel_i2c_quirk_set(dev_priv, true); |
196 | set_data(chan, 1); | 177 | set_data(gpio, 1); |
197 | udelay(I2C_RISEFALL_TIME); | 178 | udelay(I2C_RISEFALL_TIME); |
198 | set_clock(chan, 1); | 179 | set_clock(gpio, 1); |
199 | udelay(I2C_RISEFALL_TIME); | 180 | udelay(I2C_RISEFALL_TIME); |
200 | intel_i2c_quirk_set(dev, false); | 181 | intel_i2c_quirk_set(dev_priv, false); |
201 | 182 | ||
202 | return &chan->adapter; | 183 | return &gpio->adapter; |
203 | 184 | ||
204 | out_free: | 185 | out_free: |
205 | kfree(chan); | 186 | kfree(gpio); |
206 | return NULL; | 187 | return NULL; |
207 | } | 188 | } |
208 | 189 | ||
190 | static int | ||
191 | quirk_i2c_transfer(struct drm_i915_private *dev_priv, | ||
192 | struct i2c_adapter *adapter, | ||
193 | struct i2c_msg *msgs, | ||
194 | int num) | ||
195 | { | ||
196 | int ret; | ||
197 | |||
198 | intel_i2c_reset(dev_priv->dev); | ||
199 | |||
200 | intel_i2c_quirk_set(dev_priv, true); | ||
201 | ret = i2c_transfer(adapter, msgs, num); | ||
202 | intel_i2c_quirk_set(dev_priv, false); | ||
203 | |||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | static int | ||
208 | gmbus_xfer(struct i2c_adapter *adapter, | ||
209 | struct i2c_msg *msgs, | ||
210 | int num) | ||
211 | { | ||
212 | struct intel_gmbus *bus = container_of(adapter, | ||
213 | struct intel_gmbus, | ||
214 | adapter); | ||
215 | struct drm_i915_private *dev_priv = adapter->algo_data; | ||
216 | int i, speed, reg_offset; | ||
217 | |||
218 | if (bus->force_bitbanging) | ||
219 | return quirk_i2c_transfer(dev_priv, bus->force_bitbanging, msgs, num); | ||
220 | |||
221 | reg_offset = HAS_PCH_SPLIT(dev_priv->dev) ? PCH_GMBUS0 - GMBUS0 : 0; | ||
222 | |||
223 | speed = GMBUS_RATE_100KHZ; | ||
224 | if (INTEL_INFO(dev_priv->dev)->gen > 4 || IS_G4X(dev_priv->dev)) { | ||
225 | if (bus->pin == GMBUS_PORT_DPB) /* SDVO only? */ | ||
226 | speed = GMBUS_RATE_1MHZ; | ||
227 | else | ||
228 | speed = GMBUS_RATE_400KHZ; | ||
229 | } | ||
230 | I915_WRITE(GMBUS0 + reg_offset, speed | bus->pin); | ||
231 | |||
232 | for (i = 0; i < num; i++) { | ||
233 | u16 len = msgs[i].len; | ||
234 | u8 *buf = msgs[i].buf; | ||
235 | |||
236 | if (msgs[i].flags & I2C_M_RD) { | ||
237 | I915_WRITE(GMBUS1 + reg_offset, | ||
238 | GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | | ||
239 | (len << GMBUS_BYTE_COUNT_SHIFT) | | ||
240 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | ||
241 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); | ||
242 | do { | ||
243 | u32 val, loop = 0; | ||
244 | |||
245 | if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) | ||
246 | goto timeout; | ||
247 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
248 | return 0; | ||
249 | |||
250 | val = I915_READ(GMBUS3 + reg_offset); | ||
251 | do { | ||
252 | *buf++ = val & 0xff; | ||
253 | val >>= 8; | ||
254 | } while (--len && ++loop < 4); | ||
255 | } while (len); | ||
256 | } else { | ||
257 | u32 val = 0, loop = 0; | ||
258 | |||
259 | BUG_ON(msgs[i].len > 4); | ||
260 | |||
261 | do { | ||
262 | val |= *buf++ << (loop*8); | ||
263 | } while (--len && +loop < 4); | ||
264 | |||
265 | I915_WRITE(GMBUS3 + reg_offset, val); | ||
266 | I915_WRITE(GMBUS1 + reg_offset, | ||
267 | (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT ) | | ||
268 | (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | | ||
269 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | ||
270 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); | ||
271 | } | ||
272 | |||
273 | if (i + 1 < num && wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) | ||
274 | goto timeout; | ||
275 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | return num; | ||
280 | |||
281 | timeout: | ||
282 | DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d\n", bus->pin); | ||
283 | /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ | ||
284 | bus->force_bitbanging = intel_gpio_create(dev_priv, bus->pin); | ||
285 | if (!bus->force_bitbanging) | ||
286 | return -ENOMEM; | ||
287 | |||
288 | return quirk_i2c_transfer(dev_priv, bus->force_bitbanging, msgs, num); | ||
289 | } | ||
290 | |||
291 | static u32 gmbus_func(struct i2c_adapter *adapter) | ||
292 | { | ||
293 | return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | ||
294 | /* I2C_FUNC_10BIT_ADDR | */ | ||
295 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | | ||
296 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL); | ||
297 | } | ||
298 | |||
299 | static const struct i2c_algorithm gmbus_algorithm = { | ||
300 | .master_xfer = gmbus_xfer, | ||
301 | .functionality = gmbus_func | ||
302 | }; | ||
303 | |||
209 | /** | 304 | /** |
210 | * intel_i2c_destroy - unregister and free i2c bus resources | 305 | * intel_gmbus_setup - instantiate all Intel i2c GMBuses |
211 | * @output: channel to free | 306 | * @dev: DRM device |
212 | * | ||
213 | * Unregister the adapter from the i2c layer, then free the structure. | ||
214 | */ | 307 | */ |
215 | void intel_i2c_destroy(struct i2c_adapter *adapter) | 308 | int intel_setup_gmbus(struct drm_device *dev) |
309 | { | ||
310 | static const char *names[] = { | ||
311 | "disabled", | ||
312 | "ssc", | ||
313 | "vga", | ||
314 | "panel", | ||
315 | "dpc", | ||
316 | "dpb", | ||
317 | "dpd", | ||
318 | "reserved" | ||
319 | }; | ||
320 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
321 | int ret, i; | ||
322 | |||
323 | dev_priv->gmbus = kcalloc(sizeof(struct intel_gmbus), GMBUS_NUM_PORTS, | ||
324 | GFP_KERNEL); | ||
325 | if (dev_priv->gmbus == NULL) | ||
326 | return -ENOMEM; | ||
327 | |||
328 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { | ||
329 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | ||
330 | |||
331 | bus->adapter.owner = THIS_MODULE; | ||
332 | bus->adapter.class = I2C_CLASS_DDC; | ||
333 | snprintf(bus->adapter.name, | ||
334 | I2C_NAME_SIZE, | ||
335 | "gmbus %s", | ||
336 | names[i]); | ||
337 | |||
338 | bus->adapter.dev.parent = &dev->pdev->dev; | ||
339 | bus->adapter.algo_data = dev_priv; | ||
340 | |||
341 | bus->adapter.algo = &gmbus_algorithm; | ||
342 | ret = i2c_add_adapter(&bus->adapter); | ||
343 | if (ret) | ||
344 | goto err; | ||
345 | |||
346 | bus->pin = i; | ||
347 | } | ||
348 | |||
349 | intel_i2c_reset(dev_priv->dev); | ||
350 | |||
351 | return 0; | ||
352 | |||
353 | err: | ||
354 | while (--i) { | ||
355 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | ||
356 | i2c_del_adapter(&bus->adapter); | ||
357 | } | ||
358 | kfree(dev_priv->gmbus); | ||
359 | dev_priv->gmbus = NULL; | ||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | void intel_teardown_gmbus(struct drm_device *dev) | ||
216 | { | 364 | { |
217 | struct intel_i2c_chan *chan; | 365 | struct drm_i915_private *dev_priv = dev->dev_private; |
366 | int i; | ||
218 | 367 | ||
219 | if (!adapter) | 368 | if (dev_priv->gmbus == NULL) |
220 | return; | 369 | return; |
221 | 370 | ||
222 | chan = container_of(adapter, | 371 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { |
223 | struct intel_i2c_chan, | 372 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; |
224 | adapter); | 373 | if (bus->force_bitbanging) { |
225 | i2c_del_adapter(&chan->adapter); | 374 | i2c_del_adapter(bus->force_bitbanging); |
226 | kfree(chan); | 375 | kfree(bus->force_bitbanging); |
376 | } | ||
377 | i2c_del_adapter(&bus->adapter); | ||
378 | } | ||
379 | |||
380 | kfree(dev_priv->gmbus); | ||
381 | dev_priv->gmbus = NULL; | ||
227 | } | 382 | } |