Blame view

drivers/ssb/pcihost_wrapper.c 2.69 KB
61e115a56   Michael Buesch   [SSB]: add Sonics...
1
2
3
4
5
6
7
8
  /*
   * Sonics Silicon Backplane
   * PCI Hostdevice wrapper
   *
   * Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
   * Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
   * Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
   * Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
eb032b983   Michael Buesch   Update my e-mail ...
9
   * Copyright (c) 2005-2007 Michael Buesch <m@bues.ch>
61e115a56   Michael Buesch   [SSB]: add Sonics...
10
11
12
13
14
   *
   * Licensed under the GNU/GPL. See COPYING for details.
   */
  
  #include <linux/pci.h>
1014c22e4   Paul Gortmaker   ssb: Add export.h...
15
  #include <linux/export.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
16
  #include <linux/slab.h>
61e115a56   Michael Buesch   [SSB]: add Sonics...
17
18
19
20
21
22
  #include <linux/ssb/ssb.h>
  
  
  #ifdef CONFIG_PM
  static int ssb_pcihost_suspend(struct pci_dev *dev, pm_message_t state)
  {
8fe2b65a1   Michael Buesch   ssb: Turn suspend...
23
24
25
26
27
28
  	struct ssb_bus *ssb = pci_get_drvdata(dev);
  	int err;
  
  	err = ssb_bus_suspend(ssb);
  	if (err)
  		return err;
61e115a56   Michael Buesch   [SSB]: add Sonics...
29
30
31
32
33
34
35
36
37
  	pci_save_state(dev);
  	pci_disable_device(dev);
  	pci_set_power_state(dev, pci_choose_state(dev, state));
  
  	return 0;
  }
  
  static int ssb_pcihost_resume(struct pci_dev *dev)
  {
8fe2b65a1   Michael Buesch   ssb: Turn suspend...
38
  	struct ssb_bus *ssb = pci_get_drvdata(dev);
61e115a56   Michael Buesch   [SSB]: add Sonics...
39
40
41
42
43
44
45
  	int err;
  
  	pci_set_power_state(dev, 0);
  	err = pci_enable_device(dev);
  	if (err)
  		return err;
  	pci_restore_state(dev);
8fe2b65a1   Michael Buesch   ssb: Turn suspend...
46
47
48
  	err = ssb_bus_resume(ssb);
  	if (err)
  		return err;
61e115a56   Michael Buesch   [SSB]: add Sonics...
49
50
51
52
53
54
55
  
  	return 0;
  }
  #else /* CONFIG_PM */
  # define ssb_pcihost_suspend	NULL
  # define ssb_pcihost_resume	NULL
  #endif /* CONFIG_PM */
cd1559870   Hauke Mehrtens   ssb: add __devini...
56
57
  static int __devinit ssb_pcihost_probe(struct pci_dev *dev,
  				       const struct pci_device_id *id)
61e115a56   Michael Buesch   [SSB]: add Sonics...
58
59
60
61
  {
  	struct ssb_bus *ssb;
  	int err = -ENOMEM;
  	const char *name;
e081685c1   Larry Finger   ssb: Clear RETRY_...
62
  	u32 val;
61e115a56   Michael Buesch   [SSB]: add Sonics...
63
64
65
66
67
68
69
  
  	ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
  	if (!ssb)
  		goto out;
  	err = pci_enable_device(dev);
  	if (err)
  		goto err_kfree_ssb;
b7b05fe7f   Kay Sievers   ssb: struct devic...
70
  	name = dev_name(&dev->dev);
61e115a56   Michael Buesch   [SSB]: add Sonics...
71
72
73
74
75
76
  	if (dev->driver && dev->driver->name)
  		name = dev->driver->name;
  	err = pci_request_regions(dev, name);
  	if (err)
  		goto err_pci_disable;
  	pci_set_master(dev);
e081685c1   Larry Finger   ssb: Clear RETRY_...
77
78
79
80
81
  	/* Disable the RETRY_TIMEOUT register (0x41) to keep
  	 * PCI Tx retries from interfering with C3 CPU state */
  	pci_read_config_dword(dev, 0x40, &val);
  	if ((val & 0x0000ff00) != 0)
  		pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
61e115a56   Michael Buesch   [SSB]: add Sonics...
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  	err = ssb_bus_pcibus_register(ssb, dev);
  	if (err)
  		goto err_pci_release_regions;
  
  	pci_set_drvdata(dev, ssb);
  
  out:
  	return err;
  
  err_pci_release_regions:
  	pci_release_regions(dev);
  err_pci_disable:
  	pci_disable_device(dev);
  err_kfree_ssb:
  	kfree(ssb);
  	return err;
  }
  
  static void ssb_pcihost_remove(struct pci_dev *dev)
  {
  	struct ssb_bus *ssb = pci_get_drvdata(dev);
  
  	ssb_bus_unregister(ssb);
  	pci_release_regions(dev);
  	pci_disable_device(dev);
  	kfree(ssb);
  	pci_set_drvdata(dev, NULL);
  }
cd1559870   Hauke Mehrtens   ssb: add __devini...
110
  int __devinit ssb_pcihost_register(struct pci_driver *driver)
61e115a56   Michael Buesch   [SSB]: add Sonics...
111
112
113
114
115
116
117
118
119
  {
  	driver->probe = ssb_pcihost_probe;
  	driver->remove = ssb_pcihost_remove;
  	driver->suspend = ssb_pcihost_suspend;
  	driver->resume = ssb_pcihost_resume;
  
  	return pci_register_driver(driver);
  }
  EXPORT_SYMBOL(ssb_pcihost_register);