File Index
Files and directories
Sign in
FILE

pci-pwrctrl-tc9563.c

File preview with syntax highlighting.

linux-6.19.14/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  4 */
  5
  6#include <linux/array_size.h>
  7#include <linux/bitfield.h>
  8#include <linux/bits.h>
  9#include <linux/delay.h>
 10#include <linux/device.h>
 11#include <linux/gpio/consumer.h>
 12#include <linux/i2c.h>
 13#include <linux/mod_devicetable.h>
 14#include <linux/module.h>
 15#include <linux/of.h>
 16#include <linux/of_platform.h>
 17#include <linux/pci.h>
 18#include <linux/pci-pwrctrl.h>
 19#include <linux/platform_device.h>
 20#include <linux/regulator/consumer.h>
 21#include <linux/string.h>
 22#include <linux/types.h>
 23#include <linux/unaligned.h>
 24
 25#include "../pci.h"
 26
 27#define TC9563_GPIO_CONFIG		0x801208
 28#define TC9563_RESET_GPIO		0x801210
 29
 30#define TC9563_PORT_L0S_DELAY		0x82496c
 31#define TC9563_PORT_L1_DELAY		0x824970
 32
 33#define TC9563_EMBEDDED_ETH_DELAY	0x8200d8
 34#define TC9563_ETH_L1_DELAY_MASK	GENMASK(27, 18)
 35#define TC9563_ETH_L1_DELAY_VALUE(x)	FIELD_PREP(TC9563_ETH_L1_DELAY_MASK, x)
 36#define TC9563_ETH_L0S_DELAY_MASK	GENMASK(17, 13)
 37#define TC9563_ETH_L0S_DELAY_VALUE(x)	FIELD_PREP(TC9563_ETH_L0S_DELAY_MASK, x)
 38
 39#define TC9563_NFTS_2_5_GT		0x824978
 40#define TC9563_NFTS_5_GT		0x82497c
 41
 42#define TC9563_PORT_LANE_ACCESS_ENABLE	0x828000
 43
 44#define TC9563_PHY_RATE_CHANGE_OVERRIDE	0x828040
 45#define TC9563_PHY_RATE_CHANGE		0x828050
 46
 47#define TC9563_TX_MARGIN		0x828234
 48
 49#define TC9563_DFE_ENABLE		0x828a04
 50#define TC9563_DFE_EQ0_MODE		0x828a08
 51#define TC9563_DFE_EQ1_MODE		0x828a0c
 52#define TC9563_DFE_EQ2_MODE		0x828a14
 53#define TC9563_DFE_PD_MASK		0x828254
 54
 55#define TC9563_PORT_SELECT		0x82c02c
 56#define TC9563_PORT_ACCESS_ENABLE	0x82c030
 57
 58#define TC9563_POWER_CONTROL		0x82b09c
 59#define TC9563_POWER_CONTROL_OVREN	0x82b2c8
 60
 61#define TC9563_GPIO_MASK		0xfffffff3
 62#define TC9563_GPIO_DEASSERT_BITS	0xc  /* Bits to clear for GPIO deassert */
 63
 64#define TC9563_TX_MARGIN_MIN_UA		400000
 65
 66/*
 67 * From TC9563 PORSYS rev 0.2, figure 1.1 POR boot sequence
 68 * wait for 10ms for the internal osc frequency to stabilize.
 69 */
 70#define TC9563_OSC_STAB_DELAY_US	(10 * USEC_PER_MSEC)
 71
 72#define TC9563_L0S_L1_DELAY_UNIT_NS	256  /* Each unit represents 256 nanoseconds */
 73
 74struct tc9563_pwrctrl_reg_setting {
 75	unsigned int offset;
 76	unsigned int val;
 77};
 78
 79enum tc9563_pwrctrl_ports {
 80	TC9563_USP,
 81	TC9563_DSP1,
 82	TC9563_DSP2,
 83	TC9563_DSP3,
 84	TC9563_ETHERNET,
 85	TC9563_MAX
 86};
 87
 88struct tc9563_pwrctrl_cfg {
 89	u32 l0s_delay;
 90	u32 l1_delay;
 91	u32 tx_amp;
 92	u8 nfts[2]; /* GEN1 & GEN2 */
 93	bool disable_dfe;
 94	bool disable_port;
 95};
 96
 97#define TC9563_PWRCTL_MAX_SUPPLY	6
 98
 99static const char *const tc9563_supply_names[TC9563_PWRCTL_MAX_SUPPLY] = {
100	"vddc",
101	"vdd18",
102	"vdd09",
103	"vddio1",
104	"vddio2",
105	"vddio18",
106};
107
108struct tc9563_pwrctrl_ctx {
109	struct regulator_bulk_data supplies[TC9563_PWRCTL_MAX_SUPPLY];
110	struct tc9563_pwrctrl_cfg cfg[TC9563_MAX];
111	struct gpio_desc *reset_gpio;
112	struct i2c_adapter *adapter;
113	struct i2c_client *client;
114	struct pci_pwrctrl pwrctrl;
115};
116
117/*
118 * downstream port power off sequence, hardcoding the address
119 * as we don't know register names for these register offsets.
120 */
121static const struct tc9563_pwrctrl_reg_setting common_pwroff_seq[] = {
122	{0x82900c, 0x1},
123	{0x829010, 0x1},
124	{0x829018, 0x0},
125	{0x829020, 0x1},
126	{0x82902c, 0x1},
127	{0x829030, 0x1},
128	{0x82903c, 0x1},
129	{0x829058, 0x0},
130	{0x82905c, 0x1},
131	{0x829060, 0x1},
132	{0x8290cc, 0x1},
133	{0x8290d0, 0x1},
134	{0x8290d8, 0x1},
135	{0x8290e0, 0x1},
136	{0x8290e8, 0x1},
137	{0x8290ec, 0x1},
138	{0x8290f4, 0x1},
139	{0x82910c, 0x1},
140	{0x829110, 0x1},
141	{0x829114, 0x1},
142};
143
144static const struct tc9563_pwrctrl_reg_setting dsp1_pwroff_seq[] = {
145	{TC9563_PORT_ACCESS_ENABLE, 0x2},
146	{TC9563_PORT_LANE_ACCESS_ENABLE, 0x3},
147	{TC9563_POWER_CONTROL, 0x014f4804},
148	{TC9563_POWER_CONTROL_OVREN, 0x1},
149	{TC9563_PORT_ACCESS_ENABLE, 0x4},
150};
151
152static const struct tc9563_pwrctrl_reg_setting dsp2_pwroff_seq[] = {
153	{TC9563_PORT_ACCESS_ENABLE, 0x8},
154	{TC9563_PORT_LANE_ACCESS_ENABLE, 0x1},
155	{TC9563_POWER_CONTROL, 0x014f4804},
156	{TC9563_POWER_CONTROL_OVREN, 0x1},
157	{TC9563_PORT_ACCESS_ENABLE, 0x8},
158};
159
160/*
161 * Since all transfers are initiated by the probe, no locks are necessary,
162 * as there are no concurrent calls.
163 */
164static int tc9563_pwrctrl_i2c_write(struct i2c_client *client,
165				    u32 reg_addr, u32 reg_val)
166{
167	struct i2c_msg msg;
168	u8 msg_buf[7];
169	int ret;
170
171	msg.addr = client->addr;
172	msg.len = 7;
173	msg.flags = 0;
174
175	/* Big Endian for reg addr */
176	put_unaligned_be24(reg_addr, &msg_buf[0]);
177
178	/* Little Endian for reg val */
179	put_unaligned_le32(reg_val, &msg_buf[3]);
180
181	msg.buf = msg_buf;
182	ret = i2c_transfer(client->adapter, &msg, 1);
183	return ret == 1 ? 0 : ret;
184}
185
186static int tc9563_pwrctrl_i2c_read(struct i2c_client *client,
187				   u32 reg_addr, u32 *reg_val)
188{
189	struct i2c_msg msg[2];
190	u8 wr_data[3];
191	u32 rd_data;
192	int ret;
193
194	msg[0].addr = client->addr;
195	msg[0].len = 3;
196	msg[0].flags = 0;
197
198	/* Big Endian for reg addr */
199	put_unaligned_be24(reg_addr, &wr_data[0]);
200
201	msg[0].buf = wr_data;
202
203	msg[1].addr = client->addr;
204	msg[1].len = 4;
205	msg[1].flags = I2C_M_RD;
206
207	msg[1].buf = (u8 *)&rd_data;
208
209	ret = i2c_transfer(client->adapter, &msg[0], 2);
210	if (ret == 2) {
211		*reg_val = get_unaligned_le32(&rd_data);
212		return 0;
213	}
214
215	/* If only one message successfully completed, return -EIO */
216	return ret == 1 ? -EIO : ret;
217}
218
219static int tc9563_pwrctrl_i2c_bulk_write(struct i2c_client *client,
220					 const struct tc9563_pwrctrl_reg_setting *seq, int len)
221{
222	int ret, i;
223
224	for (i = 0; i < len; i++) {
225		ret = tc9563_pwrctrl_i2c_write(client, seq[i].offset, seq[i].val);
226		if (ret)
227			return ret;
228	}
229
230	return 0;
231}
232
233static int tc9563_pwrctrl_disable_port(struct tc9563_pwrctrl_ctx *ctx,
234				       enum tc9563_pwrctrl_ports port)
235{
236	struct tc9563_pwrctrl_cfg *cfg = &ctx->cfg[port];
237	const struct tc9563_pwrctrl_reg_setting *seq;
238	int ret, len;
239
240	if (!cfg->disable_port)
241		return 0;
242
243	if (port == TC9563_DSP1) {
244		seq = dsp1_pwroff_seq;
245		len = ARRAY_SIZE(dsp1_pwroff_seq);
246	} else {
247		seq = dsp2_pwroff_seq;
248		len = ARRAY_SIZE(dsp2_pwroff_seq);
249	}
250
251	ret = tc9563_pwrctrl_i2c_bulk_write(ctx->client, seq, len);
252	if (ret)
253		return ret;
254
255	return tc9563_pwrctrl_i2c_bulk_write(ctx->client,
256					    common_pwroff_seq, ARRAY_SIZE(common_pwroff_seq));
257}
258
259static int tc9563_pwrctrl_set_l0s_l1_entry_delay(struct tc9563_pwrctrl_ctx *ctx,
260						 enum tc9563_pwrctrl_ports port, bool is_l1, u32 ns)
261{
262	u32 rd_val, units;
263	int ret;
264
265	if (ns < TC9563_L0S_L1_DELAY_UNIT_NS)
266		return 0;
267
268	/* convert to units of 256ns */
269	units = ns / TC9563_L0S_L1_DELAY_UNIT_NS;
270
271	if (port == TC9563_ETHERNET) {
272		ret = tc9563_pwrctrl_i2c_read(ctx->client, TC9563_EMBEDDED_ETH_DELAY, &rd_val);
273		if (ret)
274			return ret;
275
276		if (is_l1)
277			rd_val = u32_replace_bits(rd_val, units, TC9563_ETH_L1_DELAY_MASK);
278		else
279			rd_val = u32_replace_bits(rd_val, units, TC9563_ETH_L0S_DELAY_MASK);
280
281		return tc9563_pwrctrl_i2c_write(ctx->client, TC9563_EMBEDDED_ETH_DELAY, rd_val);
282	}
283
284	ret = tc9563_pwrctrl_i2c_write(ctx->client, TC9563_PORT_SELECT, BIT(port));
285	if (ret)
286		return ret;
287
288	return tc9563_pwrctrl_i2c_write(ctx->client,
289				       is_l1 ? TC9563_PORT_L1_DELAY : TC9563_PORT_L0S_DELAY, units);
290}
291
292static int tc9563_pwrctrl_set_tx_amplitude(struct tc9563_pwrctrl_ctx *ctx,
293					   enum tc9563_pwrctrl_ports port)
294{
295	u32 amp = ctx->cfg[port].tx_amp;
296	int port_access;
297
298	if (amp < TC9563_TX_MARGIN_MIN_UA)
299		return 0;
300
301	/* txmargin = (Amp(uV) - 400000) / 3125 */
302	amp = (amp - TC9563_TX_MARGIN_MIN_UA) / 3125;
303
304	switch (port) {
305	case TC9563_USP:
306		port_access = 0x1;
307		break;
308	case TC9563_DSP1:
309		port_access = 0x2;
310		break;
311	case TC9563_DSP2:
312		port_access = 0x8;
313		break;
314	default:
315		return -EINVAL;
316	}
317
318	struct tc9563_pwrctrl_reg_setting tx_amp_seq[] = {
319		{TC9563_PORT_ACCESS_ENABLE, port_access},
320		{TC9563_PORT_LANE_ACCESS_ENABLE, 0x3},
321		{TC9563_TX_MARGIN, amp},
322	};
323
324	return tc9563_pwrctrl_i2c_bulk_write(ctx->client, tx_amp_seq, ARRAY_SIZE(tx_amp_seq));
325}
326
327static int tc9563_pwrctrl_disable_dfe(struct tc9563_pwrctrl_ctx *ctx,
328				      enum tc9563_pwrctrl_ports port)
329{
330	struct tc9563_pwrctrl_cfg *cfg = &ctx->cfg[port];
331	int port_access, lane_access = 0x3;
332	u32 phy_rate = 0x21;
333
334	if (!cfg->disable_dfe)
335		return 0;
336
337	switch (port) {
338	case TC9563_USP:
339		phy_rate = 0x1;
340		port_access = 0x1;
341		break;
342	case TC9563_DSP1:
343		port_access = 0x2;
344		break;
345	case TC9563_DSP2:
346		port_access = 0x8;
347		lane_access = 0x1;
348		break;
349	default:
350		return -EINVAL;
351	}
352
353	struct tc9563_pwrctrl_reg_setting disable_dfe_seq[] = {
354		{TC9563_PORT_ACCESS_ENABLE, port_access},
355		{TC9563_PORT_LANE_ACCESS_ENABLE, lane_access},
356		{TC9563_DFE_ENABLE, 0x0},
357		{TC9563_DFE_EQ0_MODE, 0x411},
358		{TC9563_DFE_EQ1_MODE, 0x11},
359		{TC9563_DFE_EQ2_MODE, 0x11},
360		{TC9563_DFE_PD_MASK, 0x7},
361		{TC9563_PHY_RATE_CHANGE_OVERRIDE, 0x10},
362		{TC9563_PHY_RATE_CHANGE, phy_rate},
363		{TC9563_PHY_RATE_CHANGE, 0x0},
364		{TC9563_PHY_RATE_CHANGE_OVERRIDE, 0x0},
365	};
366
367	return tc9563_pwrctrl_i2c_bulk_write(ctx->client,
368					    disable_dfe_seq, ARRAY_SIZE(disable_dfe_seq));
369}
370
371static int tc9563_pwrctrl_set_nfts(struct tc9563_pwrctrl_ctx *ctx,
372				   enum tc9563_pwrctrl_ports port)
373{
374	u8 *nfts = ctx->cfg[port].nfts;
375	struct tc9563_pwrctrl_reg_setting nfts_seq[] = {
376		{TC9563_NFTS_2_5_GT, nfts[0]},
377		{TC9563_NFTS_5_GT, nfts[1]},
378	};
379	int ret;
380
381	if (!nfts[0])
382		return 0;
383
384	ret =  tc9563_pwrctrl_i2c_write(ctx->client, TC9563_PORT_SELECT, BIT(port));
385	if (ret)
386		return ret;
387
388	return tc9563_pwrctrl_i2c_bulk_write(ctx->client, nfts_seq, ARRAY_SIZE(nfts_seq));
389}
390
391static int tc9563_pwrctrl_assert_deassert_reset(struct tc9563_pwrctrl_ctx *ctx, bool deassert)
392{
393	int ret, val;
394
395	ret = tc9563_pwrctrl_i2c_write(ctx->client, TC9563_GPIO_CONFIG, TC9563_GPIO_MASK);
396	if (ret)
397		return ret;
398
399	val = deassert ? TC9563_GPIO_DEASSERT_BITS : 0;
400
401	return tc9563_pwrctrl_i2c_write(ctx->client, TC9563_RESET_GPIO, val);
402}
403
404static int tc9563_pwrctrl_parse_device_dt(struct tc9563_pwrctrl_ctx *ctx, struct device_node *node,
405					  enum tc9563_pwrctrl_ports port)
406{
407	struct tc9563_pwrctrl_cfg *cfg = &ctx->cfg[port];
408	int ret;
409
410	/* Disable port if the status of the port is disabled. */
411	if (!of_device_is_available(node)) {
412		cfg->disable_port = true;
413		return 0;
414	}
415
416	ret = of_property_read_u32(node, "aspm-l0s-entry-delay-ns", &cfg->l0s_delay);
417	if (ret && ret != -EINVAL)
418		return ret;
419
420	ret = of_property_read_u32(node, "aspm-l1-entry-delay-ns", &cfg->l1_delay);
421	if (ret && ret != -EINVAL)
422		return ret;
423
424	ret = of_property_read_u32(node, "toshiba,tx-amplitude-microvolt", &cfg->tx_amp);
425	if (ret && ret != -EINVAL)
426		return ret;
427
428	ret = of_property_read_u8_array(node, "n-fts", cfg->nfts, ARRAY_SIZE(cfg->nfts));
429	if (ret && ret != -EINVAL)
430		return ret;
431
432	cfg->disable_dfe = of_property_read_bool(node, "toshiba,no-dfe-support");
433
434	return 0;
435}
436
437static void tc9563_pwrctrl_power_off(struct tc9563_pwrctrl_ctx *ctx)
438{
439	gpiod_set_value(ctx->reset_gpio, 1);
440
441	regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
442}
443
444static int tc9563_pwrctrl_bring_up(struct tc9563_pwrctrl_ctx *ctx)
445{
446	struct tc9563_pwrctrl_cfg *cfg;
447	int ret, i;
448
449	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
450	if (ret < 0)
451		return dev_err_probe(ctx->pwrctrl.dev, ret, "cannot enable regulators\n");
452
453	gpiod_set_value(ctx->reset_gpio, 0);
454
455	fsleep(TC9563_OSC_STAB_DELAY_US);
456
457	ret = tc9563_pwrctrl_assert_deassert_reset(ctx, false);
458	if (ret)
459		goto power_off;
460
461	for (i = 0; i < TC9563_MAX; i++) {
462		cfg = &ctx->cfg[i];
463		ret = tc9563_pwrctrl_disable_port(ctx, i);
464		if (ret) {
465			dev_err(ctx->pwrctrl.dev, "Disabling port failed\n");
466			goto power_off;
467		}
468
469		ret = tc9563_pwrctrl_set_l0s_l1_entry_delay(ctx, i, false, cfg->l0s_delay);
470		if (ret) {
471			dev_err(ctx->pwrctrl.dev, "Setting L0s entry delay failed\n");
472			goto power_off;
473		}
474
475		ret = tc9563_pwrctrl_set_l0s_l1_entry_delay(ctx, i, true, cfg->l1_delay);
476		if (ret) {
477			dev_err(ctx->pwrctrl.dev, "Setting L1 entry delay failed\n");
478			goto power_off;
479		}
480
481		ret = tc9563_pwrctrl_set_tx_amplitude(ctx, i);
482		if (ret) {
483			dev_err(ctx->pwrctrl.dev, "Setting Tx amplitude failed\n");
484			goto power_off;
485		}
486
487		ret = tc9563_pwrctrl_set_nfts(ctx, i);
488		if (ret) {
489			dev_err(ctx->pwrctrl.dev, "Setting N_FTS failed\n");
490			goto power_off;
491		}
492
493		ret = tc9563_pwrctrl_disable_dfe(ctx, i);
494		if (ret) {
495			dev_err(ctx->pwrctrl.dev, "Disabling DFE failed\n");
496			goto power_off;
497		}
498	}
499
500	ret = tc9563_pwrctrl_assert_deassert_reset(ctx, true);
501	if (!ret)
502		return 0;
503
504power_off:
505	tc9563_pwrctrl_power_off(ctx);
506	return ret;
507}
508
509static int tc9563_pwrctrl_probe(struct platform_device *pdev)
510{
511	struct pci_host_bridge *bridge = to_pci_host_bridge(pdev->dev.parent);
512	struct pci_bus *bus = bridge->bus;
513	struct device *dev = &pdev->dev;
514	enum tc9563_pwrctrl_ports port;
515	struct tc9563_pwrctrl_ctx *ctx;
516	struct device_node *i2c_node;
517	int ret, addr;
518
519	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
520	if (!ctx)
521		return -ENOMEM;
522
523	ret = of_property_read_u32_index(pdev->dev.of_node, "i2c-parent", 1, &addr);
524	if (ret)
525		return dev_err_probe(dev, ret, "Failed to read i2c-parent property\n");
526
527	i2c_node = of_parse_phandle(dev->of_node, "i2c-parent", 0);
528	ctx->adapter = of_find_i2c_adapter_by_node(i2c_node);
529	of_node_put(i2c_node);
530	if (!ctx->adapter)
531		return dev_err_probe(dev, -EPROBE_DEFER, "Failed to find I2C adapter\n");
532
533	ctx->client = i2c_new_dummy_device(ctx->adapter, addr);
534	if (IS_ERR(ctx->client)) {
535		dev_err(dev, "Failed to create I2C client\n");
536		put_device(&ctx->adapter->dev);
537		return PTR_ERR(ctx->client);
538	}
539
540	for (int i = 0; i < ARRAY_SIZE(tc9563_supply_names); i++)
541		ctx->supplies[i].supply = tc9563_supply_names[i];
542
543	ret = devm_regulator_bulk_get(dev, TC9563_PWRCTL_MAX_SUPPLY, ctx->supplies);
544	if (ret) {
545		dev_err_probe(dev, ret, "failed to get supply regulator\n");
546		goto remove_i2c;
547	}
548
549	ctx->reset_gpio = devm_gpiod_get(dev, "resx", GPIOD_OUT_HIGH);
550	if (IS_ERR(ctx->reset_gpio)) {
551		ret = dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), "failed to get resx GPIO\n");
552		goto remove_i2c;
553	}
554
555	pci_pwrctrl_init(&ctx->pwrctrl, dev);
556
557	port = TC9563_USP;
558	ret = tc9563_pwrctrl_parse_device_dt(ctx, pdev->dev.of_node, port);
559	if (ret) {
560		dev_err(dev, "failed to parse device tree properties: %d\n", ret);
561		goto remove_i2c;
562	}
563
564	/*
565	 * Downstream ports are always children of the upstream port.
566	 * The first node represents DSP1, the second node represents DSP2, and so on.
567	 */
568	for_each_child_of_node_scoped(pdev->dev.of_node, child) {
569		port++;
570		ret = tc9563_pwrctrl_parse_device_dt(ctx, child, port);
571		if (ret)
572			break;
573		/* Embedded ethernet device are under DSP3 */
574		if (port == TC9563_DSP3) {
575			for_each_child_of_node_scoped(child, child1) {
576				port++;
577				ret = tc9563_pwrctrl_parse_device_dt(ctx, child1, port);
578				if (ret)
579					break;
580			}
581		}
582	}
583	if (ret) {
584		dev_err(dev, "failed to parse device tree properties: %d\n", ret);
585		goto remove_i2c;
586	}
587
588	if (bridge->ops->assert_perst) {
589		ret = bridge->ops->assert_perst(bus, true);
590		if (ret)
591			goto remove_i2c;
592	}
593
594	ret = tc9563_pwrctrl_bring_up(ctx);
595	if (ret)
596		goto remove_i2c;
597
598	if (bridge->ops->assert_perst) {
599		ret = bridge->ops->assert_perst(bus, false);
600		if (ret)
601			goto power_off;
602	}
603
604	ret = devm_pci_pwrctrl_device_set_ready(dev, &ctx->pwrctrl);
605	if (ret)
606		goto power_off;
607
608	platform_set_drvdata(pdev, ctx);
609
610	return 0;
611
612power_off:
613	tc9563_pwrctrl_power_off(ctx);
614remove_i2c:
615	i2c_unregister_device(ctx->client);
616	put_device(&ctx->adapter->dev);
617	return ret;
618}
619
620static void tc9563_pwrctrl_remove(struct platform_device *pdev)
621{
622	struct tc9563_pwrctrl_ctx *ctx = platform_get_drvdata(pdev);
623
624	tc9563_pwrctrl_power_off(ctx);
625	i2c_unregister_device(ctx->client);
626	put_device(&ctx->adapter->dev);
627}
628
629static const struct of_device_id tc9563_pwrctrl_of_match[] = {
630	{ .compatible = "pci1179,0623"},
631	{ }
632};
633MODULE_DEVICE_TABLE(of, tc9563_pwrctrl_of_match);
634
635static struct platform_driver tc9563_pwrctrl_driver = {
636	.driver = {
637		.name = "pwrctrl-tc9563",
638		.of_match_table = tc9563_pwrctrl_of_match,
639		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
640	},
641	.probe = tc9563_pwrctrl_probe,
642	.remove = tc9563_pwrctrl_remove,
643};
644module_platform_driver(tc9563_pwrctrl_driver);
645
646MODULE_AUTHOR("Krishna chaitanya chundru <quic_krichai@quicinc.com>");
647MODULE_DESCRIPTION("TC956x power control driver");
648MODULE_LICENSE("GPL");
~/ Read-only file preview.