aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/accessibility/braille/braille_console.c1
-rw-r--r--drivers/hid/hid-lg.h2
-rw-r--r--drivers/hwmon/Kconfig17
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/lis3lv02d_i2c.c183
-rw-r--r--drivers/leds/Kconfig33
-rw-r--r--drivers/leds/Makefile4
-rw-r--r--drivers/leds/leds-adp5520.c230
-rw-r--r--drivers/leds/leds-alix2.c115
-rw-r--r--drivers/leds/leds-cobalt-qube.c4
-rw-r--r--drivers/leds/leds-cobalt-raq.c2
-rw-r--r--drivers/leds/leds-lt3593.c217
-rw-r--r--drivers/leds/leds-pwm.c5
-rw-r--r--drivers/leds/leds-regulator.c242
-rw-r--r--drivers/leds/leds-ss4200.c556
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/mmc/core/sdio.c5
-rw-r--r--drivers/mmc/core/sdio_bus.c7
-rw-r--r--drivers/mmc/host/Kconfig37
-rw-r--r--drivers/mmc/host/Makefile6
-rw-r--r--drivers/mmc/host/sdhci-of-core.c (renamed from drivers/mmc/host/sdhci-of.c)143
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c143
-rw-r--r--drivers/mmc/host/sdhci-of-hlwd.c65
-rw-r--r--drivers/mmc/host/sdhci-of.h42
-rw-r--r--drivers/mmc/host/sdhci.h4
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/pcmcia/pxa2xx_base.c6
-rw-r--r--drivers/platform/x86/compal-laptop.c1
-rw-r--r--drivers/regulator/88pm8607.c685
-rw-r--r--drivers/regulator/Kconfig13
-rw-r--r--drivers/regulator/Makefile4
-rw-r--r--drivers/regulator/ab3100.c33
-rw-r--r--drivers/regulator/core.c248
-rw-r--r--drivers/regulator/da903x.c2
-rw-r--r--drivers/regulator/lp3971.c4
-rw-r--r--drivers/regulator/max8660.c510
-rw-r--r--drivers/regulator/mc13783-regulator.c245
-rw-r--r--drivers/regulator/mc13783.c410
-rw-r--r--drivers/regulator/twl-regulator.c147
-rw-r--r--drivers/regulator/wm831x-dcdc.c207
-rw-r--r--drivers/regulator/wm831x-ldo.c2
-rw-r--r--drivers/rtc/rtc-ds1305.c2
-rw-r--r--drivers/rtc/rtc-ds1307.c2
-rw-r--r--drivers/rtc/rtc-ds1374.c2
-rw-r--r--drivers/spi/Kconfig28
-rw-r--r--drivers/spi/Makefile10
-rw-r--r--drivers/spi/atmel_spi.c6
-rw-r--r--drivers/spi/dw_spi.c944
-rw-r--r--drivers/spi/dw_spi_pci.c169
-rw-r--r--drivers/spi/spi_bfin5xx.c2
-rw-r--r--drivers/spi/spi_mpc8xxx.c2
-rw-r--r--drivers/spi/spi_s3c24xx.c244
-rw-r--r--drivers/spi/spi_s3c24xx_fiq.S116
-rw-r--r--drivers/spi/spi_s3c24xx_fiq.h26
-rw-r--r--drivers/spi/spi_s3c64xx.c1196
-rw-r--r--drivers/spi/spi_sh_sci.c2
-rw-r--r--drivers/spi/spi_txx9.c6
-rw-r--r--drivers/spi/spidev.c18
-rw-r--r--drivers/staging/iio/ring_sw.h1
-rw-r--r--drivers/staging/panel/panel.c2
-rw-r--r--drivers/video/atafb.c3
-rw-r--r--drivers/video/backlight/adp5520_bl.c2
-rw-r--r--drivers/video/backlight/adx_bl.c2
-rw-r--r--drivers/video/backlight/atmel-pwm-bl.c2
-rw-r--r--drivers/video/backlight/backlight.c2
-rw-r--r--drivers/video/backlight/corgi_lcd.c2
-rw-r--r--drivers/video/backlight/cr_bllcd.c4
-rw-r--r--drivers/video/backlight/da903x_bl.c2
-rw-r--r--drivers/video/backlight/generic_bl.c2
-rw-r--r--drivers/video/backlight/hp680_bl.c2
-rw-r--r--drivers/video/backlight/jornada720_bl.c2
-rw-r--r--drivers/video/backlight/kb3886_bl.c2
-rw-r--r--drivers/video/backlight/locomolcd.c2
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c20
-rw-r--r--drivers/video/backlight/omap1_bl.c2
-rw-r--r--drivers/video/backlight/progear_bl.c2
-rw-r--r--drivers/video/backlight/pwm_bl.c11
-rw-r--r--drivers/video/backlight/tosa_bl.c2
-rw-r--r--drivers/video/backlight/wm831x_bl.c2
-rw-r--r--drivers/video/via/viafbdev.c4
81 files changed, 6596 insertions, 851 deletions
diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c
index d672cfe7ca59..cb423f5aef24 100644
--- a/drivers/accessibility/braille/braille_console.c
+++ b/drivers/accessibility/braille/braille_console.c
@@ -21,7 +21,6 @@
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */ 22 */
23 23
24#include <linux/autoconf.h>
25#include <linux/kernel.h> 24#include <linux/kernel.h>
26#include <linux/module.h> 25#include <linux/module.h>
27#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
diff --git a/drivers/hid/hid-lg.h b/drivers/hid/hid-lg.h
index 27ae750ca878..bf31592eaf79 100644
--- a/drivers/hid/hid-lg.h
+++ b/drivers/hid/hid-lg.h
@@ -1,8 +1,6 @@
1#ifndef __HID_LG_H 1#ifndef __HID_LG_H
2#define __HID_LG_H 2#define __HID_LG_H
3 3
4#include <linux/autoconf.h>
5
6#ifdef CONFIG_LOGITECH_FF 4#ifdef CONFIG_LOGITECH_FF
7int lgff_init(struct hid_device *hdev); 5int lgff_init(struct hid_device *hdev);
8#else 6#else
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 95ccbe377f9c..bf28945c610d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -998,6 +998,23 @@ config SENSORS_LIS3_SPI
998 will be called lis3lv02d and a specific module for the SPI transport 998 will be called lis3lv02d and a specific module for the SPI transport
999 is called lis3lv02d_spi. 999 is called lis3lv02d_spi.
1000 1000
1001config SENSORS_LIS3_I2C
1002 tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (I2C)"
1003 depends on I2C && INPUT
1004 select INPUT_POLLDEV
1005 default n
1006 help
1007 This driver provides support for the LIS3LV02Dx accelerometer connected
1008 via I2C. The accelerometer data is readable via
1009 /sys/devices/platform/lis3lv02d.
1010
1011 This driver also provides an absolute input class device, allowing
1012 the device to act as a pinball machine-esque joystick.
1013
1014 This driver can also be built as modules. If so, the core module
1015 will be called lis3lv02d and a specific module for the I2C transport
1016 is called lis3lv02d_i2c.
1017
1001config SENSORS_APPLESMC 1018config SENSORS_APPLESMC
1002 tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" 1019 tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
1003 depends on INPUT && X86 1020 depends on INPUT && X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 33c2ee105284..4131e253f96a 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_SENSORS_IT87) += it87.o
55obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o 55obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o
56obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o 56obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
57obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o 57obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o
58obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d.o lis3lv02d_i2c.o
58obj-$(CONFIG_SENSORS_LM63) += lm63.o 59obj-$(CONFIG_SENSORS_LM63) += lm63.o
59obj-$(CONFIG_SENSORS_LM70) += lm70.o 60obj-$(CONFIG_SENSORS_LM70) += lm70.o
60obj-$(CONFIG_SENSORS_LM73) += lm73.o 61obj-$(CONFIG_SENSORS_LM73) += lm73.o
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
new file mode 100644
index 000000000000..dc1f5402c1d7
--- /dev/null
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -0,0 +1,183 @@
1/*
2 * drivers/hwmon/lis3lv02d_i2c.c
3 *
4 * Implements I2C interface for lis3lv02d (STMicroelectronics) accelerometer.
5 * Driver is based on corresponding SPI driver written by Daniel Mack
6 * (lis3lv02d_spi.c (C) 2009 Daniel Mack <daniel@caiaq.de> ).
7 *
8 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
9 *
10 * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/err.h>
31#include <linux/i2c.h>
32#include "lis3lv02d.h"
33
34#define DRV_NAME "lis3lv02d_i2c"
35
36static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
37{
38 struct i2c_client *c = lis3->bus_priv;
39 return i2c_smbus_write_byte_data(c, reg, value);
40}
41
42static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
43{
44 struct i2c_client *c = lis3->bus_priv;
45 *v = i2c_smbus_read_byte_data(c, reg);
46 return 0;
47}
48
49static int lis3_i2c_init(struct lis3lv02d *lis3)
50{
51 u8 reg;
52 int ret;
53
54 /* power up the device */
55 ret = lis3->read(lis3, CTRL_REG1, &reg);
56 if (ret < 0)
57 return ret;
58
59 reg |= CTRL1_PD0;
60 return lis3->write(lis3, CTRL_REG1, reg);
61}
62
63/* Default axis mapping but it can be overwritten by platform data */
64static struct axis_conversion lis3lv02d_axis_map = { LIS3_DEV_X,
65 LIS3_DEV_Y,
66 LIS3_DEV_Z };
67
68static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
69 const struct i2c_device_id *id)
70{
71 int ret = 0;
72 struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
73
74 if (pdata) {
75 if (pdata->axis_x)
76 lis3lv02d_axis_map.x = pdata->axis_x;
77
78 if (pdata->axis_y)
79 lis3lv02d_axis_map.y = pdata->axis_y;
80
81 if (pdata->axis_z)
82 lis3lv02d_axis_map.z = pdata->axis_z;
83
84 if (pdata->setup_resources)
85 ret = pdata->setup_resources();
86
87 if (ret)
88 goto fail;
89 }
90
91 lis3_dev.pdata = pdata;
92 lis3_dev.bus_priv = client;
93 lis3_dev.init = lis3_i2c_init;
94 lis3_dev.read = lis3_i2c_read;
95 lis3_dev.write = lis3_i2c_write;
96 lis3_dev.irq = client->irq;
97 lis3_dev.ac = lis3lv02d_axis_map;
98
99 i2c_set_clientdata(client, &lis3_dev);
100 ret = lis3lv02d_init_device(&lis3_dev);
101fail:
102 return ret;
103}
104
105static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
106{
107 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
108 struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
109
110 if (pdata && pdata->release_resources)
111 pdata->release_resources();
112
113 lis3lv02d_joystick_disable();
114 lis3lv02d_poweroff(lis3);
115
116 return lis3lv02d_remove_fs(&lis3_dev);
117}
118
119#ifdef CONFIG_PM
120static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
121{
122 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
123
124 if (!lis3->pdata->wakeup_flags)
125 lis3lv02d_poweroff(lis3);
126 return 0;
127}
128
129static int lis3lv02d_i2c_resume(struct i2c_client *client)
130{
131 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
132
133 if (!lis3->pdata->wakeup_flags)
134 lis3lv02d_poweron(lis3);
135 return 0;
136}
137
138static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
139{
140 lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
141}
142#else
143#define lis3lv02d_i2c_suspend NULL
144#define lis3lv02d_i2c_resume NULL
145#define lis3lv02d_i2c_shutdown NULL
146#endif
147
148static const struct i2c_device_id lis3lv02d_id[] = {
149 {"lis3lv02d", 0 },
150 {}
151};
152
153MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
154
155static struct i2c_driver lis3lv02d_i2c_driver = {
156 .driver = {
157 .name = DRV_NAME,
158 .owner = THIS_MODULE,
159 },
160 .suspend = lis3lv02d_i2c_suspend,
161 .shutdown = lis3lv02d_i2c_shutdown,
162 .resume = lis3lv02d_i2c_resume,
163 .probe = lis3lv02d_i2c_probe,
164 .remove = __devexit_p(lis3lv02d_i2c_remove),
165 .id_table = lis3lv02d_id,
166};
167
168static int __init lis3lv02d_init(void)
169{
170 return i2c_add_driver(&lis3lv02d_i2c_driver);
171}
172
173static void __exit lis3lv02d_exit(void)
174{
175 i2c_del_driver(&lis3lv02d_i2c_driver);
176}
177
178MODULE_AUTHOR("Nokia Corporation");
179MODULE_DESCRIPTION("lis3lv02d I2C interface");
180MODULE_LICENSE("GPL");
181
182module_init(lis3lv02d_init);
183module_exit(lis3lv02d_exit);
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index e4f599f20e38..8a0e1ec95e4a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -229,6 +229,12 @@ config LEDS_PWM
229 help 229 help
230 This option enables support for pwm driven LEDs 230 This option enables support for pwm driven LEDs
231 231
232config LEDS_REGULATOR
233 tristate "REGULATOR driven LED support"
234 depends on LEDS_CLASS && REGULATOR
235 help
236 This option enables support for regulator driven LEDs.
237
232config LEDS_BD2802 238config LEDS_BD2802
233 tristate "LED driver for BD2802 RGB LED" 239 tristate "LED driver for BD2802 RGB LED"
234 depends on LEDS_CLASS && I2C 240 depends on LEDS_CLASS && I2C
@@ -236,6 +242,33 @@ config LEDS_BD2802
236 This option enables support for BD2802GU RGB LED driver chips 242 This option enables support for BD2802GU RGB LED driver chips
237 accessed via the I2C bus. 243 accessed via the I2C bus.
238 244
245config LEDS_INTEL_SS4200
246 tristate "LED driver for Intel NAS SS4200 series"
247 depends on LEDS_CLASS && PCI && DMI
248 help
249 This option enables support for the Intel SS4200 series of
250 Network Attached Storage servers. You may control the hard
251 drive or power LEDs on the front panel. Using this driver
252 can stop the front LED from blinking after startup.
253
254config LEDS_LT3593
255 tristate "LED driver for LT3593 controllers"
256 depends on LEDS_CLASS && GENERIC_GPIO
257 help
258 This option enables support for LEDs driven by a Linear Technology
259 LT3593 controller. This controller uses a special one-wire pulse
260 coding protocol to set the brightness.
261
262config LEDS_ADP5520
263 tristate "LED Support for ADP5520/ADP5501 PMIC"
264 depends on LEDS_CLASS && PMIC_ADP5520
265 help
266 This option enables support for on-chip LED drivers found
267 on Analog Devices ADP5520/ADP5501 PMICs.
268
269 To compile this driver as a module, choose M here: the module will
270 be called leds-adp5520.
271
239comment "LED Triggers" 272comment "LED Triggers"
240 273
241config LEDS_TRIGGERS 274config LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 46d72704d606..9e63869d7c0d 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -29,6 +29,10 @@ obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
29obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o 29obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
30obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o 30obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
31obj-$(CONFIG_LEDS_PWM) += leds-pwm.o 31obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
32obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o
33obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o
34obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o
35obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o
32 36
33# LED SPI Drivers 37# LED SPI Drivers
34obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o 38obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c
new file mode 100644
index 000000000000..a8f315902131
--- /dev/null
+++ b/drivers/leds/leds-adp5520.c
@@ -0,0 +1,230 @@
1/*
2 * LEDs driver for Analog Devices ADP5520/ADP5501 MFD PMICs
3 *
4 * Copyright 2009 Analog Devices Inc.
5 *
6 * Loosely derived from leds-da903x:
7 * Copyright (C) 2008 Compulab, Ltd.
8 * Mike Rapoport <mike@compulab.co.il>
9 *
10 * Copyright (C) 2006-2008 Marvell International Ltd.
11 * Eric Miao <eric.miao@marvell.com>
12 *
13 * Licensed under the GPL-2 or later.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/leds.h>
21#include <linux/workqueue.h>
22#include <linux/mfd/adp5520.h>
23
24struct adp5520_led {
25 struct led_classdev cdev;
26 struct work_struct work;
27 struct device *master;
28 enum led_brightness new_brightness;
29 int id;
30 int flags;
31};
32
33static void adp5520_led_work(struct work_struct *work)
34{
35 struct adp5520_led *led = container_of(work, struct adp5520_led, work);
36 adp5520_write(led->master, ADP5520_LED1_CURRENT + led->id - 1,
37 led->new_brightness >> 2);
38}
39
40static void adp5520_led_set(struct led_classdev *led_cdev,
41 enum led_brightness value)
42{
43 struct adp5520_led *led;
44
45 led = container_of(led_cdev, struct adp5520_led, cdev);
46 led->new_brightness = value;
47 schedule_work(&led->work);
48}
49
50static int adp5520_led_setup(struct adp5520_led *led)
51{
52 struct device *dev = led->master;
53 int flags = led->flags;
54 int ret = 0;
55
56 switch (led->id) {
57 case FLAG_ID_ADP5520_LED1_ADP5501_LED0:
58 ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
59 (flags >> ADP5520_FLAG_OFFT_SHIFT) &
60 ADP5520_FLAG_OFFT_MASK);
61 ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
62 ADP5520_LED1_EN);
63 break;
64 case FLAG_ID_ADP5520_LED2_ADP5501_LED1:
65 ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
66 ((flags >> ADP5520_FLAG_OFFT_SHIFT) &
67 ADP5520_FLAG_OFFT_MASK) << 2);
68 ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL,
69 ADP5520_R3_MODE);
70 ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
71 ADP5520_LED2_EN);
72 break;
73 case FLAG_ID_ADP5520_LED3_ADP5501_LED2:
74 ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
75 ((flags >> ADP5520_FLAG_OFFT_SHIFT) &
76 ADP5520_FLAG_OFFT_MASK) << 4);
77 ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL,
78 ADP5520_C3_MODE);
79 ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
80 ADP5520_LED3_EN);
81 break;
82 }
83
84 return ret;
85}
86
87static int __devinit adp5520_led_prepare(struct platform_device *pdev)
88{
89 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
90 struct device *dev = pdev->dev.parent;
91 int ret = 0;
92
93 ret |= adp5520_write(dev, ADP5520_LED1_CURRENT, 0);
94 ret |= adp5520_write(dev, ADP5520_LED2_CURRENT, 0);
95 ret |= adp5520_write(dev, ADP5520_LED3_CURRENT, 0);
96 ret |= adp5520_write(dev, ADP5520_LED_TIME, pdata->led_on_time << 6);
97 ret |= adp5520_write(dev, ADP5520_LED_FADE, FADE_VAL(pdata->fade_in,
98 pdata->fade_out));
99
100 return ret;
101}
102
103static int __devinit adp5520_led_probe(struct platform_device *pdev)
104{
105 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
106 struct adp5520_led *led, *led_dat;
107 struct led_info *cur_led;
108 int ret, i;
109
110 if (pdata == NULL) {
111 dev_err(&pdev->dev, "missing platform data\n");
112 return -ENODEV;
113 }
114
115 if (pdata->num_leds > ADP5520_01_MAXLEDS) {
116 dev_err(&pdev->dev, "can't handle more than %d LEDS\n",
117 ADP5520_01_MAXLEDS);
118 return -EFAULT;
119 }
120
121 led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL);
122 if (led == NULL) {
123 dev_err(&pdev->dev, "failed to alloc memory\n");
124 return -ENOMEM;
125 }
126
127 ret = adp5520_led_prepare(pdev);
128
129 if (ret) {
130 dev_err(&pdev->dev, "failed to write\n");
131 goto err_free;
132 }
133
134 for (i = 0; i < pdata->num_leds; ++i) {
135 cur_led = &pdata->leds[i];
136 led_dat = &led[i];
137
138 led_dat->cdev.name = cur_led->name;
139 led_dat->cdev.default_trigger = cur_led->default_trigger;
140 led_dat->cdev.brightness_set = adp5520_led_set;
141 led_dat->cdev.brightness = LED_OFF;
142
143 if (cur_led->flags & ADP5520_FLAG_LED_MASK)
144 led_dat->flags = cur_led->flags;
145 else
146 led_dat->flags = i + 1;
147
148 led_dat->id = led_dat->flags & ADP5520_FLAG_LED_MASK;
149
150 led_dat->master = pdev->dev.parent;
151 led_dat->new_brightness = LED_OFF;
152
153 INIT_WORK(&led_dat->work, adp5520_led_work);
154
155 ret = led_classdev_register(led_dat->master, &led_dat->cdev);
156 if (ret) {
157 dev_err(&pdev->dev, "failed to register LED %d\n",
158 led_dat->id);
159 goto err;
160 }
161
162 ret = adp5520_led_setup(led_dat);
163 if (ret) {
164 dev_err(&pdev->dev, "failed to write\n");
165 i++;
166 goto err;
167 }
168 }
169
170 platform_set_drvdata(pdev, led);
171 return 0;
172
173err:
174 if (i > 0) {
175 for (i = i - 1; i >= 0; i--) {
176 led_classdev_unregister(&led[i].cdev);
177 cancel_work_sync(&led[i].work);
178 }
179 }
180
181err_free:
182 kfree(led);
183 return ret;
184}
185
186static int __devexit adp5520_led_remove(struct platform_device *pdev)
187{
188 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
189 struct adp5520_led *led;
190 int i;
191
192 led = platform_get_drvdata(pdev);
193
194 adp5520_clr_bits(led->master, ADP5520_LED_CONTROL,
195 ADP5520_LED1_EN | ADP5520_LED2_EN | ADP5520_LED3_EN);
196
197 for (i = 0; i < pdata->num_leds; i++) {
198 led_classdev_unregister(&led[i].cdev);
199 cancel_work_sync(&led[i].work);
200 }
201
202 kfree(led);
203 return 0;
204}
205
206static struct platform_driver adp5520_led_driver = {
207 .driver = {
208 .name = "adp5520-led",
209 .owner = THIS_MODULE,
210 },
211 .probe = adp5520_led_probe,
212 .remove = __devexit_p(adp5520_led_remove),
213};
214
215static int __init adp5520_led_init(void)
216{
217 return platform_driver_register(&adp5520_led_driver);
218}
219module_init(adp5520_led_init);
220
221static void __exit adp5520_led_exit(void)
222{
223 platform_driver_unregister(&adp5520_led_driver);
224}
225module_exit(adp5520_led_exit);
226
227MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
228MODULE_DESCRIPTION("LEDS ADP5520(01) Driver");
229MODULE_LICENSE("GPL");
230MODULE_ALIAS("platform:adp5520-led");
diff --git a/drivers/leds/leds-alix2.c b/drivers/leds/leds-alix2.c
index 731d4eef3425..f59ffadf5125 100644
--- a/drivers/leds/leds-alix2.c
+++ b/drivers/leds/leds-alix2.c
@@ -11,11 +11,24 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/string.h> 13#include <linux/string.h>
14#include <linux/pci.h>
14 15
15static int force = 0; 16static int force = 0;
16module_param(force, bool, 0444); 17module_param(force, bool, 0444);
17MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs"); 18MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs");
18 19
20#define MSR_LBAR_GPIO 0x5140000C
21#define CS5535_GPIO_SIZE 256
22
23static u32 gpio_base;
24
25static struct pci_device_id divil_pci[] = {
26 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
27 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
28 { } /* NULL entry */
29};
30MODULE_DEVICE_TABLE(pci, divil_pci);
31
19struct alix_led { 32struct alix_led {
20 struct led_classdev cdev; 33 struct led_classdev cdev;
21 unsigned short port; 34 unsigned short port;
@@ -30,9 +43,9 @@ static void alix_led_set(struct led_classdev *led_cdev,
30 container_of(led_cdev, struct alix_led, cdev); 43 container_of(led_cdev, struct alix_led, cdev);
31 44
32 if (brightness) 45 if (brightness)
33 outl(led_dev->on_value, led_dev->port); 46 outl(led_dev->on_value, gpio_base + led_dev->port);
34 else 47 else
35 outl(led_dev->off_value, led_dev->port); 48 outl(led_dev->off_value, gpio_base + led_dev->port);
36} 49}
37 50
38static struct alix_led alix_leds[] = { 51static struct alix_led alix_leds[] = {
@@ -41,7 +54,7 @@ static struct alix_led alix_leds[] = {
41 .name = "alix:1", 54 .name = "alix:1",
42 .brightness_set = alix_led_set, 55 .brightness_set = alix_led_set,
43 }, 56 },
44 .port = 0x6100, 57 .port = 0x00,
45 .on_value = 1 << 22, 58 .on_value = 1 << 22,
46 .off_value = 1 << 6, 59 .off_value = 1 << 6,
47 }, 60 },
@@ -50,7 +63,7 @@ static struct alix_led alix_leds[] = {
50 .name = "alix:2", 63 .name = "alix:2",
51 .brightness_set = alix_led_set, 64 .brightness_set = alix_led_set,
52 }, 65 },
53 .port = 0x6180, 66 .port = 0x80,
54 .on_value = 1 << 25, 67 .on_value = 1 << 25,
55 .off_value = 1 << 9, 68 .off_value = 1 << 9,
56 }, 69 },
@@ -59,7 +72,7 @@ static struct alix_led alix_leds[] = {
59 .name = "alix:3", 72 .name = "alix:3",
60 .brightness_set = alix_led_set, 73 .brightness_set = alix_led_set,
61 }, 74 },
62 .port = 0x6180, 75 .port = 0x80,
63 .on_value = 1 << 27, 76 .on_value = 1 << 27,
64 .off_value = 1 << 11, 77 .off_value = 1 << 11,
65 }, 78 },
@@ -101,64 +114,104 @@ static struct platform_driver alix_led_driver = {
101 }, 114 },
102}; 115};
103 116
104static int __init alix_present(void) 117static int __init alix_present(unsigned long bios_phys,
118 const char *alix_sig,
119 size_t alix_sig_len)
105{ 120{
106 const unsigned long bios_phys = 0x000f0000;
107 const size_t bios_len = 0x00010000; 121 const size_t bios_len = 0x00010000;
108 const char alix_sig[] = "PC Engines ALIX.";
109 const size_t alix_sig_len = sizeof(alix_sig) - 1;
110
111 const char *bios_virt; 122 const char *bios_virt;
112 const char *scan_end; 123 const char *scan_end;
113 const char *p; 124 const char *p;
114 int ret = 0; 125 char name[64];
115 126
116 if (force) { 127 if (force) {
117 printk(KERN_NOTICE "%s: forced to skip BIOS test, " 128 printk(KERN_NOTICE "%s: forced to skip BIOS test, "
118 "assume system has ALIX.2 style LEDs\n", 129 "assume system has ALIX.2 style LEDs\n",
119 KBUILD_MODNAME); 130 KBUILD_MODNAME);
120 ret = 1; 131 return 1;
121 goto out;
122 } 132 }
123 133
124 bios_virt = phys_to_virt(bios_phys); 134 bios_virt = phys_to_virt(bios_phys);
125 scan_end = bios_virt + bios_len - (alix_sig_len + 2); 135 scan_end = bios_virt + bios_len - (alix_sig_len + 2);
126 for (p = bios_virt; p < scan_end; p++) { 136 for (p = bios_virt; p < scan_end; p++) {
127 const char *tail; 137 const char *tail;
138 char *a;
128 139
129 if (memcmp(p, alix_sig, alix_sig_len) != 0) { 140 if (memcmp(p, alix_sig, alix_sig_len) != 0)
130 continue; 141 continue;
131 } 142
143 memcpy(name, p, sizeof(name));
144
145 /* remove the first \0 character from string */
146 a = strchr(name, '\0');
147 if (a)
148 *a = ' ';
149
150 /* cut the string at a newline */
151 a = strchr(name, '\r');
152 if (a)
153 *a = '\0';
132 154
133 tail = p + alix_sig_len; 155 tail = p + alix_sig_len;
134 if ((tail[0] == '2' || tail[0] == '3') && tail[1] == '\0') { 156 if ((tail[0] == '2' || tail[0] == '3')) {
135 printk(KERN_INFO 157 printk(KERN_INFO
136 "%s: system is recognized as \"%s\"\n", 158 "%s: system is recognized as \"%s\"\n",
137 KBUILD_MODNAME, p); 159 KBUILD_MODNAME, name);
138 ret = 1; 160 return 1;
139 break;
140 } 161 }
141 } 162 }
142 163
143out: 164 return 0;
144 return ret;
145} 165}
146 166
147static struct platform_device *pdev; 167static struct platform_device *pdev;
148 168
149static int __init alix_led_init(void) 169static int __init alix_pci_led_init(void)
150{ 170{
151 int ret; 171 u32 low, hi;
152 172
153 if (!alix_present()) { 173 if (pci_dev_present(divil_pci) == 0) {
154 ret = -ENODEV; 174 printk(KERN_WARNING KBUILD_MODNAME": DIVIL not found\n");
155 goto out; 175 return -ENODEV;
156 } 176 }
157 177
158 /* enable output on GPIO for LED 1,2,3 */ 178 /* Grab the GPIO I/O range */
159 outl(1 << 6, 0x6104); 179 rdmsr(MSR_LBAR_GPIO, low, hi);
160 outl(1 << 9, 0x6184); 180
161 outl(1 << 11, 0x6184); 181 /* Check the mask and whether GPIO is enabled (sanity check) */
182 if (hi != 0x0000f001) {
183 printk(KERN_WARNING KBUILD_MODNAME": GPIO not enabled\n");
184 return -ENODEV;
185 }
186
187 /* Mask off the IO base address */
188 gpio_base = low & 0x0000ff00;
189
190 if (!request_region(gpio_base, CS5535_GPIO_SIZE, KBUILD_MODNAME)) {
191 printk(KERN_ERR KBUILD_MODNAME": can't allocate I/O for GPIO\n");
192 return -ENODEV;
193 }
194
195 /* Set GPIO function to output */
196 outl(1 << 6, gpio_base + 0x04);
197 outl(1 << 9, gpio_base + 0x84);
198 outl(1 << 11, gpio_base + 0x84);
199
200 return 0;
201}
202
203static int __init alix_led_init(void)
204{
205 int ret = -ENODEV;
206 const char tinybios_sig[] = "PC Engines ALIX.";
207 const char coreboot_sig[] = "PC Engines\0ALIX.";
208
209 if (alix_present(0xf0000, tinybios_sig, sizeof(tinybios_sig) - 1) ||
210 alix_present(0x500, coreboot_sig, sizeof(coreboot_sig) - 1))
211 ret = alix_pci_led_init();
212
213 if (ret < 0)
214 return ret;
162 215
163 pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0); 216 pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0);
164 if (!IS_ERR(pdev)) { 217 if (!IS_ERR(pdev)) {
@@ -168,7 +221,6 @@ static int __init alix_led_init(void)
168 } else 221 } else
169 ret = PTR_ERR(pdev); 222 ret = PTR_ERR(pdev);
170 223
171out:
172 return ret; 224 return ret;
173} 225}
174 226
@@ -176,6 +228,7 @@ static void __exit alix_led_exit(void)
176{ 228{
177 platform_device_unregister(pdev); 229 platform_device_unregister(pdev);
178 platform_driver_unregister(&alix_led_driver); 230 platform_driver_unregister(&alix_led_driver);
231 release_region(gpio_base, CS5535_GPIO_SIZE);
179} 232}
180 233
181module_init(alix_led_init); 234module_init(alix_led_init);
diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c
index 8816806accd2..da5fb016b1a5 100644
--- a/drivers/leds/leds-cobalt-qube.c
+++ b/drivers/leds/leds-cobalt-qube.c
@@ -31,7 +31,7 @@ static struct led_classdev qube_front_led = {
31 .name = "qube::front", 31 .name = "qube::front",
32 .brightness = LED_FULL, 32 .brightness = LED_FULL,
33 .brightness_set = qube_front_led_set, 33 .brightness_set = qube_front_led_set,
34 .default_trigger = "ide-disk", 34 .default_trigger = "default-on",
35}; 35};
36 36
37static int __devinit cobalt_qube_led_probe(struct platform_device *pdev) 37static int __devinit cobalt_qube_led_probe(struct platform_device *pdev)
@@ -43,7 +43,7 @@ static int __devinit cobalt_qube_led_probe(struct platform_device *pdev)
43 if (!res) 43 if (!res)
44 return -EBUSY; 44 return -EBUSY;
45 45
46 led_port = ioremap(res->start, res->end - res->start + 1); 46 led_port = ioremap(res->start, resource_size(res));
47 if (!led_port) 47 if (!led_port)
48 return -ENOMEM; 48 return -ENOMEM;
49 49
diff --git a/drivers/leds/leds-cobalt-raq.c b/drivers/leds/leds-cobalt-raq.c
index defc212105f3..438d48384636 100644
--- a/drivers/leds/leds-cobalt-raq.c
+++ b/drivers/leds/leds-cobalt-raq.c
@@ -84,7 +84,7 @@ static int __devinit cobalt_raq_led_probe(struct platform_device *pdev)
84 if (!res) 84 if (!res)
85 return -EBUSY; 85 return -EBUSY;
86 86
87 led_port = ioremap(res->start, res->end - res->start + 1); 87 led_port = ioremap(res->start, resource_size(res));
88 if (!led_port) 88 if (!led_port)
89 return -ENOMEM; 89 return -ENOMEM;
90 90
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
new file mode 100644
index 000000000000..fee40a841959
--- /dev/null
+++ b/drivers/leds/leds-lt3593.c
@@ -0,0 +1,217 @@
1/*
2 * LEDs driver for LT3593 controllers
3 *
4 * See the datasheet at http://cds.linear.com/docs/Datasheet/3593f.pdf
5 *
6 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
7 *
8 * Based on leds-gpio.c,
9 *
10 * Copyright (C) 2007 8D Technologies inc.
11 * Raphael Assenat <raph@8d.com>
12 * Copyright (C) 2008 Freescale Semiconductor, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/leds.h>
23#include <linux/workqueue.h>
24#include <linux/delay.h>
25#include <linux/gpio.h>
26
27struct lt3593_led_data {
28 struct led_classdev cdev;
29 unsigned gpio;
30 struct work_struct work;
31 u8 new_level;
32};
33
34static void lt3593_led_work(struct work_struct *work)
35{
36 int pulses;
37 struct lt3593_led_data *led_dat =
38 container_of(work, struct lt3593_led_data, work);
39
40 /*
41 * The LT3593 resets its internal current level register to the maximum
42 * level on the first falling edge on the control pin. Each following
43 * falling edge decreases the current level by 625uA. Up to 32 pulses
44 * can be sent, so the maximum power reduction is 20mA.
45 * After a timeout of 128us, the value is taken from the register and
46 * applied is to the output driver.
47 */
48
49 if (led_dat->new_level == 0) {
50 gpio_set_value_cansleep(led_dat->gpio, 0);
51 return;
52 }
53
54 pulses = 32 - (led_dat->new_level * 32) / 255;
55
56 if (pulses == 0) {
57 gpio_set_value_cansleep(led_dat->gpio, 0);
58 mdelay(1);
59 gpio_set_value_cansleep(led_dat->gpio, 1);
60 return;
61 }
62
63 gpio_set_value_cansleep(led_dat->gpio, 1);
64
65 while (pulses--) {
66 gpio_set_value_cansleep(led_dat->gpio, 0);
67 udelay(1);
68 gpio_set_value_cansleep(led_dat->gpio, 1);
69 udelay(1);
70 }
71}
72
73static void lt3593_led_set(struct led_classdev *led_cdev,
74 enum led_brightness value)
75{
76 struct lt3593_led_data *led_dat =
77 container_of(led_cdev, struct lt3593_led_data, cdev);
78
79 led_dat->new_level = value;
80 schedule_work(&led_dat->work);
81}
82
83static int __devinit create_lt3593_led(const struct gpio_led *template,
84 struct lt3593_led_data *led_dat, struct device *parent)
85{
86 int ret, state;
87
88 /* skip leds on GPIOs that aren't available */
89 if (!gpio_is_valid(template->gpio)) {
90 printk(KERN_INFO "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n",
91 KBUILD_MODNAME, template->gpio, template->name);
92 return 0;
93 }
94
95 ret = gpio_request(template->gpio, template->name);
96 if (ret < 0)
97 return ret;
98
99 led_dat->cdev.name = template->name;
100 led_dat->cdev.default_trigger = template->default_trigger;
101 led_dat->gpio = template->gpio;
102
103 led_dat->cdev.brightness_set = lt3593_led_set;
104
105 state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
106 led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
107
108 if (!template->retain_state_suspended)
109 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
110
111 ret = gpio_direction_output(led_dat->gpio, state);
112 if (ret < 0)
113 goto err;
114
115 INIT_WORK(&led_dat->work, lt3593_led_work);
116
117 ret = led_classdev_register(parent, &led_dat->cdev);
118 if (ret < 0)
119 goto err;
120
121 printk(KERN_INFO "%s: registered LT3593 LED '%s' at GPIO %d\n",
122 KBUILD_MODNAME, template->name, template->gpio);
123
124 return 0;
125
126err:
127 gpio_free(led_dat->gpio);
128 return ret;
129}
130
131static void delete_lt3593_led(struct lt3593_led_data *led)
132{
133 if (!gpio_is_valid(led->gpio))
134 return;
135
136 led_classdev_unregister(&led->cdev);
137 cancel_work_sync(&led->work);
138 gpio_free(led->gpio);
139}
140
141static int __devinit lt3593_led_probe(struct platform_device *pdev)
142{
143 struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
144 struct lt3593_led_data *leds_data;
145 int i, ret = 0;
146
147 if (!pdata)
148 return -EBUSY;
149
150 leds_data = kzalloc(sizeof(struct lt3593_led_data) * pdata->num_leds,
151 GFP_KERNEL);
152 if (!leds_data)
153 return -ENOMEM;
154
155 for (i = 0; i < pdata->num_leds; i++) {
156 ret = create_lt3593_led(&pdata->leds[i], &leds_data[i],
157 &pdev->dev);
158 if (ret < 0)
159 goto err;
160 }
161
162 platform_set_drvdata(pdev, leds_data);
163
164 return 0;
165
166err:
167 for (i = i - 1; i >= 0; i--)
168 delete_lt3593_led(&leds_data[i]);
169
170 kfree(leds_data);
171
172 return ret;
173}
174
175static int __devexit lt3593_led_remove(struct platform_device *pdev)
176{
177 int i;
178 struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
179 struct lt3593_led_data *leds_data;
180
181 leds_data = platform_get_drvdata(pdev);
182
183 for (i = 0; i < pdata->num_leds; i++)
184 delete_lt3593_led(&leds_data[i]);
185
186 kfree(leds_data);
187
188 return 0;
189}
190
191static struct platform_driver lt3593_led_driver = {
192 .probe = lt3593_led_probe,
193 .remove = __devexit_p(lt3593_led_remove),
194 .driver = {
195 .name = "leds-lt3593",
196 .owner = THIS_MODULE,
197 },
198};
199
200MODULE_ALIAS("platform:leds-lt3593");
201
202static int __init lt3593_led_init(void)
203{
204 return platform_driver_register(&lt3593_led_driver);
205}
206
207static void __exit lt3593_led_exit(void)
208{
209 platform_driver_unregister(&lt3593_led_driver);
210}
211
212module_init(lt3593_led_init);
213module_exit(lt3593_led_exit);
214
215MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
216MODULE_DESCRIPTION("LED driver for LT3593 controllers");
217MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index cdfdc8714e10..88b1dd091cfb 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -27,7 +27,6 @@ struct led_pwm_data {
27 struct pwm_device *pwm; 27 struct pwm_device *pwm;
28 unsigned int active_low; 28 unsigned int active_low;
29 unsigned int period; 29 unsigned int period;
30 unsigned int max_brightness;
31}; 30};
32 31
33static void led_pwm_set(struct led_classdev *led_cdev, 32static void led_pwm_set(struct led_classdev *led_cdev,
@@ -35,7 +34,7 @@ static void led_pwm_set(struct led_classdev *led_cdev,
35{ 34{
36 struct led_pwm_data *led_dat = 35 struct led_pwm_data *led_dat =
37 container_of(led_cdev, struct led_pwm_data, cdev); 36 container_of(led_cdev, struct led_pwm_data, cdev);
38 unsigned int max = led_dat->max_brightness; 37 unsigned int max = led_dat->cdev.max_brightness;
39 unsigned int period = led_dat->period; 38 unsigned int period = led_dat->period;
40 39
41 if (brightness == 0) { 40 if (brightness == 0) {
@@ -77,10 +76,10 @@ static int led_pwm_probe(struct platform_device *pdev)
77 led_dat->cdev.name = cur_led->name; 76 led_dat->cdev.name = cur_led->name;
78 led_dat->cdev.default_trigger = cur_led->default_trigger; 77 led_dat->cdev.default_trigger = cur_led->default_trigger;
79 led_dat->active_low = cur_led->active_low; 78 led_dat->active_low = cur_led->active_low;
80 led_dat->max_brightness = cur_led->max_brightness;
81 led_dat->period = cur_led->pwm_period_ns; 79 led_dat->period = cur_led->pwm_period_ns;
82 led_dat->cdev.brightness_set = led_pwm_set; 80 led_dat->cdev.brightness_set = led_pwm_set;
83 led_dat->cdev.brightness = LED_OFF; 81 led_dat->cdev.brightness = LED_OFF;
82 led_dat->cdev.max_brightness = cur_led->max_brightness;
84 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 83 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
85 84
86 ret = led_classdev_register(&pdev->dev, &led_dat->cdev); 85 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c
new file mode 100644
index 000000000000..7f00de3ef922
--- /dev/null
+++ b/drivers/leds/leds-regulator.c
@@ -0,0 +1,242 @@
1/*
2 * leds-regulator.c - LED class driver for regulator driven LEDs.
3 *
4 * Copyright (C) 2009 Antonio Ospite <ospite@studenti.unina.it>
5 *
6 * Inspired by leds-wm8350 driver.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/err.h>
16#include <linux/workqueue.h>
17#include <linux/leds.h>
18#include <linux/leds-regulator.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/consumer.h>
21
22#define to_regulator_led(led_cdev) \
23 container_of(led_cdev, struct regulator_led, cdev)
24
25struct regulator_led {
26 struct led_classdev cdev;
27 enum led_brightness value;
28 int enabled;
29 struct mutex mutex;
30 struct work_struct work;
31
32 struct regulator *vcc;
33};
34
35static inline int led_regulator_get_max_brightness(struct regulator *supply)
36{
37 int ret;
38 int voltage = regulator_list_voltage(supply, 0);
39
40 if (voltage <= 0)
41 return 1;
42
43 /* even if regulator can't change voltages,
44 * we still assume it can change status
45 * and the LED can be turned on and off.
46 */
47 ret = regulator_set_voltage(supply, voltage, voltage);
48 if (ret < 0)
49 return 1;
50
51 return regulator_count_voltages(supply);
52}
53
54static int led_regulator_get_voltage(struct regulator *supply,
55 enum led_brightness brightness)
56{
57 if (brightness == 0)
58 return -EINVAL;
59
60 return regulator_list_voltage(supply, brightness - 1);
61}
62
63
64static void regulator_led_enable(struct regulator_led *led)
65{
66 int ret;
67
68 if (led->enabled)
69 return;
70
71 ret = regulator_enable(led->vcc);
72 if (ret != 0) {
73 dev_err(led->cdev.dev, "Failed to enable vcc: %d\n", ret);
74 return;
75 }
76
77 led->enabled = 1;
78}
79
80static void regulator_led_disable(struct regulator_led *led)
81{
82 int ret;
83
84 if (!led->enabled)
85 return;
86
87 ret = regulator_disable(led->vcc);
88 if (ret != 0) {
89 dev_err(led->cdev.dev, "Failed to disable vcc: %d\n", ret);
90 return;
91 }
92
93 led->enabled = 0;
94}
95
96static void regulator_led_set_value(struct regulator_led *led)
97{
98 int voltage;
99 int ret;
100
101 mutex_lock(&led->mutex);
102
103 if (led->value == LED_OFF) {
104 regulator_led_disable(led);
105 goto out;
106 }
107
108 if (led->cdev.max_brightness > 1) {
109 voltage = led_regulator_get_voltage(led->vcc, led->value);
110 dev_dbg(led->cdev.dev, "brightness: %d voltage: %d\n",
111 led->value, voltage);
112
113 ret = regulator_set_voltage(led->vcc, voltage, voltage);
114 if (ret != 0)
115 dev_err(led->cdev.dev, "Failed to set voltage %d: %d\n",
116 voltage, ret);
117 }
118
119 regulator_led_enable(led);
120
121out:
122 mutex_unlock(&led->mutex);
123}
124
125static void led_work(struct work_struct *work)
126{
127 struct regulator_led *led;
128
129 led = container_of(work, struct regulator_led, work);
130 regulator_led_set_value(led);
131}
132
133static void regulator_led_brightness_set(struct led_classdev *led_cdev,
134 enum led_brightness value)
135{
136 struct regulator_led *led = to_regulator_led(led_cdev);
137
138 led->value = value;
139 schedule_work(&led->work);
140}
141
142static int __devinit regulator_led_probe(struct platform_device *pdev)
143{
144 struct led_regulator_platform_data *pdata = pdev->dev.platform_data;
145 struct regulator_led *led;
146 struct regulator *vcc;
147 int ret = 0;
148
149 if (pdata == NULL) {
150 dev_err(&pdev->dev, "no platform data\n");
151 return -ENODEV;
152 }
153
154 vcc = regulator_get_exclusive(&pdev->dev, "vled");
155 if (IS_ERR(vcc)) {
156 dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name);
157 return PTR_ERR(vcc);
158 }
159
160 led = kzalloc(sizeof(*led), GFP_KERNEL);
161 if (led == NULL) {
162 ret = -ENOMEM;
163 goto err_vcc;
164 }
165
166 led->cdev.max_brightness = led_regulator_get_max_brightness(vcc);
167 if (pdata->brightness > led->cdev.max_brightness) {
168 dev_err(&pdev->dev, "Invalid default brightness %d\n",
169 pdata->brightness);
170 ret = -EINVAL;
171 goto err_led;
172 }
173 led->value = pdata->brightness;
174
175 led->cdev.brightness_set = regulator_led_brightness_set;
176 led->cdev.name = pdata->name;
177 led->cdev.flags |= LED_CORE_SUSPENDRESUME;
178 led->vcc = vcc;
179
180 mutex_init(&led->mutex);
181 INIT_WORK(&led->work, led_work);
182
183 platform_set_drvdata(pdev, led);
184
185 ret = led_classdev_register(&pdev->dev, &led->cdev);
186 if (ret < 0) {
187 cancel_work_sync(&led->work);
188 goto err_led;
189 }
190
191 /* to expose the default value to userspace */
192 led->cdev.brightness = led->value;
193
194 /* Set the default led status */
195 regulator_led_set_value(led);
196
197 return 0;
198
199err_led:
200 kfree(led);
201err_vcc:
202 regulator_put(vcc);
203 return ret;
204}
205
206static int __devexit regulator_led_remove(struct platform_device *pdev)
207{
208 struct regulator_led *led = platform_get_drvdata(pdev);
209
210 led_classdev_unregister(&led->cdev);
211 cancel_work_sync(&led->work);
212 regulator_led_disable(led);
213 regulator_put(led->vcc);
214 kfree(led);
215 return 0;
216}
217
218static struct platform_driver regulator_led_driver = {
219 .driver = {
220 .name = "leds-regulator",
221 .owner = THIS_MODULE,
222 },
223 .probe = regulator_led_probe,
224 .remove = __devexit_p(regulator_led_remove),
225};
226
227static int __init regulator_led_init(void)
228{
229 return platform_driver_register(&regulator_led_driver);
230}
231module_init(regulator_led_init);
232
233static void __exit regulator_led_exit(void)
234{
235 platform_driver_unregister(&regulator_led_driver);
236}
237module_exit(regulator_led_exit);
238
239MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
240MODULE_DESCRIPTION("Regulator driven LED driver");
241MODULE_LICENSE("GPL");
242MODULE_ALIAS("platform:leds-regulator");
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
new file mode 100644
index 000000000000..97f04984c1ca
--- /dev/null
+++ b/drivers/leds/leds-ss4200.c
@@ -0,0 +1,556 @@
1/*
2 * SS4200-E Hardware API
3 * Copyright (c) 2009, Intel Corporation.
4 * Copyright IBM Corporation, 2009
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Author: Dave Hansen <dave@sr71.net>
20 */
21
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24#include <linux/dmi.h>
25#include <linux/init.h>
26#include <linux/ioport.h>
27#include <linux/kernel.h>
28#include <linux/leds.h>
29#include <linux/module.h>
30#include <linux/pci.h>
31#include <linux/types.h>
32#include <linux/uaccess.h>
33
34MODULE_AUTHOR("Rodney Girod <rgirod@confocus.com>, Dave Hansen <dave@sr71.net>");
35MODULE_DESCRIPTION("Intel NAS/Home Server ICH7 GPIO Driver");
36MODULE_LICENSE("GPL");
37
38/*
39 * ICH7 LPC/GPIO PCI Config register offsets
40 */
41#define PMBASE 0x040
42#define GPIO_BASE 0x048
43#define GPIO_CTRL 0x04c
44#define GPIO_EN 0x010
45
46/*
47 * The ICH7 GPIO register block is 64 bytes in size.
48 */
49#define ICH7_GPIO_SIZE 64
50
51/*
52 * Define register offsets within the ICH7 register block.
53 */
54#define GPIO_USE_SEL 0x000
55#define GP_IO_SEL 0x004
56#define GP_LVL 0x00c
57#define GPO_BLINK 0x018
58#define GPI_INV 0x030
59#define GPIO_USE_SEL2 0x034
60#define GP_IO_SEL2 0x038
61#define GP_LVL2 0x03c
62
63/*
64 * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives.
65 */
66static struct pci_device_id ich7_lpc_pci_id[] =
67{
68 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) },
69 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) },
70 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_30) },
71 { } /* NULL entry */
72};
73
74MODULE_DEVICE_TABLE(pci, ich7_lpc_pci_id);
75
76static int __init ss4200_led_dmi_callback(const struct dmi_system_id *id)
77{
78 pr_info("detected '%s'\n", id->ident);
79 return 1;
80}
81
82static unsigned int __initdata nodetect;
83module_param_named(nodetect, nodetect, bool, 0);
84MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection");
85
86/*
87 * struct nas_led_whitelist - List of known good models
88 *
89 * Contains the known good models this driver is compatible with.
90 * When adding a new model try to be as strict as possible. This
91 * makes it possible to keep the false positives (the model is
92 * detected as working, but in reality it is not) as low as
93 * possible.
94 */
95static struct dmi_system_id __initdata nas_led_whitelist[] = {
96 {
97 .callback = ss4200_led_dmi_callback,
98 .ident = "Intel SS4200-E",
99 .matches = {
100 DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
101 DMI_MATCH(DMI_PRODUCT_NAME, "SS4200-E"),
102 DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00")
103 }
104 },
105};
106
107/*
108 * Base I/O address assigned to the Power Management register block
109 */
110static u32 g_pm_io_base;
111
112/*
113 * Base I/O address assigned to the ICH7 GPIO register block
114 */
115static u32 nas_gpio_io_base;
116
117/*
118 * When we successfully register a region, we are returned a resource.
119 * We use these to identify which regions we need to release on our way
120 * back out.
121 */
122static struct resource *gp_gpio_resource;
123
124struct nasgpio_led {
125 char *name;
126 u32 gpio_bit;
127 struct led_classdev led_cdev;
128};
129
130/*
131 * gpio_bit(s) are the ICH7 GPIO bit assignments
132 */
133static struct nasgpio_led nasgpio_leds[] = {
134 { .name = "hdd1:blue:sata", .gpio_bit = 0 },
135 { .name = "hdd1:amber:sata", .gpio_bit = 1 },
136 { .name = "hdd2:blue:sata", .gpio_bit = 2 },
137 { .name = "hdd2:amber:sata", .gpio_bit = 3 },
138 { .name = "hdd3:blue:sata", .gpio_bit = 4 },
139 { .name = "hdd3:amber:sata", .gpio_bit = 5 },
140 { .name = "hdd4:blue:sata", .gpio_bit = 6 },
141 { .name = "hdd4:amber:sata", .gpio_bit = 7 },
142 { .name = "power:blue:power", .gpio_bit = 27},
143 { .name = "power:amber:power", .gpio_bit = 28},
144};
145
146#define NAS_RECOVERY 0x00000400 /* GPIO10 */
147
148static struct nasgpio_led *
149led_classdev_to_nasgpio_led(struct led_classdev *led_cdev)
150{
151 return container_of(led_cdev, struct nasgpio_led, led_cdev);
152}
153
154static struct nasgpio_led *get_led_named(char *name)
155{
156 int i;
157 for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) {
158 if (strcmp(nasgpio_leds[i].name, name))
159 continue;
160 return &nasgpio_leds[i];
161 }
162 return NULL;
163}
164
165/*
166 * This protects access to the gpio ports.
167 */
168static DEFINE_SPINLOCK(nasgpio_gpio_lock);
169
170/*
171 * There are two gpio ports, one for blinking and the other
172 * for power. @port tells us if we're doing blinking or
173 * power control.
174 *
175 * Caller must hold nasgpio_gpio_lock
176 */
177static void __nasgpio_led_set_attr(struct led_classdev *led_cdev,
178 u32 port, u32 value)
179{
180 struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev);
181 u32 gpio_out;
182
183 gpio_out = inl(nas_gpio_io_base + port);
184 if (value)
185 gpio_out |= (1<<led->gpio_bit);
186 else
187 gpio_out &= ~(1<<led->gpio_bit);
188
189 outl(gpio_out, nas_gpio_io_base + port);
190}
191
192static void nasgpio_led_set_attr(struct led_classdev *led_cdev,
193 u32 port, u32 value)
194{
195 spin_lock(&nasgpio_gpio_lock);
196 __nasgpio_led_set_attr(led_cdev, port, value);
197 spin_unlock(&nasgpio_gpio_lock);
198}
199
200u32 nasgpio_led_get_attr(struct led_classdev *led_cdev, u32 port)
201{
202 struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev);
203 u32 gpio_in;
204
205 spin_lock(&nasgpio_gpio_lock);
206 gpio_in = inl(nas_gpio_io_base + port);
207 spin_unlock(&nasgpio_gpio_lock);
208 if (gpio_in & (1<<led->gpio_bit))
209 return 1;
210 return 0;
211}
212
213/*
214 * There is actual brightness control in the hardware,
215 * but it is via smbus commands and not implemented
216 * in this driver.
217 */
218static void nasgpio_led_set_brightness(struct led_classdev *led_cdev,
219 enum led_brightness brightness)
220{
221 u32 setting = 0;
222 if (brightness >= LED_HALF)
223 setting = 1;
224 /*
225 * Hold the lock across both operations. This ensures
226 * consistency so that both the "turn off blinking"
227 * and "turn light off" operations complete as a set.
228 */
229 spin_lock(&nasgpio_gpio_lock);
230 /*
231 * LED class documentation asks that past blink state
232 * be disabled when brightness is turned to zero.
233 */
234 if (brightness == 0)
235 __nasgpio_led_set_attr(led_cdev, GPO_BLINK, 0);
236 __nasgpio_led_set_attr(led_cdev, GP_LVL, setting);
237 spin_unlock(&nasgpio_gpio_lock);
238}
239
240static int nasgpio_led_set_blink(struct led_classdev *led_cdev,
241 unsigned long *delay_on,
242 unsigned long *delay_off)
243{
244 u32 setting = 1;
245 if (!(*delay_on == 0 && *delay_off == 0) &&
246 !(*delay_on == 500 && *delay_off == 500))
247 return -EINVAL;
248 /*
249 * These are very approximate.
250 */
251 *delay_on = 500;
252 *delay_off = 500;
253
254 nasgpio_led_set_attr(led_cdev, GPO_BLINK, setting);
255
256 return 0;
257}
258
259
260/*
261 * Initialize the ICH7 GPIO registers for NAS usage. The BIOS should have
262 * already taken care of this, but we will do so in a non destructive manner
263 * so that we have what we need whether the BIOS did it or not.
264 */
265static int __devinit ich7_gpio_init(struct device *dev)
266{
267 int i;
268 u32 config_data = 0;
269 u32 all_nas_led = 0;
270
271 for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++)
272 all_nas_led |= (1<<nasgpio_leds[i].gpio_bit);
273
274 spin_lock(&nasgpio_gpio_lock);
275 /*
276 * We need to enable all of the GPIO lines used by the NAS box,
277 * so we will read the current Use Selection and add our usage
278 * to it. This should be benign with regard to the original
279 * BIOS configuration.
280 */
281 config_data = inl(nas_gpio_io_base + GPIO_USE_SEL);
282 dev_dbg(dev, ": Data read from GPIO_USE_SEL = 0x%08x\n", config_data);
283 config_data |= all_nas_led + NAS_RECOVERY;
284 outl(config_data, nas_gpio_io_base + GPIO_USE_SEL);
285 config_data = inl(nas_gpio_io_base + GPIO_USE_SEL);
286 dev_dbg(dev, ": GPIO_USE_SEL = 0x%08x\n\n", config_data);
287
288 /*
289 * The LED GPIO outputs need to be configured for output, so we
290 * will ensure that all LED lines are cleared for output and the
291 * RECOVERY line ready for input. This too should be benign with
292 * regard to BIOS configuration.
293 */
294 config_data = inl(nas_gpio_io_base + GP_IO_SEL);
295 dev_dbg(dev, ": Data read from GP_IO_SEL = 0x%08x\n",
296 config_data);
297 config_data &= ~all_nas_led;
298 config_data |= NAS_RECOVERY;
299 outl(config_data, nas_gpio_io_base + GP_IO_SEL);
300 config_data = inl(nas_gpio_io_base + GP_IO_SEL);
301 dev_dbg(dev, ": GP_IO_SEL = 0x%08x\n", config_data);
302
303 /*
304 * In our final system, the BIOS will initialize the state of all
305 * of the LEDs. For now, we turn them all off (or Low).
306 */
307 config_data = inl(nas_gpio_io_base + GP_LVL);
308 dev_dbg(dev, ": Data read from GP_LVL = 0x%08x\n", config_data);
309 /*
310 * In our final system, the BIOS will initialize the blink state of all
311 * of the LEDs. For now, we turn blink off for all of them.
312 */
313 config_data = inl(nas_gpio_io_base + GPO_BLINK);
314 dev_dbg(dev, ": Data read from GPO_BLINK = 0x%08x\n", config_data);
315
316 /*
317 * At this moment, I am unsure if anything needs to happen with GPI_INV
318 */
319 config_data = inl(nas_gpio_io_base + GPI_INV);
320 dev_dbg(dev, ": Data read from GPI_INV = 0x%08x\n", config_data);
321
322 spin_unlock(&nasgpio_gpio_lock);
323 return 0;
324}
325
326static void ich7_lpc_cleanup(struct device *dev)
327{
328 /*
329 * If we were given exclusive use of the GPIO
330 * I/O Address range, we must return it.
331 */
332 if (gp_gpio_resource) {
333 dev_dbg(dev, ": Releasing GPIO I/O addresses\n");
334 release_region(nas_gpio_io_base, ICH7_GPIO_SIZE);
335 gp_gpio_resource = NULL;
336 }
337}
338
339/*
340 * The OS has determined that the LPC of the Intel ICH7 Southbridge is present
341 * so we can retrive the required operational information and prepare the GPIO.
342 */
343static struct pci_dev *nas_gpio_pci_dev;
344static int __devinit ich7_lpc_probe(struct pci_dev *dev,
345 const struct pci_device_id *id)
346{
347 int status;
348 u32 gc = 0;
349
350 status = pci_enable_device(dev);
351 if (status) {
352 dev_err(&dev->dev, "pci_enable_device failed\n");
353 return -EIO;
354 }
355
356 nas_gpio_pci_dev = dev;
357 status = pci_read_config_dword(dev, PMBASE, &g_pm_io_base);
358 if (status)
359 goto out;
360 g_pm_io_base &= 0x00000ff80;
361
362 status = pci_read_config_dword(dev, GPIO_CTRL, &gc);
363 if (!(GPIO_EN & gc)) {
364 status = -EEXIST;
365 dev_info(&dev->dev,
366 "ERROR: The LPC GPIO Block has not been enabled.\n");
367 goto out;
368 }
369
370 status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base);
371 if (0 > status) {
372 dev_info(&dev->dev, "Unable to read GPIOBASE.\n");
373 goto out;
374 }
375 dev_dbg(&dev->dev, ": GPIOBASE = 0x%08x\n", nas_gpio_io_base);
376 nas_gpio_io_base &= 0x00000ffc0;
377
378 /*
379 * Insure that we have exclusive access to the GPIO I/O address range.
380 */
381 gp_gpio_resource = request_region(nas_gpio_io_base, ICH7_GPIO_SIZE,
382 KBUILD_MODNAME);
383 if (NULL == gp_gpio_resource) {
384 dev_info(&dev->dev,
385 "ERROR Unable to register GPIO I/O addresses.\n");
386 status = -1;
387 goto out;
388 }
389
390 /*
391 * Initialize the GPIO for NAS/Home Server Use
392 */
393 ich7_gpio_init(&dev->dev);
394
395out:
396 if (status) {
397 ich7_lpc_cleanup(&dev->dev);
398 pci_disable_device(dev);
399 }
400 return status;
401}
402
403static void ich7_lpc_remove(struct pci_dev *dev)
404{
405 ich7_lpc_cleanup(&dev->dev);
406 pci_disable_device(dev);
407}
408
409/*
410 * pci_driver structure passed to the PCI modules
411 */
412static struct pci_driver nas_gpio_pci_driver = {
413 .name = KBUILD_MODNAME,
414 .id_table = ich7_lpc_pci_id,
415 .probe = ich7_lpc_probe,
416 .remove = ich7_lpc_remove,
417};
418
419static struct led_classdev *get_classdev_for_led_nr(int nr)
420{
421 struct nasgpio_led *nas_led = &nasgpio_leds[nr];
422 struct led_classdev *led = &nas_led->led_cdev;
423 return led;
424}
425
426
427static void set_power_light_amber_noblink(void)
428{
429 struct nasgpio_led *amber = get_led_named("power:amber:power");
430 struct nasgpio_led *blue = get_led_named("power:blue:power");
431
432 if (!amber || !blue)
433 return;
434 /*
435 * LED_OFF implies disabling future blinking
436 */
437 pr_debug("setting blue off and amber on\n");
438
439 nasgpio_led_set_brightness(&blue->led_cdev, LED_OFF);
440 nasgpio_led_set_brightness(&amber->led_cdev, LED_FULL);
441}
442
443static ssize_t nas_led_blink_show(struct device *dev,
444 struct device_attribute *attr, char *buf)
445{
446 struct led_classdev *led = dev_get_drvdata(dev);
447 int blinking = 0;
448 if (nasgpio_led_get_attr(led, GPO_BLINK))
449 blinking = 1;
450 return sprintf(buf, "%u\n", blinking);
451}
452
453static ssize_t nas_led_blink_store(struct device *dev,
454 struct device_attribute *attr,
455 const char *buf, size_t size)
456{
457 int ret;
458 struct led_classdev *led = dev_get_drvdata(dev);
459 unsigned long blink_state;
460
461 ret = strict_strtoul(buf, 10, &blink_state);
462 if (ret)
463 return ret;
464
465 nasgpio_led_set_attr(led, GPO_BLINK, blink_state);
466
467 return size;
468}
469
470static DEVICE_ATTR(blink, 0644, nas_led_blink_show, nas_led_blink_store);
471
472static int register_nasgpio_led(int led_nr)
473{
474 int ret;
475 struct nasgpio_led *nas_led = &nasgpio_leds[led_nr];
476 struct led_classdev *led = get_classdev_for_led_nr(led_nr);
477
478 led->name = nas_led->name;
479 led->brightness = LED_OFF;
480 if (nasgpio_led_get_attr(led, GP_LVL))
481 led->brightness = LED_FULL;
482 led->brightness_set = nasgpio_led_set_brightness;
483 led->blink_set = nasgpio_led_set_blink;
484 ret = led_classdev_register(&nas_gpio_pci_dev->dev, led);
485 if (ret)
486 return ret;
487 ret = device_create_file(led->dev, &dev_attr_blink);
488 if (ret)
489 led_classdev_unregister(led);
490 return ret;
491}
492
493static void unregister_nasgpio_led(int led_nr)
494{
495 struct led_classdev *led = get_classdev_for_led_nr(led_nr);
496 led_classdev_unregister(led);
497 device_remove_file(led->dev, &dev_attr_blink);
498}
499/*
500 * module load/initialization
501 */
502static int __init nas_gpio_init(void)
503{
504 int i;
505 int ret = 0;
506 int nr_devices = 0;
507
508 nr_devices = dmi_check_system(nas_led_whitelist);
509 if (nodetect) {
510 pr_info("skipping hardware autodetection\n");
511 pr_info("Please send 'dmidecode' output to dave@sr71.net\n");
512 nr_devices++;
513 }
514
515 if (nr_devices <= 0) {
516 pr_info("no LED devices found\n");
517 return -ENODEV;
518 }
519
520 pr_info("registering PCI driver\n");
521 ret = pci_register_driver(&nas_gpio_pci_driver);
522 if (ret)
523 return ret;
524 for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) {
525 ret = register_nasgpio_led(i);
526 if (ret)
527 goto out_err;
528 }
529 /*
530 * When the system powers on, the BIOS leaves the power
531 * light blue and blinking. This will turn it solid
532 * amber once the driver is loaded.
533 */
534 set_power_light_amber_noblink();
535 return 0;
536out_err:
537 for (; i >= 0; i--)
538 unregister_nasgpio_led(i);
539 pci_unregister_driver(&nas_gpio_pci_driver);
540 return ret;
541}
542
543/*
544 * module unload
545 */
546static void __exit nas_gpio_exit(void)
547{
548 int i;
549 pr_info("Unregistering driver\n");
550 for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++)
551 unregister_nasgpio_led(i);
552 pci_unregister_driver(&nas_gpio_pci_driver);
553}
554
555module_init(nas_gpio_init);
556module_exit(nas_gpio_exit);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1a7a9fc50ea1..e3551d20464f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -203,6 +203,7 @@ config CS5535_MFGPT
203 203
204config CS5535_MFGPT_DEFAULT_IRQ 204config CS5535_MFGPT_DEFAULT_IRQ
205 int 205 int
206 depends on CS5535_MFGPT
206 default 7 207 default 7
207 help 208 help
208 MFGPTs on the CS5535 require an interrupt. The selected IRQ 209 MFGPTs on the CS5535 require an interrupt. The selected IRQ
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index cdb845b68ab5..06b64085a355 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -516,7 +516,8 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
516 * The number of functions on the card is encoded inside 516 * The number of functions on the card is encoded inside
517 * the ocr. 517 * the ocr.
518 */ 518 */
519 card->sdio_funcs = funcs = (ocr & 0x70000000) >> 28; 519 funcs = (ocr & 0x70000000) >> 28;
520 card->sdio_funcs = 0;
520 521
521 /* 522 /*
522 * If needed, disconnect card detection pull-up resistor. 523 * If needed, disconnect card detection pull-up resistor.
@@ -528,7 +529,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
528 /* 529 /*
529 * Initialize (but don't add) all present functions. 530 * Initialize (but don't add) all present functions.
530 */ 531 */
531 for (i = 0;i < funcs;i++) { 532 for (i = 0; i < funcs; i++, card->sdio_funcs++) {
532 err = sdio_init_func(host->card, i + 1); 533 err = sdio_init_func(host->card, i + 1);
533 if (err) 534 if (err)
534 goto remove; 535 goto remove;
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index d37464e296a5..9e060c87e64d 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -248,12 +248,15 @@ int sdio_add_func(struct sdio_func *func)
248/* 248/*
249 * Unregister a SDIO function with the driver model, and 249 * Unregister a SDIO function with the driver model, and
250 * (eventually) free it. 250 * (eventually) free it.
251 * This function can be called through error paths where sdio_add_func() was
252 * never executed (because a failure occurred at an earlier point).
251 */ 253 */
252void sdio_remove_func(struct sdio_func *func) 254void sdio_remove_func(struct sdio_func *func)
253{ 255{
254 if (sdio_func_present(func)) 256 if (!sdio_func_present(func))
255 device_del(&func->dev); 257 return;
256 258
259 device_del(&func->dev);
257 put_device(&func->dev); 260 put_device(&func->dev);
258} 261}
259 262
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 9d405b181781..ce1d28884e29 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -44,6 +44,19 @@ config MMC_SDHCI_IO_ACCESSORS
44 This is silent Kconfig symbol that is selected by the drivers that 44 This is silent Kconfig symbol that is selected by the drivers that
45 need to overwrite SDHCI IO memory accessors. 45 need to overwrite SDHCI IO memory accessors.
46 46
47config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
48 bool
49 select MMC_SDHCI_IO_ACCESSORS
50 help
51 This option is selected by drivers running on big endian hosts
52 and performing I/O to a SDHCI controller through a bus that
53 implements a hardware byte swapper using a 32-bit datum.
54 This endian mapping mode is called "data invariance" and
55 has the effect of scrambling the addresses and formats of data
56 accessed in sizes other than the datum size.
57
58 This is the case for the Freescale eSDHC and Nintendo Wii SDHCI.
59
47config MMC_SDHCI_PCI 60config MMC_SDHCI_PCI
48 tristate "SDHCI support on PCI bus" 61 tristate "SDHCI support on PCI bus"
49 depends on MMC_SDHCI && PCI 62 depends on MMC_SDHCI && PCI
@@ -75,11 +88,29 @@ config MMC_RICOH_MMC
75config MMC_SDHCI_OF 88config MMC_SDHCI_OF
76 tristate "SDHCI support on OpenFirmware platforms" 89 tristate "SDHCI support on OpenFirmware platforms"
77 depends on MMC_SDHCI && PPC_OF 90 depends on MMC_SDHCI && PPC_OF
78 select MMC_SDHCI_IO_ACCESSORS
79 help 91 help
80 This selects the OF support for Secure Digital Host Controller 92 This selects the OF support for Secure Digital Host Controller
81 Interfaces. So far, only the Freescale eSDHC controller is known 93 Interfaces.
82 to exist on OF platforms. 94
95 If unsure, say N.
96
97config MMC_SDHCI_OF_ESDHC
98 bool "SDHCI OF support for the Freescale eSDHC controller"
99 depends on MMC_SDHCI_OF
100 select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
101 help
102 This selects the Freescale eSDHC controller support.
103
104 If unsure, say N.
105
106config MMC_SDHCI_OF_HLWD
107 bool "SDHCI OF support for the Nintendo Wii SDHCI controllers"
108 depends on MMC_SDHCI_OF
109 select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
110 help
111 This selects the Secure Digital Host Controller Interface (SDHCI)
112 found in the "Hollywood" chipset of the Nintendo Wii video game
113 console.
83 114
84 If unsure, say N. 115 If unsure, say N.
85 116
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index ded4d8cdd9d7..3d253dd4240f 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -13,7 +13,6 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o
13obj-$(CONFIG_MMC_SDHCI) += sdhci.o 13obj-$(CONFIG_MMC_SDHCI) += sdhci.o
14obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o 14obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
15obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o 15obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
16obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o
17obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o 16obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
18obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o 17obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o
19obj-$(CONFIG_MMC_WBSD) += wbsd.o 18obj-$(CONFIG_MMC_WBSD) += wbsd.o
@@ -37,6 +36,11 @@ obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
37obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o 36obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o
38obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o 37obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o
39 38
39obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o
40sdhci-of-y := sdhci-of-core.o
41sdhci-of-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o
42sdhci-of-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o
43
40ifeq ($(CONFIG_CB710_DEBUG),y) 44ifeq ($(CONFIG_CB710_DEBUG),y)
41 CFLAGS-cb710-mmc += -DDEBUG 45 CFLAGS-cb710-mmc += -DDEBUG
42endif 46endif
diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of-core.c
index 01ab916c2802..55e33135edb4 100644
--- a/drivers/mmc/host/sdhci-of.c
+++ b/drivers/mmc/host/sdhci-of-core.c
@@ -22,62 +22,37 @@
22#include <linux/of_platform.h> 22#include <linux/of_platform.h>
23#include <linux/mmc/host.h> 23#include <linux/mmc/host.h>
24#include <asm/machdep.h> 24#include <asm/machdep.h>
25#include "sdhci-of.h"
25#include "sdhci.h" 26#include "sdhci.h"
26 27
27struct sdhci_of_data { 28#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
28 unsigned int quirks;
29 struct sdhci_ops ops;
30};
31
32struct sdhci_of_host {
33 unsigned int clock;
34 u16 xfer_mode_shadow;
35};
36 29
37/* 30/*
38 * Ops and quirks for the Freescale eSDHC controller. 31 * These accessors are designed for big endian hosts doing I/O to
32 * little endian controllers incorporating a 32-bit hardware byte swapper.
39 */ 33 */
40 34
41#define ESDHC_DMA_SYSCTL 0x40c 35u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
42#define ESDHC_DMA_SNOOP 0x00000040
43
44#define ESDHC_SYSTEM_CONTROL 0x2c
45#define ESDHC_CLOCK_MASK 0x0000fff0
46#define ESDHC_PREDIV_SHIFT 8
47#define ESDHC_DIVIDER_SHIFT 4
48#define ESDHC_CLOCK_PEREN 0x00000004
49#define ESDHC_CLOCK_HCKEN 0x00000002
50#define ESDHC_CLOCK_IPGEN 0x00000001
51
52#define ESDHC_HOST_CONTROL_RES 0x05
53
54static u32 esdhc_readl(struct sdhci_host *host, int reg)
55{ 36{
56 return in_be32(host->ioaddr + reg); 37 return in_be32(host->ioaddr + reg);
57} 38}
58 39
59static u16 esdhc_readw(struct sdhci_host *host, int reg) 40u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
60{ 41{
61 u16 ret; 42 return in_be16(host->ioaddr + (reg ^ 0x2));
62
63 if (unlikely(reg == SDHCI_HOST_VERSION))
64 ret = in_be16(host->ioaddr + reg);
65 else
66 ret = in_be16(host->ioaddr + (reg ^ 0x2));
67 return ret;
68} 43}
69 44
70static u8 esdhc_readb(struct sdhci_host *host, int reg) 45u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
71{ 46{
72 return in_8(host->ioaddr + (reg ^ 0x3)); 47 return in_8(host->ioaddr + (reg ^ 0x3));
73} 48}
74 49
75static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) 50void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg)
76{ 51{
77 out_be32(host->ioaddr + reg, val); 52 out_be32(host->ioaddr + reg, val);
78} 53}
79 54
80static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) 55void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
81{ 56{
82 struct sdhci_of_host *of_host = sdhci_priv(host); 57 struct sdhci_of_host *of_host = sdhci_priv(host);
83 int base = reg & ~0x3; 58 int base = reg & ~0x3;
@@ -92,106 +67,21 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
92 of_host->xfer_mode_shadow = val; 67 of_host->xfer_mode_shadow = val;
93 return; 68 return;
94 case SDHCI_COMMAND: 69 case SDHCI_COMMAND:
95 esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow, 70 sdhci_be32bs_writel(host, val << 16 | of_host->xfer_mode_shadow,
96 SDHCI_TRANSFER_MODE); 71 SDHCI_TRANSFER_MODE);
97 return; 72 return;
98 case SDHCI_BLOCK_SIZE:
99 /*
100 * Two last DMA bits are reserved, and first one is used for
101 * non-standard blksz of 4096 bytes that we don't support
102 * yet. So clear the DMA boundary bits.
103 */
104 val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
105 /* fall through */
106 } 73 }
107 clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); 74 clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
108} 75}
109 76
110static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) 77void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
111{ 78{
112 int base = reg & ~0x3; 79 int base = reg & ~0x3;
113 int shift = (reg & 0x3) * 8; 80 int shift = (reg & 0x3) * 8;
114 81
115 /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
116 if (reg == SDHCI_HOST_CONTROL)
117 val &= ~ESDHC_HOST_CONTROL_RES;
118
119 clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); 82 clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
120} 83}
121 84#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */
122static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
123{
124 int pre_div = 2;
125 int div = 1;
126
127 clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
128 ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
129
130 if (clock == 0)
131 goto out;
132
133 while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
134 pre_div *= 2;
135
136 while (host->max_clk / pre_div / div > clock && div < 16)
137 div++;
138
139 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
140 clock, host->max_clk / pre_div / div);
141
142 pre_div >>= 1;
143 div--;
144
145 setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
146 ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
147 div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
148 mdelay(100);
149out:
150 host->clock = clock;
151}
152
153static int esdhc_enable_dma(struct sdhci_host *host)
154{
155 setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
156 return 0;
157}
158
159static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
160{
161 struct sdhci_of_host *of_host = sdhci_priv(host);
162
163 return of_host->clock;
164}
165
166static unsigned int esdhc_get_min_clock(struct sdhci_host *host)
167{
168 struct sdhci_of_host *of_host = sdhci_priv(host);
169
170 return of_host->clock / 256 / 16;
171}
172
173static struct sdhci_of_data sdhci_esdhc = {
174 .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
175 SDHCI_QUIRK_BROKEN_CARD_DETECTION |
176 SDHCI_QUIRK_NO_BUSY_IRQ |
177 SDHCI_QUIRK_NONSTANDARD_CLOCK |
178 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
179 SDHCI_QUIRK_PIO_NEEDS_DELAY |
180 SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
181 SDHCI_QUIRK_NO_CARD_NO_RESET,
182 .ops = {
183 .readl = esdhc_readl,
184 .readw = esdhc_readw,
185 .readb = esdhc_readb,
186 .writel = esdhc_writel,
187 .writew = esdhc_writew,
188 .writeb = esdhc_writeb,
189 .set_clock = esdhc_set_clock,
190 .enable_dma = esdhc_enable_dma,
191 .get_max_clock = esdhc_get_max_clock,
192 .get_min_clock = esdhc_get_min_clock,
193 },
194};
195 85
196#ifdef CONFIG_PM 86#ifdef CONFIG_PM
197 87
@@ -301,9 +191,14 @@ static int __devexit sdhci_of_remove(struct of_device *ofdev)
301} 191}
302 192
303static const struct of_device_id sdhci_of_match[] = { 193static const struct of_device_id sdhci_of_match[] = {
194#ifdef CONFIG_MMC_SDHCI_OF_ESDHC
304 { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, 195 { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
305 { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, 196 { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
306 { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, 197 { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, },
198#endif
199#ifdef CONFIG_MMC_SDHCI_OF_HLWD
200 { .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd, },
201#endif
307 { .compatible = "generic-sdhci", }, 202 { .compatible = "generic-sdhci", },
308 {}, 203 {},
309}; 204};
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
new file mode 100644
index 000000000000..d5b11a17e648
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -0,0 +1,143 @@
1/*
2 * Freescale eSDHC controller driver.
3 *
4 * Copyright (c) 2007 Freescale Semiconductor, Inc.
5 * Copyright (c) 2009 MontaVista Software, Inc.
6 *
7 * Authors: Xiaobo Xie <X.Xie@freescale.com>
8 * Anton Vorontsov <avorontsov@ru.mvista.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 */
15
16#include <linux/io.h>
17#include <linux/delay.h>
18#include <linux/mmc/host.h>
19#include "sdhci-of.h"
20#include "sdhci.h"
21
22/*
23 * Ops and quirks for the Freescale eSDHC controller.
24 */
25
26#define ESDHC_DMA_SYSCTL 0x40c
27#define ESDHC_DMA_SNOOP 0x00000040
28
29#define ESDHC_SYSTEM_CONTROL 0x2c
30#define ESDHC_CLOCK_MASK 0x0000fff0
31#define ESDHC_PREDIV_SHIFT 8
32#define ESDHC_DIVIDER_SHIFT 4
33#define ESDHC_CLOCK_PEREN 0x00000004
34#define ESDHC_CLOCK_HCKEN 0x00000002
35#define ESDHC_CLOCK_IPGEN 0x00000001
36
37#define ESDHC_HOST_CONTROL_RES 0x05
38
39static u16 esdhc_readw(struct sdhci_host *host, int reg)
40{
41 u16 ret;
42
43 if (unlikely(reg == SDHCI_HOST_VERSION))
44 ret = in_be16(host->ioaddr + reg);
45 else
46 ret = sdhci_be32bs_readw(host, reg);
47 return ret;
48}
49
50static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
51{
52 if (reg == SDHCI_BLOCK_SIZE) {
53 /*
54 * Two last DMA bits are reserved, and first one is used for
55 * non-standard blksz of 4096 bytes that we don't support
56 * yet. So clear the DMA boundary bits.
57 */
58 val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
59 }
60 sdhci_be32bs_writew(host, val, reg);
61}
62
63static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
64{
65 /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
66 if (reg == SDHCI_HOST_CONTROL)
67 val &= ~ESDHC_HOST_CONTROL_RES;
68 sdhci_be32bs_writeb(host, val, reg);
69}
70
71static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
72{
73 int pre_div = 2;
74 int div = 1;
75
76 clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
77 ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
78
79 if (clock == 0)
80 goto out;
81
82 while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
83 pre_div *= 2;
84
85 while (host->max_clk / pre_div / div > clock && div < 16)
86 div++;
87
88 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
89 clock, host->max_clk / pre_div / div);
90
91 pre_div >>= 1;
92 div--;
93
94 setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
95 ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
96 div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
97 mdelay(100);
98out:
99 host->clock = clock;
100}
101
102static int esdhc_enable_dma(struct sdhci_host *host)
103{
104 setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
105 return 0;
106}
107
108static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
109{
110 struct sdhci_of_host *of_host = sdhci_priv(host);
111
112 return of_host->clock;
113}
114
115static unsigned int esdhc_get_min_clock(struct sdhci_host *host)
116{
117 struct sdhci_of_host *of_host = sdhci_priv(host);
118
119 return of_host->clock / 256 / 16;
120}
121
122struct sdhci_of_data sdhci_esdhc = {
123 .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
124 SDHCI_QUIRK_BROKEN_CARD_DETECTION |
125 SDHCI_QUIRK_NO_BUSY_IRQ |
126 SDHCI_QUIRK_NONSTANDARD_CLOCK |
127 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
128 SDHCI_QUIRK_PIO_NEEDS_DELAY |
129 SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
130 SDHCI_QUIRK_NO_CARD_NO_RESET,
131 .ops = {
132 .readl = sdhci_be32bs_readl,
133 .readw = esdhc_readw,
134 .readb = sdhci_be32bs_readb,
135 .writel = sdhci_be32bs_writel,
136 .writew = esdhc_writew,
137 .writeb = esdhc_writeb,
138 .set_clock = esdhc_set_clock,
139 .enable_dma = esdhc_enable_dma,
140 .get_max_clock = esdhc_get_max_clock,
141 .get_min_clock = esdhc_get_min_clock,
142 },
143};
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
new file mode 100644
index 000000000000..35117f3ed757
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -0,0 +1,65 @@
1/*
2 * drivers/mmc/host/sdhci-of-hlwd.c
3 *
4 * Nintendo Wii Secure Digital Host Controller Interface.
5 * Copyright (C) 2009 The GameCube Linux Team
6 * Copyright (C) 2009 Albert Herranz
7 *
8 * Based on sdhci-of-esdhc.c
9 *
10 * Copyright (c) 2007 Freescale Semiconductor, Inc.
11 * Copyright (c) 2009 MontaVista Software, Inc.
12 *
13 * Authors: Xiaobo Xie <X.Xie@freescale.com>
14 * Anton Vorontsov <avorontsov@ru.mvista.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or (at
19 * your option) any later version.
20 */
21
22#include <linux/delay.h>
23#include <linux/mmc/host.h>
24#include "sdhci-of.h"
25#include "sdhci.h"
26
27/*
28 * Ops and quirks for the Nintendo Wii SDHCI controllers.
29 */
30
31/*
32 * We need a small delay after each write, or things go horribly wrong.
33 */
34#define SDHCI_HLWD_WRITE_DELAY 5 /* usecs */
35
36static void sdhci_hlwd_writel(struct sdhci_host *host, u32 val, int reg)
37{
38 sdhci_be32bs_writel(host, val, reg);
39 udelay(SDHCI_HLWD_WRITE_DELAY);
40}
41
42static void sdhci_hlwd_writew(struct sdhci_host *host, u16 val, int reg)
43{
44 sdhci_be32bs_writew(host, val, reg);
45 udelay(SDHCI_HLWD_WRITE_DELAY);
46}
47
48static void sdhci_hlwd_writeb(struct sdhci_host *host, u8 val, int reg)
49{
50 sdhci_be32bs_writeb(host, val, reg);
51 udelay(SDHCI_HLWD_WRITE_DELAY);
52}
53
54struct sdhci_of_data sdhci_hlwd = {
55 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
56 SDHCI_QUIRK_32BIT_DMA_SIZE,
57 .ops = {
58 .readl = sdhci_be32bs_readl,
59 .readw = sdhci_be32bs_readw,
60 .readb = sdhci_be32bs_readb,
61 .writel = sdhci_hlwd_writel,
62 .writew = sdhci_hlwd_writew,
63 .writeb = sdhci_hlwd_writeb,
64 },
65};
diff --git a/drivers/mmc/host/sdhci-of.h b/drivers/mmc/host/sdhci-of.h
new file mode 100644
index 000000000000..ad09ad9915d8
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of.h
@@ -0,0 +1,42 @@
1/*
2 * OpenFirmware bindings for Secure Digital Host Controller Interface.
3 *
4 * Copyright (c) 2007 Freescale Semiconductor, Inc.
5 * Copyright (c) 2009 MontaVista Software, Inc.
6 *
7 * Authors: Xiaobo Xie <X.Xie@freescale.com>
8 * Anton Vorontsov <avorontsov@ru.mvista.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 */
15
16#ifndef __SDHCI_OF_H
17#define __SDHCI_OF_H
18
19#include <linux/types.h>
20#include "sdhci.h"
21
22struct sdhci_of_data {
23 unsigned int quirks;
24 struct sdhci_ops ops;
25};
26
27struct sdhci_of_host {
28 unsigned int clock;
29 u16 xfer_mode_shadow;
30};
31
32extern u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg);
33extern u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg);
34extern u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg);
35extern void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg);
36extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg);
37extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg);
38
39extern struct sdhci_of_data sdhci_esdhc;
40extern struct sdhci_of_data sdhci_hlwd;
41
42#endif /* __SDHCI_OF_H */
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index ce5f1d73dc04..842f46f94284 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -8,6 +8,8 @@
8 * the Free Software Foundation; either version 2 of the License, or (at 8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version. 9 * your option) any later version.
10 */ 10 */
11#ifndef __SDHCI_H
12#define __SDHCI_H
11 13
12#include <linux/scatterlist.h> 14#include <linux/scatterlist.h>
13#include <linux/compiler.h> 15#include <linux/compiler.h>
@@ -408,3 +410,5 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead);
408extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); 410extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
409extern int sdhci_resume_host(struct sdhci_host *host); 411extern int sdhci_resume_host(struct sdhci_host *host);
410#endif 412#endif
413
414#endif /* __SDHCI_H */
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 74fa075c838a..b13f6417b5b2 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -20,14 +20,23 @@
20 20
21#include <asm/io.h> 21#include <asm/io.h>
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23#include <asm/cacheflush.h>
24 23
25#include <asm/mach/flash.h> 24#include <asm/mach/flash.h>
26 25
26#define CACHELINESIZE 32
27
27static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from, 28static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from,
28 ssize_t len) 29 ssize_t len)
29{ 30{
30 flush_ioremap_region(map->phys, map->cached, from, len); 31 unsigned long start = (unsigned long)map->cached + from;
32 unsigned long end = start + len;
33
34 start &= ~(CACHELINESIZE - 1);
35 while (start < end) {
36 /* invalidate D cache line */
37 asm volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
38 start += CACHELINESIZE;
39 }
31} 40}
32 41
33struct pxa2xx_flash_info { 42struct pxa2xx_flash_info {
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 675b7df632fc..27ca859e7453 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -63,7 +63,7 @@
63#ifndef __iwl_core_h__ 63#ifndef __iwl_core_h__
64#define __iwl_core_h__ 64#define __iwl_core_h__
65 65
66#include <linux/utsrelease.h> 66#include <generated/utsrelease.h>
67 67
68/************************ 68/************************
69 * forward declarations * 69 * forward declarations *
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 3aabf1e37988..76e640bccde8 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -291,7 +291,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
291 skt->nr = ops->first + i; 291 skt->nr = ops->first + i;
292 skt->ops = ops; 292 skt->ops = ops;
293 skt->socket.owner = ops->owner; 293 skt->socket.owner = ops->owner;
294 skt->socket.dev.parent = dev; 294 skt->socket.dev.parent = &dev->dev;
295 skt->socket.pci_irq = NO_IRQ; 295 skt->socket.pci_irq = NO_IRQ;
296 296
297 ret = pxa2xx_drv_pcmcia_add_one(skt); 297 ret = pxa2xx_drv_pcmcia_add_one(skt);
@@ -304,8 +304,8 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
304 soc_pcmcia_remove_one(&sinfo->skt[i]); 304 soc_pcmcia_remove_one(&sinfo->skt[i]);
305 kfree(sinfo); 305 kfree(sinfo);
306 } else { 306 } else {
307 pxa2xx_configure_sockets(dev); 307 pxa2xx_configure_sockets(&dev->dev);
308 dev_set_drvdata(dev, sinfo); 308 dev_set_drvdata(&dev->dev, sinfo);
309 } 309 }
310 310
311 return ret; 311 return ret;
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
index 11003bba10d3..1a387e79f719 100644
--- a/drivers/platform/x86/compal-laptop.c
+++ b/drivers/platform/x86/compal-laptop.c
@@ -51,7 +51,6 @@
51#include <linux/dmi.h> 51#include <linux/dmi.h>
52#include <linux/backlight.h> 52#include <linux/backlight.h>
53#include <linux/platform_device.h> 53#include <linux/platform_device.h>
54#include <linux/autoconf.h>
55 54
56#define COMPAL_DRIVER_VERSION "0.2.6" 55#define COMPAL_DRIVER_VERSION "0.2.6"
57 56
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
new file mode 100644
index 000000000000..04719551381b
--- /dev/null
+++ b/drivers/regulator/88pm8607.c
@@ -0,0 +1,685 @@
1/*
2 * Regulators driver for Marvell 88PM8607
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/err.h>
14#include <linux/platform_device.h>
15#include <linux/regulator/driver.h>
16#include <linux/regulator/machine.h>
17#include <linux/mfd/88pm8607.h>
18
19struct pm8607_regulator_info {
20 struct regulator_desc desc;
21 struct pm8607_chip *chip;
22 struct regulator_dev *regulator;
23
24 int min_uV;
25 int max_uV;
26 int step_uV;
27 int vol_reg;
28 int vol_shift;
29 int vol_nbits;
30 int update_reg;
31 int update_bit;
32 int enable_reg;
33 int enable_bit;
34 int slope_double;
35};
36
37static inline int check_range(struct pm8607_regulator_info *info,
38 int min_uV, int max_uV)
39{
40 if (max_uV < info->min_uV || min_uV > info->max_uV || min_uV > max_uV)
41 return -EINVAL;
42
43 return 0;
44}
45
46static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
47{
48 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
49 uint8_t chip_id = info->chip->chip_id;
50 int ret = -EINVAL;
51
52 switch (info->desc.id) {
53 case PM8607_ID_BUCK1:
54 ret = (index < 0x1d) ? (index * 25000 + 800000) :
55 ((index < 0x20) ? 1500000 :
56 ((index < 0x40) ? ((index - 0x20) * 25000) :
57 -EINVAL));
58 break;
59 case PM8607_ID_BUCK3:
60 ret = (index < 0x3d) ? (index * 25000) :
61 ((index < 0x40) ? 1500000 : -EINVAL);
62 if (ret < 0)
63 break;
64 if (info->slope_double)
65 ret <<= 1;
66 break;
67 case PM8607_ID_LDO1:
68 ret = (index == 0) ? 1800000 :
69 ((index == 1) ? 1200000 :
70 ((index == 2) ? 2800000 : -EINVAL));
71 break;
72 case PM8607_ID_LDO5:
73 ret = (index == 0) ? 2900000 :
74 ((index == 1) ? 3000000 :
75 ((index == 2) ? 3100000 : 3300000));
76 break;
77 case PM8607_ID_LDO7:
78 case PM8607_ID_LDO8:
79 ret = (index < 3) ? (index * 50000 + 1800000) :
80 ((index < 8) ? (index * 50000 + 2550000) :
81 -EINVAL);
82 break;
83 case PM8607_ID_LDO12:
84 ret = (index < 2) ? (index * 100000 + 1800000) :
85 ((index < 7) ? (index * 100000 + 2500000) :
86 ((index == 7) ? 3300000 : 1200000));
87 break;
88 case PM8607_ID_LDO2:
89 case PM8607_ID_LDO3:
90 case PM8607_ID_LDO9:
91 switch (chip_id) {
92 case PM8607_CHIP_A0:
93 case PM8607_CHIP_A1:
94 ret = (index < 3) ? (index * 50000 + 1800000) :
95 ((index < 8) ? (index * 50000 + 2550000) :
96 -EINVAL);
97 break;
98 case PM8607_CHIP_B0:
99 ret = (index < 3) ? (index * 50000 + 1800000) :
100 ((index < 7) ? (index * 50000 + 2550000) :
101 3300000);
102 break;
103 }
104 break;
105 case PM8607_ID_LDO4:
106 switch (chip_id) {
107 case PM8607_CHIP_A0:
108 case PM8607_CHIP_A1:
109 ret = (index < 3) ? (index * 50000 + 1800000) :
110 ((index < 8) ? (index * 50000 + 2550000) :
111 -EINVAL);
112 break;
113 case PM8607_CHIP_B0:
114 ret = (index < 3) ? (index * 50000 + 1800000) :
115 ((index < 6) ? (index * 50000 + 2550000) :
116 ((index == 6) ? 2900000 : 3300000));
117 break;
118 }
119 break;
120 case PM8607_ID_LDO6:
121 switch (chip_id) {
122 case PM8607_CHIP_A0:
123 case PM8607_CHIP_A1:
124 ret = (index < 3) ? (index * 50000 + 1800000) :
125 ((index < 8) ? (index * 50000 + 2450000) :
126 -EINVAL);
127 break;
128 case PM8607_CHIP_B0:
129 ret = (index < 2) ? (index * 50000 + 1800000) :
130 ((index < 7) ? (index * 50000 + 2500000) :
131 3300000);
132 break;
133 }
134 break;
135 case PM8607_ID_LDO10:
136 switch (chip_id) {
137 case PM8607_CHIP_A0:
138 case PM8607_CHIP_A1:
139 ret = (index < 3) ? (index * 50000 + 1800000) :
140 ((index < 8) ? (index * 50000 + 2550000) :
141 1200000);
142 break;
143 case PM8607_CHIP_B0:
144 ret = (index < 3) ? (index * 50000 + 1800000) :
145 ((index < 7) ? (index * 50000 + 2550000) :
146 ((index == 7) ? 3300000 : 1200000));
147 break;
148 }
149 break;
150 case PM8607_ID_LDO14:
151 switch (chip_id) {
152 case PM8607_CHIP_A0:
153 case PM8607_CHIP_A1:
154 ret = (index < 3) ? (index * 50000 + 1800000) :
155 ((index < 8) ? (index * 50000 + 2550000) :
156 -EINVAL);
157 break;
158 case PM8607_CHIP_B0:
159 ret = (index < 2) ? (index * 50000 + 1800000) :
160 ((index < 7) ? (index * 50000 + 2600000) :
161 3300000);
162 break;
163 }
164 break;
165 }
166 return ret;
167}
168
169static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
170{
171 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
172 uint8_t chip_id = info->chip->chip_id;
173 int val = -ENOENT;
174 int ret;
175
176 switch (info->desc.id) {
177 case PM8607_ID_BUCK1:
178 if (min_uV >= 800000) /* 800mV ~ 1500mV / 25mV */
179 val = (min_uV - 775001) / 25000;
180 else { /* 25mV ~ 775mV / 25mV */
181 val = (min_uV + 249999) / 25000;
182 val += 32;
183 }
184 break;
185 case PM8607_ID_BUCK3:
186 if (info->slope_double)
187 min_uV = min_uV >> 1;
188 val = (min_uV + 249999) / 25000; /* 0mV ~ 1500mV / 25mV */
189
190 break;
191 case PM8607_ID_LDO1:
192 if (min_uV > 1800000)
193 val = 2;
194 else if (min_uV > 1200000)
195 val = 0;
196 else
197 val = 1;
198 break;
199 case PM8607_ID_LDO5:
200 if (min_uV > 3100000)
201 val = 3;
202 else /* 2900mV ~ 3100mV / 100mV */
203 val = (min_uV - 2800001) / 100000;
204 break;
205 case PM8607_ID_LDO7:
206 case PM8607_ID_LDO8:
207 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
208 if (min_uV <= 1800000)
209 val = 0; /* 1800mv */
210 else if (min_uV <= 1900000)
211 val = (min_uV - 1750001) / 50000;
212 else
213 val = 3; /* 2700mV */
214 } else { /* 2700mV ~ 2900mV / 50mV */
215 if (min_uV <= 2900000) {
216 val = (min_uV - 2650001) / 50000;
217 val += 3;
218 } else
219 val = -EINVAL;
220 }
221 break;
222 case PM8607_ID_LDO10:
223 if (min_uV > 2850000)
224 val = 7;
225 else if (min_uV <= 1200000)
226 val = 8;
227 else if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */
228 val = (min_uV - 1750001) / 50000;
229 else { /* 2700mV ~ 2850mV / 50mV */
230 val = (min_uV - 2650001) / 50000;
231 val += 3;
232 }
233 break;
234 case PM8607_ID_LDO12:
235 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 100mV */
236 if (min_uV <= 1200000)
237 val = 8; /* 1200mV */
238 else if (min_uV <= 1800000)
239 val = 0; /* 1800mV */
240 else if (min_uV <= 1900000)
241 val = (min_uV - 1700001) / 100000;
242 else
243 val = 2; /* 2700mV */
244 } else { /* 2700mV ~ 3100mV / 100mV */
245 if (min_uV <= 3100000) {
246 val = (min_uV - 2600001) / 100000;
247 val += 2;
248 } else if (min_uV <= 3300000)
249 val = 7;
250 else
251 val = -EINVAL;
252 }
253 break;
254 case PM8607_ID_LDO2:
255 case PM8607_ID_LDO3:
256 case PM8607_ID_LDO9:
257 switch (chip_id) {
258 case PM8607_CHIP_A0:
259 case PM8607_CHIP_A1:
260 if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */
261 if (min_uV <= 1800000)
262 val = 0;
263 else if (min_uV <= 1900000)
264 val = (min_uV - 1750001) / 50000;
265 else
266 val = 3; /* 2700mV */
267 else { /* 2700mV ~ 2900mV / 50mV */
268 if (min_uV <= 2900000) {
269 val = (min_uV - 2650001) / 50000;
270 val += 3;
271 } else
272 val = -EINVAL;
273 }
274 break;
275 case PM8607_CHIP_B0:
276 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
277 if (min_uV <= 1800000)
278 val = 0;
279 else if (min_uV <= 1900000)
280 val = (min_uV - 1750001) / 50000;
281 else
282 val = 3; /* 2700mV */
283 } else { /* 2700mV ~ 2850mV / 50mV */
284 if (min_uV <= 2850000) {
285 val = (min_uV - 2650001) / 50000;
286 val += 3;
287 } else if (min_uV <= 3300000)
288 val = 7;
289 else
290 val = -EINVAL;
291 }
292 break;
293 }
294 break;
295 case PM8607_ID_LDO4:
296 switch (chip_id) {
297 case PM8607_CHIP_A0:
298 case PM8607_CHIP_A1:
299 if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */
300 if (min_uV <= 1800000)
301 val = 0;
302 else if (min_uV <= 1900000)
303 val = (min_uV - 1750001) / 50000;
304 else
305 val = 3; /* 2700mV */
306 else { /* 2700mV ~ 2900mV / 50mV */
307 if (min_uV <= 2900000) {
308 val = (min_uV - 2650001) / 50000;
309 val += 3;
310 } else
311 val = -EINVAL;
312 }
313 break;
314 case PM8607_CHIP_B0:
315 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
316 if (min_uV <= 1800000)
317 val = 0;
318 else if (min_uV <= 1900000)
319 val = (min_uV - 1750001) / 50000;
320 else
321 val = 3; /* 2700mV */
322 } else { /* 2700mV ~ 2800mV / 50mV */
323 if (min_uV <= 2850000) {
324 val = (min_uV - 2650001) / 50000;
325 val += 3;
326 } else if (min_uV <= 2900000)
327 val = 6;
328 else if (min_uV <= 3300000)
329 val = 7;
330 else
331 val = -EINVAL;
332 }
333 break;
334 }
335 break;
336 case PM8607_ID_LDO6:
337 switch (chip_id) {
338 case PM8607_CHIP_A0:
339 case PM8607_CHIP_A1:
340 if (min_uV < 2600000) { /* 1800mV ~ 1900mV / 50mV */
341 if (min_uV <= 1800000)
342 val = 0;
343 else if (min_uV <= 1900000)
344 val = (min_uV - 1750001) / 50000;
345 else
346 val = 3; /* 2600mV */
347 } else { /* 2600mV ~ 2800mV / 50mV */
348 if (min_uV <= 2800000) {
349 val = (min_uV - 2550001) / 50000;
350 val += 3;
351 } else
352 val = -EINVAL;
353 }
354 break;
355 case PM8607_CHIP_B0:
356 if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */
357 if (min_uV <= 1800000)
358 val = 0;
359 else if (min_uV <= 1850000)
360 val = (min_uV - 1750001) / 50000;
361 else
362 val = 2; /* 2600mV */
363 } else { /* 2600mV ~ 2800mV / 50mV */
364 if (min_uV <= 2800000) {
365 val = (min_uV - 2550001) / 50000;
366 val += 2;
367 } else if (min_uV <= 3300000)
368 val = 7;
369 else
370 val = -EINVAL;
371 }
372 break;
373 }
374 break;
375 case PM8607_ID_LDO14:
376 switch (chip_id) {
377 case PM8607_CHIP_A0:
378 case PM8607_CHIP_A1:
379 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
380 if (min_uV <= 1800000)
381 val = 0;
382 else if (min_uV <= 1900000)
383 val = (min_uV - 1750001) / 50000;
384 else
385 val = 3; /* 2700mV */
386 } else { /* 2700mV ~ 2900mV / 50mV */
387 if (min_uV <= 2900000) {
388 val = (min_uV - 2650001) / 50000;
389 val += 3;
390 } else
391 val = -EINVAL;
392 }
393 break;
394 case PM8607_CHIP_B0:
395 if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */
396 if (min_uV <= 1800000)
397 val = 0;
398 else if (min_uV <= 1850000)
399 val = (min_uV - 1750001) / 50000;
400 else
401 val = 2; /* 2700mV */
402 } else { /* 2700mV ~ 2900mV / 50mV */
403 if (min_uV <= 2900000) {
404 val = (min_uV - 2650001) / 50000;
405 val += 2;
406 } else if (min_uV <= 3300000)
407 val = 7;
408 else
409 val = -EINVAL;
410 }
411 break;
412 }
413 break;
414 }
415 if (val >= 0) {
416 ret = pm8607_list_voltage(rdev, val);
417 if (ret > max_uV) {
418 pr_err("exceed voltage range (%d %d) uV",
419 min_uV, max_uV);
420 return -EINVAL;
421 }
422 } else
423 pr_err("invalid voltage range (%d %d) uV", min_uV, max_uV);
424 return val;
425}
426
427static int pm8607_set_voltage(struct regulator_dev *rdev,
428 int min_uV, int max_uV)
429{
430 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
431 struct pm8607_chip *chip = info->chip;
432 uint8_t val, mask;
433 int ret;
434
435 if (check_range(info, min_uV, max_uV)) {
436 pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
437 return -EINVAL;
438 }
439
440 ret = choose_voltage(rdev, min_uV, max_uV);
441 if (ret < 0)
442 return -EINVAL;
443 val = (uint8_t)(ret << info->vol_shift);
444 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
445
446 ret = pm8607_set_bits(chip, info->vol_reg, mask, val);
447 if (ret)
448 return ret;
449 switch (info->desc.id) {
450 case PM8607_ID_BUCK1:
451 case PM8607_ID_BUCK3:
452 ret = pm8607_set_bits(chip, info->update_reg,
453 1 << info->update_bit,
454 1 << info->update_bit);
455 break;
456 }
457 return ret;
458}
459
460static int pm8607_get_voltage(struct regulator_dev *rdev)
461{
462 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
463 struct pm8607_chip *chip = info->chip;
464 uint8_t val, mask;
465 int ret;
466
467 ret = pm8607_reg_read(chip, info->vol_reg);
468 if (ret < 0)
469 return ret;
470
471 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
472 val = ((unsigned char)ret & mask) >> info->vol_shift;
473
474 return pm8607_list_voltage(rdev, val);
475}
476
477static int pm8607_enable(struct regulator_dev *rdev)
478{
479 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
480 struct pm8607_chip *chip = info->chip;
481
482 return pm8607_set_bits(chip, info->enable_reg,
483 1 << info->enable_bit,
484 1 << info->enable_bit);
485}
486
487static int pm8607_disable(struct regulator_dev *rdev)
488{
489 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
490 struct pm8607_chip *chip = info->chip;
491
492 return pm8607_set_bits(chip, info->enable_reg,
493 1 << info->enable_bit, 0);
494}
495
496static int pm8607_is_enabled(struct regulator_dev *rdev)
497{
498 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
499 struct pm8607_chip *chip = info->chip;
500 int ret;
501
502 ret = pm8607_reg_read(chip, info->enable_reg);
503 if (ret < 0)
504 return ret;
505
506 return !!((unsigned char)ret & (1 << info->enable_bit));
507}
508
509static struct regulator_ops pm8607_regulator_ops = {
510 .set_voltage = pm8607_set_voltage,
511 .get_voltage = pm8607_get_voltage,
512 .enable = pm8607_enable,
513 .disable = pm8607_disable,
514 .is_enabled = pm8607_is_enabled,
515};
516
517#define PM8607_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
518{ \
519 .desc = { \
520 .name = "BUCK" #_id, \
521 .ops = &pm8607_regulator_ops, \
522 .type = REGULATOR_VOLTAGE, \
523 .id = PM8607_ID_BUCK##_id, \
524 .owner = THIS_MODULE, \
525 }, \
526 .min_uV = (min) * 1000, \
527 .max_uV = (max) * 1000, \
528 .step_uV = (step) * 1000, \
529 .vol_reg = PM8607_##vreg, \
530 .vol_shift = (0), \
531 .vol_nbits = (nbits), \
532 .update_reg = PM8607_##ureg, \
533 .update_bit = (ubit), \
534 .enable_reg = PM8607_##ereg, \
535 .enable_bit = (ebit), \
536 .slope_double = (0), \
537}
538
539#define PM8607_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \
540{ \
541 .desc = { \
542 .name = "LDO" #_id, \
543 .ops = &pm8607_regulator_ops, \
544 .type = REGULATOR_VOLTAGE, \
545 .id = PM8607_ID_LDO##_id, \
546 .owner = THIS_MODULE, \
547 }, \
548 .min_uV = (min) * 1000, \
549 .max_uV = (max) * 1000, \
550 .step_uV = (step) * 1000, \
551 .vol_reg = PM8607_##vreg, \
552 .vol_shift = (shift), \
553 .vol_nbits = (nbits), \
554 .enable_reg = PM8607_##ereg, \
555 .enable_bit = (ebit), \
556 .slope_double = (0), \
557}
558
559static struct pm8607_regulator_info pm8607_regulator_info[] = {
560 PM8607_DVC(1, 0, 1500, 25, BUCK1, 6, GO, 0, SUPPLIES_EN11, 0),
561 PM8607_DVC(3, 0, 1500, 25, BUCK3, 6, GO, 2, SUPPLIES_EN11, 2),
562
563 PM8607_LDO(1 , 1200, 2800, 0, LDO1 , 0, 2, SUPPLIES_EN11, 3),
564 PM8607_LDO(2 , 1800, 3300, 0, LDO2 , 0, 3, SUPPLIES_EN11, 4),
565 PM8607_LDO(3 , 1800, 3300, 0, LDO3 , 0, 3, SUPPLIES_EN11, 5),
566 PM8607_LDO(4 , 1800, 3300, 0, LDO4 , 0, 3, SUPPLIES_EN11, 6),
567 PM8607_LDO(5 , 2900, 3300, 0, LDO5 , 0, 2, SUPPLIES_EN11, 7),
568 PM8607_LDO(6 , 1800, 3300, 0, LDO6 , 0, 3, SUPPLIES_EN12, 0),
569 PM8607_LDO(7 , 1800, 2900, 0, LDO7 , 0, 3, SUPPLIES_EN12, 1),
570 PM8607_LDO(8 , 1800, 2900, 0, LDO8 , 0, 3, SUPPLIES_EN12, 2),
571 PM8607_LDO(9 , 1800, 3300, 0, LDO9 , 0, 3, SUPPLIES_EN12, 3),
572 PM8607_LDO(10, 1200, 3300, 0, LDO10, 0, 4, SUPPLIES_EN11, 4),
573 PM8607_LDO(12, 1200, 3300, 0, LDO12, 0, 4, SUPPLIES_EN11, 5),
574 PM8607_LDO(14, 1800, 3300, 0, LDO14, 0, 3, SUPPLIES_EN11, 6),
575};
576
577static inline struct pm8607_regulator_info *find_regulator_info(int id)
578{
579 struct pm8607_regulator_info *info;
580 int i;
581
582 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
583 info = &pm8607_regulator_info[i];
584 if (info->desc.id == id)
585 return info;
586 }
587 return NULL;
588}
589
590static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
591{
592 struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent);
593 struct pm8607_platform_data *pdata = chip->dev->platform_data;
594 struct pm8607_regulator_info *info = NULL;
595
596 info = find_regulator_info(pdev->id);
597 if (info == NULL) {
598 dev_err(&pdev->dev, "invalid regulator ID specified\n");
599 return -EINVAL;
600 }
601
602 info->chip = chip;
603
604 info->regulator = regulator_register(&info->desc, &pdev->dev,
605 pdata->regulator[pdev->id], info);
606 if (IS_ERR(info->regulator)) {
607 dev_err(&pdev->dev, "failed to register regulator %s\n",
608 info->desc.name);
609 return PTR_ERR(info->regulator);
610 }
611
612 /* check DVC ramp slope double */
613 if (info->desc.id == PM8607_ID_BUCK3)
614 if (info->chip->buck3_double)
615 info->slope_double = 1;
616
617 platform_set_drvdata(pdev, info);
618 return 0;
619}
620
621static int __devexit pm8607_regulator_remove(struct platform_device *pdev)
622{
623 struct pm8607_regulator_info *info = platform_get_drvdata(pdev);
624
625 regulator_unregister(info->regulator);
626 return 0;
627}
628
629#define PM8607_REGULATOR_DRIVER(_name) \
630{ \
631 .driver = { \
632 .name = "88pm8607-" #_name, \
633 .owner = THIS_MODULE, \
634 }, \
635 .probe = pm8607_regulator_probe, \
636 .remove = __devexit_p(pm8607_regulator_remove), \
637}
638
639static struct platform_driver pm8607_regulator_driver[] = {
640 PM8607_REGULATOR_DRIVER(buck1),
641 PM8607_REGULATOR_DRIVER(buck2),
642 PM8607_REGULATOR_DRIVER(buck3),
643 PM8607_REGULATOR_DRIVER(ldo1),
644 PM8607_REGULATOR_DRIVER(ldo2),
645 PM8607_REGULATOR_DRIVER(ldo3),
646 PM8607_REGULATOR_DRIVER(ldo4),
647 PM8607_REGULATOR_DRIVER(ldo5),
648 PM8607_REGULATOR_DRIVER(ldo6),
649 PM8607_REGULATOR_DRIVER(ldo7),
650 PM8607_REGULATOR_DRIVER(ldo8),
651 PM8607_REGULATOR_DRIVER(ldo9),
652 PM8607_REGULATOR_DRIVER(ldo10),
653 PM8607_REGULATOR_DRIVER(ldo12),
654 PM8607_REGULATOR_DRIVER(ldo14),
655};
656
657static int __init pm8607_regulator_init(void)
658{
659 int i, count, ret;
660
661 count = ARRAY_SIZE(pm8607_regulator_driver);
662 for (i = 0; i < count; i++) {
663 ret = platform_driver_register(&pm8607_regulator_driver[i]);
664 if (ret != 0)
665 pr_err("Failed to register regulator driver: %d\n",
666 ret);
667 }
668 return 0;
669}
670subsys_initcall(pm8607_regulator_init);
671
672static void __exit pm8607_regulator_exit(void)
673{
674 int i, count;
675
676 count = ARRAY_SIZE(pm8607_regulator_driver);
677 for (i = 0; i < count; i++)
678 platform_driver_unregister(&pm8607_regulator_driver[i]);
679}
680module_exit(pm8607_regulator_exit);
681
682MODULE_LICENSE("GPL");
683MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
684MODULE_DESCRIPTION("Regulator Driver for Marvell 88PM8607 PMIC");
685MODULE_ALIAS("platform:88pm8607-regulator");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 7cfdd65bebb4..262f62eec837 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -69,6 +69,13 @@ config REGULATOR_MAX1586
69 regulator via I2C bus. The provided regulator is suitable 69 regulator via I2C bus. The provided regulator is suitable
70 for PXA27x chips to control VCC_CORE and VCC_USIM voltages. 70 for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
71 71
72config REGULATOR_MAX8660
73 tristate "Maxim 8660/8661 voltage regulator"
74 depends on I2C
75 help
76 This driver controls a Maxim 8660/8661 voltage output
77 regulator via I2C bus.
78
72config REGULATOR_TWL4030 79config REGULATOR_TWL4030
73 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" 80 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
74 depends on TWL4030_CORE 81 depends on TWL4030_CORE
@@ -157,5 +164,11 @@ config REGULATOR_TPS6507X
157 three step-down converters and two general-purpose LDO voltage regulators. 164 three step-down converters and two general-purpose LDO voltage regulators.
158 It supports TI's software based Class-2 SmartReflex implementation. 165 It supports TI's software based Class-2 SmartReflex implementation.
159 166
167config REGULATOR_88PM8607
168 bool "Marvell 88PM8607 Power regulators"
169 depends on MFD_88PM8607=y
170 help
171 This driver supports 88PM8607 voltage regulator chips.
172
160endif 173endif
161 174
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 9ae3cc44e668..b3c806c79415 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
12obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o 12obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
13obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o 13obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
14obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o 14obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
15obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
15obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 16obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
16obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o 17obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
17obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o 18obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
@@ -20,10 +21,11 @@ obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
20obj-$(CONFIG_REGULATOR_DA903X) += da903x.o 21obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
21obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o 22obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
22obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o 23obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
23obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o 24obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
24obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o 25obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
25 26
26obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o 27obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
27obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o 28obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
29obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
28 30
29ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG 31ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index 49aeee823a25..b349db4504b7 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -81,7 +81,7 @@ static const u8 ab3100_reg_init_order[AB3100_NUM_REGULATORS+2] = {
81#define LDO_C_VOLTAGE 2650000 81#define LDO_C_VOLTAGE 2650000
82#define LDO_D_VOLTAGE 2650000 82#define LDO_D_VOLTAGE 2650000
83 83
84static const int const ldo_e_buck_typ_voltages[] = { 84static const int ldo_e_buck_typ_voltages[] = {
85 1800000, 85 1800000,
86 1400000, 86 1400000,
87 1300000, 87 1300000,
@@ -91,7 +91,7 @@ static const int const ldo_e_buck_typ_voltages[] = {
91 900000, 91 900000,
92}; 92};
93 93
94static const int const ldo_f_typ_voltages[] = { 94static const int ldo_f_typ_voltages[] = {
95 1800000, 95 1800000,
96 1400000, 96 1400000,
97 1300000, 97 1300000,
@@ -102,21 +102,21 @@ static const int const ldo_f_typ_voltages[] = {
102 2650000, 102 2650000,
103}; 103};
104 104
105static const int const ldo_g_typ_voltages[] = { 105static const int ldo_g_typ_voltages[] = {
106 2850000, 106 2850000,
107 2750000, 107 2750000,
108 1800000, 108 1800000,
109 1500000, 109 1500000,
110}; 110};
111 111
112static const int const ldo_h_typ_voltages[] = { 112static const int ldo_h_typ_voltages[] = {
113 2750000, 113 2750000,
114 1800000, 114 1800000,
115 1500000, 115 1500000,
116 1200000, 116 1200000,
117}; 117};
118 118
119static const int const ldo_k_typ_voltages[] = { 119static const int ldo_k_typ_voltages[] = {
120 2750000, 120 2750000,
121 1800000, 121 1800000,
122}; 122};
@@ -241,24 +241,12 @@ static int ab3100_disable_regulator(struct regulator_dev *reg)
241 * LDO D is a special regulator. When it is disabled, the entire 241 * LDO D is a special regulator. When it is disabled, the entire
242 * system is shut down. So this is handled specially. 242 * system is shut down. So this is handled specially.
243 */ 243 */
244 pr_info("Called ab3100_disable_regulator\n");
244 if (abreg->regreg == AB3100_LDO_D) { 245 if (abreg->regreg == AB3100_LDO_D) {
245 int i;
246
247 dev_info(&reg->dev, "disabling LDO D - shut down system\n"); 246 dev_info(&reg->dev, "disabling LDO D - shut down system\n");
248 /*
249 * Set regulators to default values, ignore any errors,
250 * we're going DOWN
251 */
252 for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
253 (void) ab3100_set_register_interruptible(abreg->ab3100,
254 ab3100_reg_init_order[i],
255 abreg->plfdata->reg_initvals[i]);
256 }
257
258 /* Setting LDO D to 0x00 cuts the power to the SoC */ 247 /* Setting LDO D to 0x00 cuts the power to the SoC */
259 return ab3100_set_register_interruptible(abreg->ab3100, 248 return ab3100_set_register_interruptible(abreg->ab3100,
260 AB3100_LDO_D, 0x00U); 249 AB3100_LDO_D, 0x00U);
261
262 } 250 }
263 251
264 /* 252 /*
@@ -607,13 +595,6 @@ static int __init ab3100_regulators_probe(struct platform_device *pdev)
607 } 595 }
608 } 596 }
609 597
610 if (err) {
611 dev_err(&pdev->dev,
612 "LDO D regulator initialization failed with error %d\n",
613 err);
614 return err;
615 }
616
617 /* Register the regulators */ 598 /* Register the regulators */
618 for (i = 0; i < AB3100_NUM_REGULATORS; i++) { 599 for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
619 struct ab3100_regulator *reg = &ab3100_regulators[i]; 600 struct ab3100_regulator *reg = &ab3100_regulators[i];
@@ -688,7 +669,7 @@ static __init int ab3100_regulators_init(void)
688 669
689static __exit void ab3100_regulators_exit(void) 670static __exit void ab3100_regulators_exit(void)
690{ 671{
691 platform_driver_register(&ab3100_regulators_driver); 672 platform_driver_unregister(&ab3100_regulators_driver);
692} 673}
693 674
694subsys_initcall(ab3100_regulators_init); 675subsys_initcall(ab3100_regulators_init);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index efe568deda12..686ef270ecf7 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -66,6 +66,16 @@ static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
66static void _notifier_call_chain(struct regulator_dev *rdev, 66static void _notifier_call_chain(struct regulator_dev *rdev,
67 unsigned long event, void *data); 67 unsigned long event, void *data);
68 68
69static const char *rdev_get_name(struct regulator_dev *rdev)
70{
71 if (rdev->constraints && rdev->constraints->name)
72 return rdev->constraints->name;
73 else if (rdev->desc->name)
74 return rdev->desc->name;
75 else
76 return "";
77}
78
69/* gets the regulator for a given consumer device */ 79/* gets the regulator for a given consumer device */
70static struct regulator *get_device_regulator(struct device *dev) 80static struct regulator *get_device_regulator(struct device *dev)
71{ 81{
@@ -96,12 +106,12 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
96 106
97 if (!rdev->constraints) { 107 if (!rdev->constraints) {
98 printk(KERN_ERR "%s: no constraints for %s\n", __func__, 108 printk(KERN_ERR "%s: no constraints for %s\n", __func__,
99 rdev->desc->name); 109 rdev_get_name(rdev));
100 return -ENODEV; 110 return -ENODEV;
101 } 111 }
102 if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { 112 if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
103 printk(KERN_ERR "%s: operation not allowed for %s\n", 113 printk(KERN_ERR "%s: operation not allowed for %s\n",
104 __func__, rdev->desc->name); 114 __func__, rdev_get_name(rdev));
105 return -EPERM; 115 return -EPERM;
106 } 116 }
107 117
@@ -124,12 +134,12 @@ static int regulator_check_current_limit(struct regulator_dev *rdev,
124 134
125 if (!rdev->constraints) { 135 if (!rdev->constraints) {
126 printk(KERN_ERR "%s: no constraints for %s\n", __func__, 136 printk(KERN_ERR "%s: no constraints for %s\n", __func__,
127 rdev->desc->name); 137 rdev_get_name(rdev));
128 return -ENODEV; 138 return -ENODEV;
129 } 139 }
130 if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) { 140 if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) {
131 printk(KERN_ERR "%s: operation not allowed for %s\n", 141 printk(KERN_ERR "%s: operation not allowed for %s\n",
132 __func__, rdev->desc->name); 142 __func__, rdev_get_name(rdev));
133 return -EPERM; 143 return -EPERM;
134 } 144 }
135 145
@@ -159,17 +169,17 @@ static int regulator_check_mode(struct regulator_dev *rdev, int mode)
159 169
160 if (!rdev->constraints) { 170 if (!rdev->constraints) {
161 printk(KERN_ERR "%s: no constraints for %s\n", __func__, 171 printk(KERN_ERR "%s: no constraints for %s\n", __func__,
162 rdev->desc->name); 172 rdev_get_name(rdev));
163 return -ENODEV; 173 return -ENODEV;
164 } 174 }
165 if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) { 175 if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) {
166 printk(KERN_ERR "%s: operation not allowed for %s\n", 176 printk(KERN_ERR "%s: operation not allowed for %s\n",
167 __func__, rdev->desc->name); 177 __func__, rdev_get_name(rdev));
168 return -EPERM; 178 return -EPERM;
169 } 179 }
170 if (!(rdev->constraints->valid_modes_mask & mode)) { 180 if (!(rdev->constraints->valid_modes_mask & mode)) {
171 printk(KERN_ERR "%s: invalid mode %x for %s\n", 181 printk(KERN_ERR "%s: invalid mode %x for %s\n",
172 __func__, mode, rdev->desc->name); 182 __func__, mode, rdev_get_name(rdev));
173 return -EINVAL; 183 return -EINVAL;
174 } 184 }
175 return 0; 185 return 0;
@@ -180,12 +190,12 @@ static int regulator_check_drms(struct regulator_dev *rdev)
180{ 190{
181 if (!rdev->constraints) { 191 if (!rdev->constraints) {
182 printk(KERN_ERR "%s: no constraints for %s\n", __func__, 192 printk(KERN_ERR "%s: no constraints for %s\n", __func__,
183 rdev->desc->name); 193 rdev_get_name(rdev));
184 return -ENODEV; 194 return -ENODEV;
185 } 195 }
186 if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) { 196 if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
187 printk(KERN_ERR "%s: operation not allowed for %s\n", 197 printk(KERN_ERR "%s: operation not allowed for %s\n",
188 __func__, rdev->desc->name); 198 __func__, rdev_get_name(rdev));
189 return -EPERM; 199 return -EPERM;
190 } 200 }
191 return 0; 201 return 0;
@@ -230,16 +240,8 @@ static ssize_t regulator_name_show(struct device *dev,
230 struct device_attribute *attr, char *buf) 240 struct device_attribute *attr, char *buf)
231{ 241{
232 struct regulator_dev *rdev = dev_get_drvdata(dev); 242 struct regulator_dev *rdev = dev_get_drvdata(dev);
233 const char *name;
234 243
235 if (rdev->constraints && rdev->constraints->name) 244 return sprintf(buf, "%s\n", rdev_get_name(rdev));
236 name = rdev->constraints->name;
237 else if (rdev->desc->name)
238 name = rdev->desc->name;
239 else
240 name = "";
241
242 return sprintf(buf, "%s\n", name);
243} 245}
244 246
245static ssize_t regulator_print_opmode(char *buf, int mode) 247static ssize_t regulator_print_opmode(char *buf, int mode)
@@ -388,7 +390,7 @@ static ssize_t regulator_total_uA_show(struct device *dev,
388 390
389 mutex_lock(&rdev->mutex); 391 mutex_lock(&rdev->mutex);
390 list_for_each_entry(regulator, &rdev->consumer_list, list) 392 list_for_each_entry(regulator, &rdev->consumer_list, list)
391 uA += regulator->uA_load; 393 uA += regulator->uA_load;
392 mutex_unlock(&rdev->mutex); 394 mutex_unlock(&rdev->mutex);
393 return sprintf(buf, "%d\n", uA); 395 return sprintf(buf, "%d\n", uA);
394} 396}
@@ -563,7 +565,7 @@ static void drms_uA_update(struct regulator_dev *rdev)
563 565
564 /* calc total requested load */ 566 /* calc total requested load */
565 list_for_each_entry(sibling, &rdev->consumer_list, list) 567 list_for_each_entry(sibling, &rdev->consumer_list, list)
566 current_uA += sibling->uA_load; 568 current_uA += sibling->uA_load;
567 569
568 /* now get the optimum mode for our new total regulator load */ 570 /* now get the optimum mode for our new total regulator load */
569 mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, 571 mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
@@ -579,10 +581,29 @@ static int suspend_set_state(struct regulator_dev *rdev,
579 struct regulator_state *rstate) 581 struct regulator_state *rstate)
580{ 582{
581 int ret = 0; 583 int ret = 0;
584 bool can_set_state;
582 585
583 /* enable & disable are mandatory for suspend control */ 586 can_set_state = rdev->desc->ops->set_suspend_enable &&
584 if (!rdev->desc->ops->set_suspend_enable || 587 rdev->desc->ops->set_suspend_disable;
585 !rdev->desc->ops->set_suspend_disable) { 588
589 /* If we have no suspend mode configration don't set anything;
590 * only warn if the driver actually makes the suspend mode
591 * configurable.
592 */
593 if (!rstate->enabled && !rstate->disabled) {
594 if (can_set_state)
595 printk(KERN_WARNING "%s: No configuration for %s\n",
596 __func__, rdev_get_name(rdev));
597 return 0;
598 }
599
600 if (rstate->enabled && rstate->disabled) {
601 printk(KERN_ERR "%s: invalid configuration for %s\n",
602 __func__, rdev_get_name(rdev));
603 return -EINVAL;
604 }
605
606 if (!can_set_state) {
586 printk(KERN_ERR "%s: no way to set suspend state\n", 607 printk(KERN_ERR "%s: no way to set suspend state\n",
587 __func__); 608 __func__);
588 return -EINVAL; 609 return -EINVAL;
@@ -641,25 +662,43 @@ static void print_constraints(struct regulator_dev *rdev)
641{ 662{
642 struct regulation_constraints *constraints = rdev->constraints; 663 struct regulation_constraints *constraints = rdev->constraints;
643 char buf[80]; 664 char buf[80];
644 int count; 665 int count = 0;
666 int ret;
645 667
646 if (rdev->desc->type == REGULATOR_VOLTAGE) { 668 if (constraints->min_uV && constraints->max_uV) {
647 if (constraints->min_uV == constraints->max_uV) 669 if (constraints->min_uV == constraints->max_uV)
648 count = sprintf(buf, "%d mV ", 670 count += sprintf(buf + count, "%d mV ",
649 constraints->min_uV / 1000); 671 constraints->min_uV / 1000);
650 else 672 else
651 count = sprintf(buf, "%d <--> %d mV ", 673 count += sprintf(buf + count, "%d <--> %d mV ",
652 constraints->min_uV / 1000, 674 constraints->min_uV / 1000,
653 constraints->max_uV / 1000); 675 constraints->max_uV / 1000);
654 } else { 676 }
677
678 if (!constraints->min_uV ||
679 constraints->min_uV != constraints->max_uV) {
680 ret = _regulator_get_voltage(rdev);
681 if (ret > 0)
682 count += sprintf(buf + count, "at %d mV ", ret / 1000);
683 }
684
685 if (constraints->min_uA && constraints->max_uA) {
655 if (constraints->min_uA == constraints->max_uA) 686 if (constraints->min_uA == constraints->max_uA)
656 count = sprintf(buf, "%d mA ", 687 count += sprintf(buf + count, "%d mA ",
657 constraints->min_uA / 1000); 688 constraints->min_uA / 1000);
658 else 689 else
659 count = sprintf(buf, "%d <--> %d mA ", 690 count += sprintf(buf + count, "%d <--> %d mA ",
660 constraints->min_uA / 1000, 691 constraints->min_uA / 1000,
661 constraints->max_uA / 1000); 692 constraints->max_uA / 1000);
662 } 693 }
694
695 if (!constraints->min_uA ||
696 constraints->min_uA != constraints->max_uA) {
697 ret = _regulator_get_current_limit(rdev);
698 if (ret > 0)
699 count += sprintf(buf + count, "at %d uA ", ret / 1000);
700 }
701
663 if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) 702 if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
664 count += sprintf(buf + count, "fast "); 703 count += sprintf(buf + count, "fast ");
665 if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL) 704 if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL)
@@ -669,33 +708,30 @@ static void print_constraints(struct regulator_dev *rdev)
669 if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY) 708 if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
670 count += sprintf(buf + count, "standby"); 709 count += sprintf(buf + count, "standby");
671 710
672 printk(KERN_INFO "regulator: %s: %s\n", rdev->desc->name, buf); 711 printk(KERN_INFO "regulator: %s: %s\n", rdev_get_name(rdev), buf);
673} 712}
674 713
675/** 714static int machine_constraints_voltage(struct regulator_dev *rdev,
676 * set_machine_constraints - sets regulator constraints
677 * @rdev: regulator source
678 * @constraints: constraints to apply
679 *
680 * Allows platform initialisation code to define and constrain
681 * regulator circuits e.g. valid voltage/current ranges, etc. NOTE:
682 * Constraints *must* be set by platform code in order for some
683 * regulator operations to proceed i.e. set_voltage, set_current_limit,
684 * set_mode.
685 */
686static int set_machine_constraints(struct regulator_dev *rdev,
687 struct regulation_constraints *constraints) 715 struct regulation_constraints *constraints)
688{ 716{
689 int ret = 0;
690 const char *name;
691 struct regulator_ops *ops = rdev->desc->ops; 717 struct regulator_ops *ops = rdev->desc->ops;
718 const char *name = rdev_get_name(rdev);
719 int ret;
692 720
693 if (constraints->name) 721 /* do we need to apply the constraint voltage */
694 name = constraints->name; 722 if (rdev->constraints->apply_uV &&
695 else if (rdev->desc->name) 723 rdev->constraints->min_uV == rdev->constraints->max_uV &&
696 name = rdev->desc->name; 724 ops->set_voltage) {
697 else 725 ret = ops->set_voltage(rdev,
698 name = "regulator"; 726 rdev->constraints->min_uV, rdev->constraints->max_uV);
727 if (ret < 0) {
728 printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n",
729 __func__,
730 rdev->constraints->min_uV, name);
731 rdev->constraints = NULL;
732 return ret;
733 }
734 }
699 735
700 /* constrain machine-level voltage specs to fit 736 /* constrain machine-level voltage specs to fit
701 * the actual range supported by this regulator. 737 * the actual range supported by this regulator.
@@ -719,14 +755,13 @@ static int set_machine_constraints(struct regulator_dev *rdev,
719 755
720 /* voltage constraints are optional */ 756 /* voltage constraints are optional */
721 if ((cmin == 0) && (cmax == 0)) 757 if ((cmin == 0) && (cmax == 0))
722 goto out; 758 return 0;
723 759
724 /* else require explicit machine-level constraints */ 760 /* else require explicit machine-level constraints */
725 if (cmin <= 0 || cmax <= 0 || cmax < cmin) { 761 if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
726 pr_err("%s: %s '%s' voltage constraints\n", 762 pr_err("%s: %s '%s' voltage constraints\n",
727 __func__, "invalid", name); 763 __func__, "invalid", name);
728 ret = -EINVAL; 764 return -EINVAL;
729 goto out;
730 } 765 }
731 766
732 /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ 767 /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
@@ -748,8 +783,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
748 if (max_uV < min_uV) { 783 if (max_uV < min_uV) {
749 pr_err("%s: %s '%s' voltage constraints\n", 784 pr_err("%s: %s '%s' voltage constraints\n",
750 __func__, "unsupportable", name); 785 __func__, "unsupportable", name);
751 ret = -EINVAL; 786 return -EINVAL;
752 goto out;
753 } 787 }
754 788
755 /* use regulator's subset of machine constraints */ 789 /* use regulator's subset of machine constraints */
@@ -767,22 +801,34 @@ static int set_machine_constraints(struct regulator_dev *rdev,
767 } 801 }
768 } 802 }
769 803
804 return 0;
805}
806
807/**
808 * set_machine_constraints - sets regulator constraints
809 * @rdev: regulator source
810 * @constraints: constraints to apply
811 *
812 * Allows platform initialisation code to define and constrain
813 * regulator circuits e.g. valid voltage/current ranges, etc. NOTE:
814 * Constraints *must* be set by platform code in order for some
815 * regulator operations to proceed i.e. set_voltage, set_current_limit,
816 * set_mode.
817 */
818static int set_machine_constraints(struct regulator_dev *rdev,
819 struct regulation_constraints *constraints)
820{
821 int ret = 0;
822 const char *name;
823 struct regulator_ops *ops = rdev->desc->ops;
824
770 rdev->constraints = constraints; 825 rdev->constraints = constraints;
771 826
772 /* do we need to apply the constraint voltage */ 827 name = rdev_get_name(rdev);
773 if (rdev->constraints->apply_uV && 828
774 rdev->constraints->min_uV == rdev->constraints->max_uV && 829 ret = machine_constraints_voltage(rdev, constraints);
775 ops->set_voltage) { 830 if (ret != 0)
776 ret = ops->set_voltage(rdev, 831 goto out;
777 rdev->constraints->min_uV, rdev->constraints->max_uV);
778 if (ret < 0) {
779 printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n",
780 __func__,
781 rdev->constraints->min_uV, name);
782 rdev->constraints = NULL;
783 goto out;
784 }
785 }
786 832
787 /* do we need to setup our suspend state */ 833 /* do we need to setup our suspend state */
788 if (constraints->initial_state) { 834 if (constraints->initial_state) {
@@ -903,7 +949,7 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
903 dev_name(&node->regulator->dev), 949 dev_name(&node->regulator->dev),
904 node->regulator->desc->name, 950 node->regulator->desc->name,
905 supply, 951 supply,
906 dev_name(&rdev->dev), rdev->desc->name); 952 dev_name(&rdev->dev), rdev_get_name(rdev));
907 return -EBUSY; 953 return -EBUSY;
908 } 954 }
909 955
@@ -1212,7 +1258,7 @@ static int _regulator_enable(struct regulator_dev *rdev)
1212 ret = _regulator_enable(rdev->supply); 1258 ret = _regulator_enable(rdev->supply);
1213 if (ret < 0) { 1259 if (ret < 0) {
1214 printk(KERN_ERR "%s: failed to enable %s: %d\n", 1260 printk(KERN_ERR "%s: failed to enable %s: %d\n",
1215 __func__, rdev->desc->name, ret); 1261 __func__, rdev_get_name(rdev), ret);
1216 return ret; 1262 return ret;
1217 } 1263 }
1218 } 1264 }
@@ -1238,7 +1284,7 @@ static int _regulator_enable(struct regulator_dev *rdev)
1238 } 1284 }
1239 } else if (ret < 0) { 1285 } else if (ret < 0) {
1240 printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n", 1286 printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
1241 __func__, rdev->desc->name, ret); 1287 __func__, rdev_get_name(rdev), ret);
1242 return ret; 1288 return ret;
1243 } 1289 }
1244 /* Fallthrough on positive return values - already enabled */ 1290 /* Fallthrough on positive return values - already enabled */
@@ -1279,7 +1325,7 @@ static int _regulator_disable(struct regulator_dev *rdev)
1279 1325
1280 if (WARN(rdev->use_count <= 0, 1326 if (WARN(rdev->use_count <= 0,
1281 "unbalanced disables for %s\n", 1327 "unbalanced disables for %s\n",
1282 rdev->desc->name)) 1328 rdev_get_name(rdev)))
1283 return -EIO; 1329 return -EIO;
1284 1330
1285 /* are we the last user and permitted to disable ? */ 1331 /* are we the last user and permitted to disable ? */
@@ -1292,7 +1338,7 @@ static int _regulator_disable(struct regulator_dev *rdev)
1292 ret = rdev->desc->ops->disable(rdev); 1338 ret = rdev->desc->ops->disable(rdev);
1293 if (ret < 0) { 1339 if (ret < 0) {
1294 printk(KERN_ERR "%s: failed to disable %s\n", 1340 printk(KERN_ERR "%s: failed to disable %s\n",
1295 __func__, rdev->desc->name); 1341 __func__, rdev_get_name(rdev));
1296 return ret; 1342 return ret;
1297 } 1343 }
1298 } 1344 }
@@ -1349,7 +1395,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
1349 ret = rdev->desc->ops->disable(rdev); 1395 ret = rdev->desc->ops->disable(rdev);
1350 if (ret < 0) { 1396 if (ret < 0) {
1351 printk(KERN_ERR "%s: failed to force disable %s\n", 1397 printk(KERN_ERR "%s: failed to force disable %s\n",
1352 __func__, rdev->desc->name); 1398 __func__, rdev_get_name(rdev));
1353 return ret; 1399 return ret;
1354 } 1400 }
1355 /* notify other consumers that power has been forced off */ 1401 /* notify other consumers that power has been forced off */
@@ -1766,7 +1812,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
1766 output_uV = rdev->desc->ops->get_voltage(rdev); 1812 output_uV = rdev->desc->ops->get_voltage(rdev);
1767 if (output_uV <= 0) { 1813 if (output_uV <= 0) {
1768 printk(KERN_ERR "%s: invalid output voltage found for %s\n", 1814 printk(KERN_ERR "%s: invalid output voltage found for %s\n",
1769 __func__, rdev->desc->name); 1815 __func__, rdev_get_name(rdev));
1770 goto out; 1816 goto out;
1771 } 1817 }
1772 1818
@@ -1777,13 +1823,13 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
1777 input_uV = rdev->constraints->input_uV; 1823 input_uV = rdev->constraints->input_uV;
1778 if (input_uV <= 0) { 1824 if (input_uV <= 0) {
1779 printk(KERN_ERR "%s: invalid input voltage found for %s\n", 1825 printk(KERN_ERR "%s: invalid input voltage found for %s\n",
1780 __func__, rdev->desc->name); 1826 __func__, rdev_get_name(rdev));
1781 goto out; 1827 goto out;
1782 } 1828 }
1783 1829
1784 /* calc total requested load for this regulator */ 1830 /* calc total requested load for this regulator */
1785 list_for_each_entry(consumer, &rdev->consumer_list, list) 1831 list_for_each_entry(consumer, &rdev->consumer_list, list)
1786 total_uA_load += consumer->uA_load; 1832 total_uA_load += consumer->uA_load;
1787 1833
1788 mode = rdev->desc->ops->get_optimum_mode(rdev, 1834 mode = rdev->desc->ops->get_optimum_mode(rdev,
1789 input_uV, output_uV, 1835 input_uV, output_uV,
@@ -1791,7 +1837,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
1791 ret = regulator_check_mode(rdev, mode); 1837 ret = regulator_check_mode(rdev, mode);
1792 if (ret < 0) { 1838 if (ret < 0) {
1793 printk(KERN_ERR "%s: failed to get optimum mode for %s @" 1839 printk(KERN_ERR "%s: failed to get optimum mode for %s @"
1794 " %d uA %d -> %d uV\n", __func__, rdev->desc->name, 1840 " %d uA %d -> %d uV\n", __func__, rdev_get_name(rdev),
1795 total_uA_load, input_uV, output_uV); 1841 total_uA_load, input_uV, output_uV);
1796 goto out; 1842 goto out;
1797 } 1843 }
@@ -1799,7 +1845,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
1799 ret = rdev->desc->ops->set_mode(rdev, mode); 1845 ret = rdev->desc->ops->set_mode(rdev, mode);
1800 if (ret < 0) { 1846 if (ret < 0) {
1801 printk(KERN_ERR "%s: failed to set optimum mode %x for %s\n", 1847 printk(KERN_ERR "%s: failed to set optimum mode %x for %s\n",
1802 __func__, mode, rdev->desc->name); 1848 __func__, mode, rdev_get_name(rdev));
1803 goto out; 1849 goto out;
1804 } 1850 }
1805 ret = mode; 1851 ret = mode;
@@ -1852,9 +1898,9 @@ static void _notifier_call_chain(struct regulator_dev *rdev,
1852 1898
1853 /* now notify regulator we supply */ 1899 /* now notify regulator we supply */
1854 list_for_each_entry(_rdev, &rdev->supply_list, slist) { 1900 list_for_each_entry(_rdev, &rdev->supply_list, slist) {
1855 mutex_lock(&_rdev->mutex); 1901 mutex_lock(&_rdev->mutex);
1856 _notifier_call_chain(_rdev, event, data); 1902 _notifier_call_chain(_rdev, event, data);
1857 mutex_unlock(&_rdev->mutex); 1903 mutex_unlock(&_rdev->mutex);
1858 } 1904 }
1859} 1905}
1860 1906
@@ -1885,9 +1931,9 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
1885 consumers[i].consumer = regulator_get(dev, 1931 consumers[i].consumer = regulator_get(dev,
1886 consumers[i].supply); 1932 consumers[i].supply);
1887 if (IS_ERR(consumers[i].consumer)) { 1933 if (IS_ERR(consumers[i].consumer)) {
1888 dev_err(dev, "Failed to get supply '%s'\n",
1889 consumers[i].supply);
1890 ret = PTR_ERR(consumers[i].consumer); 1934 ret = PTR_ERR(consumers[i].consumer);
1935 dev_err(dev, "Failed to get supply '%s': %d\n",
1936 consumers[i].supply, ret);
1891 consumers[i].consumer = NULL; 1937 consumers[i].consumer = NULL;
1892 goto err; 1938 goto err;
1893 } 1939 }
@@ -1930,8 +1976,8 @@ int regulator_bulk_enable(int num_consumers,
1930 return 0; 1976 return 0;
1931 1977
1932err: 1978err:
1933 printk(KERN_ERR "Failed to enable %s\n", consumers[i].supply); 1979 printk(KERN_ERR "Failed to enable %s: %d\n", consumers[i].supply, ret);
1934 for (i = 0; i < num_consumers; i++) 1980 for (--i; i >= 0; --i)
1935 regulator_disable(consumers[i].consumer); 1981 regulator_disable(consumers[i].consumer);
1936 1982
1937 return ret; 1983 return ret;
@@ -1965,8 +2011,9 @@ int regulator_bulk_disable(int num_consumers,
1965 return 0; 2011 return 0;
1966 2012
1967err: 2013err:
1968 printk(KERN_ERR "Failed to disable %s\n", consumers[i].supply); 2014 printk(KERN_ERR "Failed to disable %s: %d\n", consumers[i].supply,
1969 for (i = 0; i < num_consumers; i++) 2015 ret);
2016 for (--i; i >= 0; --i)
1970 regulator_enable(consumers[i].consumer); 2017 regulator_enable(consumers[i].consumer);
1971 2018
1972 return ret; 2019 return ret;
@@ -2316,7 +2363,7 @@ int regulator_suspend_prepare(suspend_state_t state)
2316 2363
2317 if (ret < 0) { 2364 if (ret < 0) {
2318 printk(KERN_ERR "%s: failed to prepare %s\n", 2365 printk(KERN_ERR "%s: failed to prepare %s\n",
2319 __func__, rdev->desc->name); 2366 __func__, rdev_get_name(rdev));
2320 goto out; 2367 goto out;
2321 } 2368 }
2322 } 2369 }
@@ -2429,12 +2476,7 @@ static int __init regulator_init_complete(void)
2429 ops = rdev->desc->ops; 2476 ops = rdev->desc->ops;
2430 c = rdev->constraints; 2477 c = rdev->constraints;
2431 2478
2432 if (c && c->name) 2479 name = rdev_get_name(rdev);
2433 name = c->name;
2434 else if (rdev->desc->name)
2435 name = rdev->desc->name;
2436 else
2437 name = "regulator";
2438 2480
2439 if (!ops->disable || (c && c->always_on)) 2481 if (!ops->disable || (c && c->always_on))
2440 continue; 2482 continue;
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index aa224d936e0d..f8c4661a7a81 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -331,7 +331,7 @@ static int da9034_get_ldo12_voltage(struct regulator_dev *rdev)
331static int da9034_list_ldo12_voltage(struct regulator_dev *rdev, 331static int da9034_list_ldo12_voltage(struct regulator_dev *rdev,
332 unsigned selector) 332 unsigned selector)
333{ 333{
334 if (selector > ARRAY_SIZE(da9034_ldo12_data)) 334 if (selector >= ARRAY_SIZE(da9034_ldo12_data))
335 return -EINVAL; 335 return -EINVAL;
336 return da9034_ldo12_data[selector] * 1000; 336 return da9034_ldo12_data[selector] * 1000;
337} 337}
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
index 7803a320543b..76d08c282f9c 100644
--- a/drivers/regulator/lp3971.c
+++ b/drivers/regulator/lp3971.c
@@ -446,8 +446,8 @@ static int setup_regulators(struct lp3971 *lp3971,
446 lp3971->rdev[i] = regulator_register(&regulators[id], 446 lp3971->rdev[i] = regulator_register(&regulators[id],
447 lp3971->dev, pdata->regulators[i].initdata, lp3971); 447 lp3971->dev, pdata->regulators[i].initdata, lp3971);
448 448
449 err = IS_ERR(lp3971->rdev[i]); 449 if (IS_ERR(lp3971->rdev[i])) {
450 if (err) { 450 err = PTR_ERR(lp3971->rdev[i]);
451 dev_err(lp3971->dev, "regulator init failed: %d\n", 451 dev_err(lp3971->dev, "regulator init failed: %d\n",
452 err); 452 err);
453 goto error; 453 goto error;
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c
new file mode 100644
index 000000000000..acc2fb7b6087
--- /dev/null
+++ b/drivers/regulator/max8660.c
@@ -0,0 +1,510 @@
1/*
2 * max8660.c -- Voltage regulation for the Maxim 8660/8661
3 *
4 * based on max1586.c and wm8400-regulator.c
5 *
6 * Copyright (C) 2009 Wolfram Sang, Pengutronix e.K.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Some info:
22 *
23 * Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8660-MAX8661.pdf
24 *
25 * This chip is a bit nasty because it is a write-only device. Thus, the driver
26 * uses shadow registers to keep track of its values. The main problem appears
27 * to be the initialization: When Linux boots up, we cannot know if the chip is
28 * in the default state or not, so we would have to pass such information in
29 * platform_data. As this adds a bit of complexity to the driver, this is left
30 * out for now until it is really needed.
31 *
32 * [A|S|M]DTV1 registers are currently not used, but [A|S|M]DTV2.
33 *
34 * If the driver is feature complete, it might be worth to check if one set of
35 * functions for V3-V7 is sufficient. For maximum flexibility during
36 * development, they are separated for now.
37 *
38 */
39
40#include <linux/module.h>
41#include <linux/err.h>
42#include <linux/i2c.h>
43#include <linux/platform_device.h>
44#include <linux/regulator/driver.h>
45#include <linux/regulator/max8660.h>
46
47#define MAX8660_DCDC_MIN_UV 725000
48#define MAX8660_DCDC_MAX_UV 1800000
49#define MAX8660_DCDC_STEP 25000
50#define MAX8660_DCDC_MAX_SEL 0x2b
51
52#define MAX8660_LDO5_MIN_UV 1700000
53#define MAX8660_LDO5_MAX_UV 2000000
54#define MAX8660_LDO5_STEP 25000
55#define MAX8660_LDO5_MAX_SEL 0x0c
56
57#define MAX8660_LDO67_MIN_UV 1800000
58#define MAX8660_LDO67_MAX_UV 3300000
59#define MAX8660_LDO67_STEP 100000
60#define MAX8660_LDO67_MAX_SEL 0x0f
61
62enum {
63 MAX8660_OVER1,
64 MAX8660_OVER2,
65 MAX8660_VCC1,
66 MAX8660_ADTV1,
67 MAX8660_ADTV2,
68 MAX8660_SDTV1,
69 MAX8660_SDTV2,
70 MAX8660_MDTV1,
71 MAX8660_MDTV2,
72 MAX8660_L12VCR,
73 MAX8660_FPWM,
74 MAX8660_N_REGS, /* not a real register */
75};
76
77struct max8660 {
78 struct i2c_client *client;
79 u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */
80 struct regulator_dev *rdev[];
81};
82
83static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val)
84{
85 static const u8 max8660_addresses[MAX8660_N_REGS] =
86 { 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 };
87
88 int ret;
89 u8 reg_val = (max8660->shadow_regs[reg] & mask) | val;
90 dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n",
91 max8660_addresses[reg], reg_val);
92
93 ret = i2c_smbus_write_byte_data(max8660->client,
94 max8660_addresses[reg], reg_val);
95 if (ret == 0)
96 max8660->shadow_regs[reg] = reg_val;
97
98 return ret;
99}
100
101
102/*
103 * DCDC functions
104 */
105
106static int max8660_dcdc_is_enabled(struct regulator_dev *rdev)
107{
108 struct max8660 *max8660 = rdev_get_drvdata(rdev);
109 u8 val = max8660->shadow_regs[MAX8660_OVER1];
110 u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4;
111 return !!(val & mask);
112}
113
114static int max8660_dcdc_enable(struct regulator_dev *rdev)
115{
116 struct max8660 *max8660 = rdev_get_drvdata(rdev);
117 u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4;
118 return max8660_write(max8660, MAX8660_OVER1, 0xff, bit);
119}
120
121static int max8660_dcdc_disable(struct regulator_dev *rdev)
122{
123 struct max8660 *max8660 = rdev_get_drvdata(rdev);
124 u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4;
125 return max8660_write(max8660, MAX8660_OVER1, mask, 0);
126}
127
128static int max8660_dcdc_list(struct regulator_dev *rdev, unsigned selector)
129{
130 if (selector > MAX8660_DCDC_MAX_SEL)
131 return -EINVAL;
132 return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP;
133}
134
135static int max8660_dcdc_get(struct regulator_dev *rdev)
136{
137 struct max8660 *max8660 = rdev_get_drvdata(rdev);
138 u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2;
139 u8 selector = max8660->shadow_regs[reg];
140 return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP;
141}
142
143static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV)
144{
145 struct max8660 *max8660 = rdev_get_drvdata(rdev);
146 u8 reg, selector, bits;
147 int ret;
148
149 if (min_uV < MAX8660_DCDC_MIN_UV || min_uV > MAX8660_DCDC_MAX_UV)
150 return -EINVAL;
151 if (max_uV < MAX8660_DCDC_MIN_UV || max_uV > MAX8660_DCDC_MAX_UV)
152 return -EINVAL;
153
154 selector = (min_uV - (MAX8660_DCDC_MIN_UV - MAX8660_DCDC_STEP + 1))
155 / MAX8660_DCDC_STEP;
156
157 ret = max8660_dcdc_list(rdev, selector);
158 if (ret < 0 || ret > max_uV)
159 return -EINVAL;
160
161 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2;
162 ret = max8660_write(max8660, reg, 0, selector);
163 if (ret)
164 return ret;
165
166 /* Select target voltage register and activate regulation */
167 bits = (rdev_get_id(rdev) == MAX8660_V3) ? 0x03 : 0x30;
168 return max8660_write(max8660, MAX8660_VCC1, 0xff, bits);
169}
170
171static struct regulator_ops max8660_dcdc_ops = {
172 .is_enabled = max8660_dcdc_is_enabled,
173 .list_voltage = max8660_dcdc_list,
174 .set_voltage = max8660_dcdc_set,
175 .get_voltage = max8660_dcdc_get,
176};
177
178
179/*
180 * LDO5 functions
181 */
182
183static int max8660_ldo5_list(struct regulator_dev *rdev, unsigned selector)
184{
185 if (selector > MAX8660_LDO5_MAX_SEL)
186 return -EINVAL;
187 return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP;
188}
189
190static int max8660_ldo5_get(struct regulator_dev *rdev)
191{
192 struct max8660 *max8660 = rdev_get_drvdata(rdev);
193 u8 selector = max8660->shadow_regs[MAX8660_MDTV2];
194
195 return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP;
196}
197
198static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV)
199{
200 struct max8660 *max8660 = rdev_get_drvdata(rdev);
201 u8 selector;
202 int ret;
203
204 if (min_uV < MAX8660_LDO5_MIN_UV || min_uV > MAX8660_LDO5_MAX_UV)
205 return -EINVAL;
206 if (max_uV < MAX8660_LDO5_MIN_UV || max_uV > MAX8660_LDO5_MAX_UV)
207 return -EINVAL;
208
209 selector = (min_uV - (MAX8660_LDO5_MIN_UV - MAX8660_LDO5_STEP + 1))
210 / MAX8660_LDO5_STEP;
211 ret = max8660_ldo5_list(rdev, selector);
212 if (ret < 0 || ret > max_uV)
213 return -EINVAL;
214
215 ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector);
216 if (ret)
217 return ret;
218
219 /* Select target voltage register and activate regulation */
220 return max8660_write(max8660, MAX8660_VCC1, 0xff, 0xc0);
221}
222
223static struct regulator_ops max8660_ldo5_ops = {
224 .list_voltage = max8660_ldo5_list,
225 .set_voltage = max8660_ldo5_set,
226 .get_voltage = max8660_ldo5_get,
227};
228
229
230/*
231 * LDO67 functions
232 */
233
234static int max8660_ldo67_is_enabled(struct regulator_dev *rdev)
235{
236 struct max8660 *max8660 = rdev_get_drvdata(rdev);
237 u8 val = max8660->shadow_regs[MAX8660_OVER2];
238 u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4;
239 return !!(val & mask);
240}
241
242static int max8660_ldo67_enable(struct regulator_dev *rdev)
243{
244 struct max8660 *max8660 = rdev_get_drvdata(rdev);
245 u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4;
246 return max8660_write(max8660, MAX8660_OVER2, 0xff, bit);
247}
248
249static int max8660_ldo67_disable(struct regulator_dev *rdev)
250{
251 struct max8660 *max8660 = rdev_get_drvdata(rdev);
252 u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4;
253 return max8660_write(max8660, MAX8660_OVER2, mask, 0);
254}
255
256static int max8660_ldo67_list(struct regulator_dev *rdev, unsigned selector)
257{
258 if (selector > MAX8660_LDO67_MAX_SEL)
259 return -EINVAL;
260 return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP;
261}
262
263static int max8660_ldo67_get(struct regulator_dev *rdev)
264{
265 struct max8660 *max8660 = rdev_get_drvdata(rdev);
266 u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4;
267 u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf;
268
269 return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP;
270}
271
272static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, int max_uV)
273{
274 struct max8660 *max8660 = rdev_get_drvdata(rdev);
275 u8 selector;
276 int ret;
277
278 if (min_uV < MAX8660_LDO67_MIN_UV || min_uV > MAX8660_LDO67_MAX_UV)
279 return -EINVAL;
280 if (max_uV < MAX8660_LDO67_MIN_UV || max_uV > MAX8660_LDO67_MAX_UV)
281 return -EINVAL;
282
283 selector = (min_uV - (MAX8660_LDO67_MIN_UV - MAX8660_LDO67_STEP + 1))
284 / MAX8660_LDO67_STEP;
285
286 ret = max8660_ldo67_list(rdev, selector);
287 if (ret < 0 || ret > max_uV)
288 return -EINVAL;
289
290 if (rdev_get_id(rdev) == MAX8660_V6)
291 return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector);
292 else
293 return max8660_write(max8660, MAX8660_L12VCR, 0x0f, selector << 4);
294}
295
296static struct regulator_ops max8660_ldo67_ops = {
297 .is_enabled = max8660_ldo67_is_enabled,
298 .enable = max8660_ldo67_enable,
299 .disable = max8660_ldo67_disable,
300 .list_voltage = max8660_ldo67_list,
301 .get_voltage = max8660_ldo67_get,
302 .set_voltage = max8660_ldo67_set,
303};
304
305static struct regulator_desc max8660_reg[] = {
306 {
307 .name = "V3(DCDC)",
308 .id = MAX8660_V3,
309 .ops = &max8660_dcdc_ops,
310 .type = REGULATOR_VOLTAGE,
311 .n_voltages = MAX8660_DCDC_MAX_SEL + 1,
312 .owner = THIS_MODULE,
313 },
314 {
315 .name = "V4(DCDC)",
316 .id = MAX8660_V4,
317 .ops = &max8660_dcdc_ops,
318 .type = REGULATOR_VOLTAGE,
319 .n_voltages = MAX8660_DCDC_MAX_SEL + 1,
320 .owner = THIS_MODULE,
321 },
322 {
323 .name = "V5(LDO)",
324 .id = MAX8660_V5,
325 .ops = &max8660_ldo5_ops,
326 .type = REGULATOR_VOLTAGE,
327 .n_voltages = MAX8660_LDO5_MAX_SEL + 1,
328 .owner = THIS_MODULE,
329 },
330 {
331 .name = "V6(LDO)",
332 .id = MAX8660_V6,
333 .ops = &max8660_ldo67_ops,
334 .type = REGULATOR_VOLTAGE,
335 .n_voltages = MAX8660_LDO67_MAX_SEL + 1,
336 .owner = THIS_MODULE,
337 },
338 {
339 .name = "V7(LDO)",
340 .id = MAX8660_V7,
341 .ops = &max8660_ldo67_ops,
342 .type = REGULATOR_VOLTAGE,
343 .n_voltages = MAX8660_LDO67_MAX_SEL + 1,
344 .owner = THIS_MODULE,
345 },
346};
347
348static int max8660_probe(struct i2c_client *client,
349 const struct i2c_device_id *i2c_id)
350{
351 struct regulator_dev **rdev;
352 struct max8660_platform_data *pdata = client->dev.platform_data;
353 struct max8660 *max8660;
354 int boot_on, i, id, ret = -EINVAL;
355
356 if (pdata->num_subdevs > MAX8660_V_END) {
357 dev_err(&client->dev, "Too much regulators found!\n");
358 goto out;
359 }
360
361 max8660 = kzalloc(sizeof(struct max8660) +
362 sizeof(struct regulator_dev *) * MAX8660_V_END,
363 GFP_KERNEL);
364 if (!max8660) {
365 ret = -ENOMEM;
366 goto out;
367 }
368
369 max8660->client = client;
370 rdev = max8660->rdev;
371
372 if (pdata->en34_is_high) {
373 /* Simulate always on */
374 max8660->shadow_regs[MAX8660_OVER1] = 5;
375 } else {
376 /* Otherwise devices can be toggled via software */
377 max8660_dcdc_ops.enable = max8660_dcdc_enable;
378 max8660_dcdc_ops.disable = max8660_dcdc_disable;
379 }
380
381 /*
382 * First, set up shadow registers to prevent glitches. As some
383 * registers are shared between regulators, everything must be properly
384 * set up for all regulators in advance.
385 */
386 max8660->shadow_regs[MAX8660_ADTV1] =
387 max8660->shadow_regs[MAX8660_ADTV2] =
388 max8660->shadow_regs[MAX8660_SDTV1] =
389 max8660->shadow_regs[MAX8660_SDTV2] = 0x1b;
390 max8660->shadow_regs[MAX8660_MDTV1] =
391 max8660->shadow_regs[MAX8660_MDTV2] = 0x04;
392
393 for (i = 0; i < pdata->num_subdevs; i++) {
394
395 if (!pdata->subdevs[i].platform_data)
396 goto err_free;
397
398 boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
399
400 switch (pdata->subdevs[i].id) {
401 case MAX8660_V3:
402 if (boot_on)
403 max8660->shadow_regs[MAX8660_OVER1] |= 1;
404 break;
405
406 case MAX8660_V4:
407 if (boot_on)
408 max8660->shadow_regs[MAX8660_OVER1] |= 4;
409 break;
410
411 case MAX8660_V5:
412 break;
413
414 case MAX8660_V6:
415 if (boot_on)
416 max8660->shadow_regs[MAX8660_OVER2] |= 2;
417 break;
418
419 case MAX8660_V7:
420 if (!strcmp(i2c_id->name, "max8661")) {
421 dev_err(&client->dev, "Regulator not on this chip!\n");
422 goto err_free;
423 }
424
425 if (boot_on)
426 max8660->shadow_regs[MAX8660_OVER2] |= 4;
427 break;
428
429 default:
430 dev_err(&client->dev, "invalid regulator %s\n",
431 pdata->subdevs[i].name);
432 goto err_free;
433 }
434 }
435
436 /* Finally register devices */
437 for (i = 0; i < pdata->num_subdevs; i++) {
438
439 id = pdata->subdevs[i].id;
440
441 rdev[i] = regulator_register(&max8660_reg[id], &client->dev,
442 pdata->subdevs[i].platform_data,
443 max8660);
444 if (IS_ERR(rdev[i])) {
445 ret = PTR_ERR(rdev[i]);
446 dev_err(&client->dev, "failed to register %s\n",
447 max8660_reg[id].name);
448 goto err_unregister;
449 }
450 }
451
452 i2c_set_clientdata(client, rdev);
453 dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n");
454 return 0;
455
456err_unregister:
457 while (--i >= 0)
458 regulator_unregister(rdev[i]);
459err_free:
460 kfree(max8660);
461out:
462 return ret;
463}
464
465static int max8660_remove(struct i2c_client *client)
466{
467 struct regulator_dev **rdev = i2c_get_clientdata(client);
468 int i;
469
470 for (i = 0; i < MAX8660_V_END; i++)
471 if (rdev[i])
472 regulator_unregister(rdev[i]);
473 kfree(rdev);
474 i2c_set_clientdata(client, NULL);
475
476 return 0;
477}
478
479static const struct i2c_device_id max8660_id[] = {
480 { "max8660", 0 },
481 { "max8661", 0 },
482 { }
483};
484MODULE_DEVICE_TABLE(i2c, max8660_id);
485
486static struct i2c_driver max8660_driver = {
487 .probe = max8660_probe,
488 .remove = max8660_remove,
489 .driver = {
490 .name = "max8660",
491 },
492 .id_table = max8660_id,
493};
494
495static int __init max8660_init(void)
496{
497 return i2c_add_driver(&max8660_driver);
498}
499subsys_initcall(max8660_init);
500
501static void __exit max8660_exit(void)
502{
503 i2c_del_driver(&max8660_driver);
504}
505module_exit(max8660_exit);
506
507/* Module information */
508MODULE_DESCRIPTION("MAXIM 8660/8661 voltage regulator driver");
509MODULE_AUTHOR("Wolfram Sang");
510MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
new file mode 100644
index 000000000000..39c495300045
--- /dev/null
+++ b/drivers/regulator/mc13783-regulator.c
@@ -0,0 +1,245 @@
1/*
2 * Regulator Driver for Freescale MC13783 PMIC
3 *
4 * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/mfd/mc13783.h>
12#include <linux/regulator/machine.h>
13#include <linux/regulator/driver.h>
14#include <linux/platform_device.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/err.h>
18
19#define MC13783_REG_SWITCHERS4 28
20#define MC13783_REG_SWITCHERS4_PLLEN (1 << 18)
21
22#define MC13783_REG_SWITCHERS5 29
23#define MC13783_REG_SWITCHERS5_SW3EN (1 << 20)
24
25#define MC13783_REG_REGULATORMODE0 32
26#define MC13783_REG_REGULATORMODE0_VAUDIOEN (1 << 0)
27#define MC13783_REG_REGULATORMODE0_VIOHIEN (1 << 3)
28#define MC13783_REG_REGULATORMODE0_VIOLOEN (1 << 6)
29#define MC13783_REG_REGULATORMODE0_VDIGEN (1 << 9)
30#define MC13783_REG_REGULATORMODE0_VGENEN (1 << 12)
31#define MC13783_REG_REGULATORMODE0_VRFDIGEN (1 << 15)
32#define MC13783_REG_REGULATORMODE0_VRFREFEN (1 << 18)
33#define MC13783_REG_REGULATORMODE0_VRFCPEN (1 << 21)
34
35#define MC13783_REG_REGULATORMODE1 33
36#define MC13783_REG_REGULATORMODE1_VSIMEN (1 << 0)
37#define MC13783_REG_REGULATORMODE1_VESIMEN (1 << 3)
38#define MC13783_REG_REGULATORMODE1_VCAMEN (1 << 6)
39#define MC13783_REG_REGULATORMODE1_VRFBGEN (1 << 9)
40#define MC13783_REG_REGULATORMODE1_VVIBEN (1 << 11)
41#define MC13783_REG_REGULATORMODE1_VRF1EN (1 << 12)
42#define MC13783_REG_REGULATORMODE1_VRF2EN (1 << 15)
43#define MC13783_REG_REGULATORMODE1_VMMC1EN (1 << 18)
44#define MC13783_REG_REGULATORMODE1_VMMC2EN (1 << 21)
45
46#define MC13783_REG_POWERMISC 34
47#define MC13783_REG_POWERMISC_GPO1EN (1 << 6)
48#define MC13783_REG_POWERMISC_GPO2EN (1 << 8)
49#define MC13783_REG_POWERMISC_GPO3EN (1 << 10)
50#define MC13783_REG_POWERMISC_GPO4EN (1 << 12)
51
52struct mc13783_regulator {
53 struct regulator_desc desc;
54 int reg;
55 int enable_bit;
56};
57
58static struct regulator_ops mc13783_regulator_ops;
59
60#define MC13783_DEFINE(prefix, _name, _reg) \
61 [MC13783_ ## prefix ## _ ## _name] = { \
62 .desc = { \
63 .name = #prefix "_" #_name, \
64 .ops = &mc13783_regulator_ops, \
65 .type = REGULATOR_VOLTAGE, \
66 .id = MC13783_ ## prefix ## _ ## _name, \
67 .owner = THIS_MODULE, \
68 }, \
69 .reg = MC13783_REG_ ## _reg, \
70 .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \
71 }
72
73#define MC13783_DEFINE_SW(_name, _reg) MC13783_DEFINE(SW, _name, _reg)
74#define MC13783_DEFINE_REGU(_name, _reg) MC13783_DEFINE(REGU, _name, _reg)
75
76static struct mc13783_regulator mc13783_regulators[] = {
77 MC13783_DEFINE_SW(SW3, SWITCHERS5),
78 MC13783_DEFINE_SW(PLL, SWITCHERS4),
79
80 MC13783_DEFINE_REGU(VAUDIO, REGULATORMODE0),
81 MC13783_DEFINE_REGU(VIOHI, REGULATORMODE0),
82 MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0),
83 MC13783_DEFINE_REGU(VDIG, REGULATORMODE0),
84 MC13783_DEFINE_REGU(VGEN, REGULATORMODE0),
85 MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0),
86 MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0),
87 MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0),
88 MC13783_DEFINE_REGU(VSIM, REGULATORMODE1),
89 MC13783_DEFINE_REGU(VESIM, REGULATORMODE1),
90 MC13783_DEFINE_REGU(VCAM, REGULATORMODE1),
91 MC13783_DEFINE_REGU(VRFBG, REGULATORMODE1),
92 MC13783_DEFINE_REGU(VVIB, REGULATORMODE1),
93 MC13783_DEFINE_REGU(VRF1, REGULATORMODE1),
94 MC13783_DEFINE_REGU(VRF2, REGULATORMODE1),
95 MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1),
96 MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1),
97 MC13783_DEFINE_REGU(GPO1, POWERMISC),
98 MC13783_DEFINE_REGU(GPO2, POWERMISC),
99 MC13783_DEFINE_REGU(GPO3, POWERMISC),
100 MC13783_DEFINE_REGU(GPO4, POWERMISC),
101};
102
103struct mc13783_regulator_priv {
104 struct mc13783 *mc13783;
105 struct regulator_dev *regulators[];
106};
107
108static int mc13783_regulator_enable(struct regulator_dev *rdev)
109{
110 struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
111 int id = rdev_get_id(rdev);
112 int ret;
113
114 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
115
116 mc13783_lock(priv->mc13783);
117 ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg,
118 mc13783_regulators[id].enable_bit,
119 mc13783_regulators[id].enable_bit);
120 mc13783_unlock(priv->mc13783);
121
122 return ret;
123}
124
125static int mc13783_regulator_disable(struct regulator_dev *rdev)
126{
127 struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
128 int id = rdev_get_id(rdev);
129 int ret;
130
131 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
132
133 mc13783_lock(priv->mc13783);
134 ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg,
135 mc13783_regulators[id].enable_bit, 0);
136 mc13783_unlock(priv->mc13783);
137
138 return ret;
139}
140
141static int mc13783_regulator_is_enabled(struct regulator_dev *rdev)
142{
143 struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
144 int ret, id = rdev_get_id(rdev);
145 unsigned int val;
146
147 mc13783_lock(priv->mc13783);
148 ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
149 mc13783_unlock(priv->mc13783);
150
151 if (ret)
152 return ret;
153
154 return (val & mc13783_regulators[id].enable_bit) != 0;
155}
156
157static struct regulator_ops mc13783_regulator_ops = {
158 .enable = mc13783_regulator_enable,
159 .disable = mc13783_regulator_disable,
160 .is_enabled = mc13783_regulator_is_enabled,
161};
162
163static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
164{
165 struct mc13783_regulator_priv *priv;
166 struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent);
167 struct mc13783_regulator_platform_data *pdata =
168 dev_get_platdata(&pdev->dev);
169 struct mc13783_regulator_init_data *init_data;
170 int i, ret;
171
172 dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id);
173
174 priv = kzalloc(sizeof(*priv) +
175 pdata->num_regulators * sizeof(priv->regulators[0]),
176 GFP_KERNEL);
177 if (!priv)
178 return -ENOMEM;
179
180 priv->mc13783 = mc13783;
181
182 for (i = 0; i < pdata->num_regulators; i++) {
183 init_data = &pdata->regulators[i];
184 priv->regulators[i] = regulator_register(
185 &mc13783_regulators[init_data->id].desc,
186 &pdev->dev, init_data->init_data, priv);
187
188 if (IS_ERR(priv->regulators[i])) {
189 dev_err(&pdev->dev, "failed to register regulator %s\n",
190 mc13783_regulators[i].desc.name);
191 ret = PTR_ERR(priv->regulators[i]);
192 goto err;
193 }
194 }
195
196 platform_set_drvdata(pdev, priv);
197
198 return 0;
199err:
200 while (--i >= 0)
201 regulator_unregister(priv->regulators[i]);
202
203 kfree(priv);
204
205 return ret;
206}
207
208static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
209{
210 struct mc13783_regulator_priv *priv = platform_get_drvdata(pdev);
211 struct mc13783_regulator_platform_data *pdata =
212 dev_get_platdata(&pdev->dev);
213 int i;
214
215 for (i = 0; i < pdata->num_regulators; i++)
216 regulator_unregister(priv->regulators[i]);
217
218 return 0;
219}
220
221static struct platform_driver mc13783_regulator_driver = {
222 .driver = {
223 .name = "mc13783-regulator",
224 .owner = THIS_MODULE,
225 },
226 .remove = __devexit_p(mc13783_regulator_remove),
227 .probe = mc13783_regulator_probe,
228};
229
230static int __init mc13783_regulator_init(void)
231{
232 return platform_driver_register(&mc13783_regulator_driver);
233}
234subsys_initcall(mc13783_regulator_init);
235
236static void __exit mc13783_regulator_exit(void)
237{
238 platform_driver_unregister(&mc13783_regulator_driver);
239}
240module_exit(mc13783_regulator_exit);
241
242MODULE_LICENSE("GPL v2");
243MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
244MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC");
245MODULE_ALIAS("platform:mc13783-regulator");
diff --git a/drivers/regulator/mc13783.c b/drivers/regulator/mc13783.c
deleted file mode 100644
index 710211f67449..000000000000
--- a/drivers/regulator/mc13783.c
+++ /dev/null
@@ -1,410 +0,0 @@
1/*
2 * Regulator Driver for Freescale MC13783 PMIC
3 *
4 * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/mfd/mc13783-private.h>
12#include <linux/regulator/machine.h>
13#include <linux/regulator/driver.h>
14#include <linux/platform_device.h>
15#include <linux/mfd/mc13783.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/err.h>
19
20struct mc13783_regulator {
21 struct regulator_desc desc;
22 int reg;
23 int enable_bit;
24};
25
26static struct regulator_ops mc13783_regulator_ops;
27
28static struct mc13783_regulator mc13783_regulators[] = {
29 [MC13783_SW_SW3] = {
30 .desc = {
31 .name = "SW_SW3",
32 .ops = &mc13783_regulator_ops,
33 .type = REGULATOR_VOLTAGE,
34 .id = MC13783_SW_SW3,
35 .owner = THIS_MODULE,
36 },
37 .reg = MC13783_REG_SWITCHERS_5,
38 .enable_bit = MC13783_SWCTRL_SW3_EN,
39 },
40 [MC13783_SW_PLL] = {
41 .desc = {
42 .name = "SW_PLL",
43 .ops = &mc13783_regulator_ops,
44 .type = REGULATOR_VOLTAGE,
45 .id = MC13783_SW_PLL,
46 .owner = THIS_MODULE,
47 },
48 .reg = MC13783_REG_SWITCHERS_4,
49 .enable_bit = MC13783_SWCTRL_PLL_EN,
50 },
51 [MC13783_REGU_VAUDIO] = {
52 .desc = {
53 .name = "REGU_VAUDIO",
54 .ops = &mc13783_regulator_ops,
55 .type = REGULATOR_VOLTAGE,
56 .id = MC13783_REGU_VAUDIO,
57 .owner = THIS_MODULE,
58 },
59 .reg = MC13783_REG_REGULATOR_MODE_0,
60 .enable_bit = MC13783_REGCTRL_VAUDIO_EN,
61 },
62 [MC13783_REGU_VIOHI] = {
63 .desc = {
64 .name = "REGU_VIOHI",
65 .ops = &mc13783_regulator_ops,
66 .type = REGULATOR_VOLTAGE,
67 .id = MC13783_REGU_VIOHI,
68 .owner = THIS_MODULE,
69 },
70 .reg = MC13783_REG_REGULATOR_MODE_0,
71 .enable_bit = MC13783_REGCTRL_VIOHI_EN,
72 },
73 [MC13783_REGU_VIOLO] = {
74 .desc = {
75 .name = "REGU_VIOLO",
76 .ops = &mc13783_regulator_ops,
77 .type = REGULATOR_VOLTAGE,
78 .id = MC13783_REGU_VIOLO,
79 .owner = THIS_MODULE,
80 },
81 .reg = MC13783_REG_REGULATOR_MODE_0,
82 .enable_bit = MC13783_REGCTRL_VIOLO_EN,
83 },
84 [MC13783_REGU_VDIG] = {
85 .desc = {
86 .name = "REGU_VDIG",
87 .ops = &mc13783_regulator_ops,
88 .type = REGULATOR_VOLTAGE,
89 .id = MC13783_REGU_VDIG,
90 .owner = THIS_MODULE,
91 },
92 .reg = MC13783_REG_REGULATOR_MODE_0,
93 .enable_bit = MC13783_REGCTRL_VDIG_EN,
94 },
95 [MC13783_REGU_VGEN] = {
96 .desc = {
97 .name = "REGU_VGEN",
98 .ops = &mc13783_regulator_ops,
99 .type = REGULATOR_VOLTAGE,
100 .id = MC13783_REGU_VGEN,
101 .owner = THIS_MODULE,
102 },
103 .reg = MC13783_REG_REGULATOR_MODE_0,
104 .enable_bit = MC13783_REGCTRL_VGEN_EN,
105 },
106 [MC13783_REGU_VRFDIG] = {
107 .desc = {
108 .name = "REGU_VRFDIG",
109 .ops = &mc13783_regulator_ops,
110 .type = REGULATOR_VOLTAGE,
111 .id = MC13783_REGU_VRFDIG,
112 .owner = THIS_MODULE,
113 },
114 .reg = MC13783_REG_REGULATOR_MODE_0,
115 .enable_bit = MC13783_REGCTRL_VRFDIG_EN,
116 },
117 [MC13783_REGU_VRFREF] = {
118 .desc = {
119 .name = "REGU_VRFREF",
120 .ops = &mc13783_regulator_ops,
121 .type = REGULATOR_VOLTAGE,
122 .id = MC13783_REGU_VRFREF,
123 .owner = THIS_MODULE,
124 },
125 .reg = MC13783_REG_REGULATOR_MODE_0,
126 .enable_bit = MC13783_REGCTRL_VRFREF_EN,
127 },
128 [MC13783_REGU_VRFCP] = {
129 .desc = {
130 .name = "REGU_VRFCP",
131 .ops = &mc13783_regulator_ops,
132 .type = REGULATOR_VOLTAGE,
133 .id = MC13783_REGU_VRFCP,
134 .owner = THIS_MODULE,
135 },
136 .reg = MC13783_REG_REGULATOR_MODE_0,
137 .enable_bit = MC13783_REGCTRL_VRFCP_EN,
138 },
139 [MC13783_REGU_VSIM] = {
140 .desc = {
141 .name = "REGU_VSIM",
142 .ops = &mc13783_regulator_ops,
143 .type = REGULATOR_VOLTAGE,
144 .id = MC13783_REGU_VSIM,
145 .owner = THIS_MODULE,
146 },
147 .reg = MC13783_REG_REGULATOR_MODE_1,
148 .enable_bit = MC13783_REGCTRL_VSIM_EN,
149 },
150 [MC13783_REGU_VESIM] = {
151 .desc = {
152 .name = "REGU_VESIM",
153 .ops = &mc13783_regulator_ops,
154 .type = REGULATOR_VOLTAGE,
155 .id = MC13783_REGU_VESIM,
156 .owner = THIS_MODULE,
157 },
158 .reg = MC13783_REG_REGULATOR_MODE_1,
159 .enable_bit = MC13783_REGCTRL_VESIM_EN,
160 },
161 [MC13783_REGU_VCAM] = {
162 .desc = {
163 .name = "REGU_VCAM",
164 .ops = &mc13783_regulator_ops,
165 .type = REGULATOR_VOLTAGE,
166 .id = MC13783_REGU_VCAM,
167 .owner = THIS_MODULE,
168 },
169 .reg = MC13783_REG_REGULATOR_MODE_1,
170 .enable_bit = MC13783_REGCTRL_VCAM_EN,
171 },
172 [MC13783_REGU_VRFBG] = {
173 .desc = {
174 .name = "REGU_VRFBG",
175 .ops = &mc13783_regulator_ops,
176 .type = REGULATOR_VOLTAGE,
177 .id = MC13783_REGU_VRFBG,
178 .owner = THIS_MODULE,
179 },
180 .reg = MC13783_REG_REGULATOR_MODE_1,
181 .enable_bit = MC13783_REGCTRL_VRFBG_EN,
182 },
183 [MC13783_REGU_VVIB] = {
184 .desc = {
185 .name = "REGU_VVIB",
186 .ops = &mc13783_regulator_ops,
187 .type = REGULATOR_VOLTAGE,
188 .id = MC13783_REGU_VVIB,
189 .owner = THIS_MODULE,
190 },
191 .reg = MC13783_REG_REGULATOR_MODE_1,
192 .enable_bit = MC13783_REGCTRL_VVIB_EN,
193 },
194 [MC13783_REGU_VRF1] = {
195 .desc = {
196 .name = "REGU_VRF1",
197 .ops = &mc13783_regulator_ops,
198 .type = REGULATOR_VOLTAGE,
199 .id = MC13783_REGU_VRF1,
200 .owner = THIS_MODULE,
201 },
202 .reg = MC13783_REG_REGULATOR_MODE_1,
203 .enable_bit = MC13783_REGCTRL_VRF1_EN,
204 },
205 [MC13783_REGU_VRF2] = {
206 .desc = {
207 .name = "REGU_VRF2",
208 .ops = &mc13783_regulator_ops,
209 .type = REGULATOR_VOLTAGE,
210 .id = MC13783_REGU_VRF2,
211 .owner = THIS_MODULE,
212 },
213 .reg = MC13783_REG_REGULATOR_MODE_1,
214 .enable_bit = MC13783_REGCTRL_VRF2_EN,
215 },
216 [MC13783_REGU_VMMC1] = {
217 .desc = {
218 .name = "REGU_VMMC1",
219 .ops = &mc13783_regulator_ops,
220 .type = REGULATOR_VOLTAGE,
221 .id = MC13783_REGU_VMMC1,
222 .owner = THIS_MODULE,
223 },
224 .reg = MC13783_REG_REGULATOR_MODE_1,
225 .enable_bit = MC13783_REGCTRL_VMMC1_EN,
226 },
227 [MC13783_REGU_VMMC2] = {
228 .desc = {
229 .name = "REGU_VMMC2",
230 .ops = &mc13783_regulator_ops,
231 .type = REGULATOR_VOLTAGE,
232 .id = MC13783_REGU_VMMC2,
233 .owner = THIS_MODULE,
234 },
235 .reg = MC13783_REG_REGULATOR_MODE_1,
236 .enable_bit = MC13783_REGCTRL_VMMC2_EN,
237 },
238 [MC13783_REGU_GPO1] = {
239 .desc = {
240 .name = "REGU_GPO1",
241 .ops = &mc13783_regulator_ops,
242 .type = REGULATOR_VOLTAGE,
243 .id = MC13783_REGU_GPO1,
244 .owner = THIS_MODULE,
245 },
246 .reg = MC13783_REG_POWER_MISCELLANEOUS,
247 .enable_bit = MC13783_REGCTRL_GPO1_EN,
248 },
249 [MC13783_REGU_GPO2] = {
250 .desc = {
251 .name = "REGU_GPO2",
252 .ops = &mc13783_regulator_ops,
253 .type = REGULATOR_VOLTAGE,
254 .id = MC13783_REGU_GPO2,
255 .owner = THIS_MODULE,
256 },
257 .reg = MC13783_REG_POWER_MISCELLANEOUS,
258 .enable_bit = MC13783_REGCTRL_GPO2_EN,
259 },
260 [MC13783_REGU_GPO3] = {
261 .desc = {
262 .name = "REGU_GPO3",
263 .ops = &mc13783_regulator_ops,
264 .type = REGULATOR_VOLTAGE,
265 .id = MC13783_REGU_GPO3,
266 .owner = THIS_MODULE,
267 },
268 .reg = MC13783_REG_POWER_MISCELLANEOUS,
269 .enable_bit = MC13783_REGCTRL_GPO3_EN,
270 },
271 [MC13783_REGU_GPO4] = {
272 .desc = {
273 .name = "REGU_GPO4",
274 .ops = &mc13783_regulator_ops,
275 .type = REGULATOR_VOLTAGE,
276 .id = MC13783_REGU_GPO4,
277 .owner = THIS_MODULE,
278 },
279 .reg = MC13783_REG_POWER_MISCELLANEOUS,
280 .enable_bit = MC13783_REGCTRL_GPO4_EN,
281 },
282};
283
284struct mc13783_priv {
285 struct regulator_desc desc[ARRAY_SIZE(mc13783_regulators)];
286 struct mc13783 *mc13783;
287 struct regulator_dev *regulators[0];
288};
289
290static int mc13783_enable(struct regulator_dev *rdev)
291{
292 struct mc13783_priv *priv = rdev_get_drvdata(rdev);
293 int id = rdev_get_id(rdev);
294
295 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
296
297 return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
298 mc13783_regulators[id].enable_bit,
299 mc13783_regulators[id].enable_bit);
300}
301
302static int mc13783_disable(struct regulator_dev *rdev)
303{
304 struct mc13783_priv *priv = rdev_get_drvdata(rdev);
305 int id = rdev_get_id(rdev);
306
307 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
308
309 return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
310 mc13783_regulators[id].enable_bit, 0);
311}
312
313static int mc13783_is_enabled(struct regulator_dev *rdev)
314{
315 struct mc13783_priv *priv = rdev_get_drvdata(rdev);
316 int ret, id = rdev_get_id(rdev);
317 unsigned int val;
318
319 ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
320 if (ret)
321 return ret;
322
323 return (val & mc13783_regulators[id].enable_bit) != 0;
324}
325
326static struct regulator_ops mc13783_regulator_ops = {
327 .enable = mc13783_enable,
328 .disable = mc13783_disable,
329 .is_enabled = mc13783_is_enabled,
330};
331
332static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
333{
334 struct mc13783_priv *priv;
335 struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent);
336 struct mc13783_regulator_init_data *init_data;
337 int i, ret;
338
339 dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id);
340
341 priv = kzalloc(sizeof(*priv) + mc13783->num_regulators * sizeof(void *),
342 GFP_KERNEL);
343 if (!priv)
344 return -ENOMEM;
345
346 priv->mc13783 = mc13783;
347
348 for (i = 0; i < mc13783->num_regulators; i++) {
349 init_data = &mc13783->regulators[i];
350 priv->regulators[i] = regulator_register(
351 &mc13783_regulators[init_data->id].desc,
352 &pdev->dev, init_data->init_data, priv);
353
354 if (IS_ERR(priv->regulators[i])) {
355 dev_err(&pdev->dev, "failed to register regulator %s\n",
356 mc13783_regulators[i].desc.name);
357 ret = PTR_ERR(priv->regulators[i]);
358 goto err;
359 }
360 }
361
362 platform_set_drvdata(pdev, priv);
363
364 return 0;
365err:
366 while (--i >= 0)
367 regulator_unregister(priv->regulators[i]);
368
369 kfree(priv);
370
371 return ret;
372}
373
374static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
375{
376 struct mc13783_priv *priv = platform_get_drvdata(pdev);
377 struct mc13783 *mc13783 = priv->mc13783;
378 int i;
379
380 for (i = 0; i < mc13783->num_regulators; i++)
381 regulator_unregister(priv->regulators[i]);
382
383 return 0;
384}
385
386static struct platform_driver mc13783_regulator_driver = {
387 .driver = {
388 .name = "mc13783-regulator",
389 .owner = THIS_MODULE,
390 },
391 .remove = __devexit_p(mc13783_regulator_remove),
392};
393
394static int __init mc13783_regulator_init(void)
395{
396 return platform_driver_probe(&mc13783_regulator_driver,
397 mc13783_regulator_probe);
398}
399subsys_initcall(mc13783_regulator_init);
400
401static void __exit mc13783_regulator_exit(void)
402{
403 platform_driver_unregister(&mc13783_regulator_driver);
404}
405module_exit(mc13783_regulator_exit);
406
407MODULE_LICENSE("GPL");
408MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
409MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC");
410MODULE_ALIAS("platform:mc13783-regulator");
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 7ea1c3a31081..7e674859bd59 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -12,6 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/delay.h>
15#include <linux/platform_device.h> 16#include <linux/platform_device.h>
16#include <linux/regulator/driver.h> 17#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h> 18#include <linux/regulator/machine.h>
@@ -40,6 +41,12 @@ struct twlreg_info {
40 u8 table_len; 41 u8 table_len;
41 const u16 *table; 42 const u16 *table;
42 43
44 /* regulator specific turn-on delay */
45 u16 delay;
46
47 /* State REMAP default configuration */
48 u8 remap;
49
43 /* chip constraints on regulator behavior */ 50 /* chip constraints on regulator behavior */
44 u16 min_mV; 51 u16 min_mV;
45 52
@@ -128,6 +135,7 @@ static int twlreg_enable(struct regulator_dev *rdev)
128{ 135{
129 struct twlreg_info *info = rdev_get_drvdata(rdev); 136 struct twlreg_info *info = rdev_get_drvdata(rdev);
130 int grp; 137 int grp;
138 int ret;
131 139
132 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); 140 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
133 if (grp < 0) 141 if (grp < 0)
@@ -138,7 +146,11 @@ static int twlreg_enable(struct regulator_dev *rdev)
138 else 146 else
139 grp |= P1_GRP_6030; 147 grp |= P1_GRP_6030;
140 148
141 return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); 149 ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
150
151 udelay(info->delay);
152
153 return ret;
142} 154}
143 155
144static int twlreg_disable(struct regulator_dev *rdev) 156static int twlreg_disable(struct regulator_dev *rdev)
@@ -151,9 +163,9 @@ static int twlreg_disable(struct regulator_dev *rdev)
151 return grp; 163 return grp;
152 164
153 if (twl_class_is_4030()) 165 if (twl_class_is_4030())
154 grp &= ~P1_GRP_4030; 166 grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
155 else 167 else
156 grp &= ~P1_GRP_6030; 168 grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030);
157 169
158 return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); 170 return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
159} 171}
@@ -294,6 +306,18 @@ static const u16 VSIM_VSEL_table[] = {
294static const u16 VDAC_VSEL_table[] = { 306static const u16 VDAC_VSEL_table[] = {
295 1200, 1300, 1800, 1800, 307 1200, 1300, 1800, 1800,
296}; 308};
309static const u16 VDD1_VSEL_table[] = {
310 800, 1450,
311};
312static const u16 VDD2_VSEL_table[] = {
313 800, 1450, 1500,
314};
315static const u16 VIO_VSEL_table[] = {
316 1800, 1850,
317};
318static const u16 VINTANA2_VSEL_table[] = {
319 2500, 2750,
320};
297static const u16 VAUX1_6030_VSEL_table[] = { 321static const u16 VAUX1_6030_VSEL_table[] = {
298 1000, 1300, 1800, 2500, 322 1000, 1300, 1800, 2500,
299 2800, 2900, 3000, 3000, 323 2800, 2900, 3000, 3000,
@@ -414,20 +438,30 @@ static struct regulator_ops twlfixed_ops = {
414 438
415/*----------------------------------------------------------------------*/ 439/*----------------------------------------------------------------------*/
416 440
417#define TWL4030_ADJUSTABLE_LDO(label, offset, num) \ 441#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \
418 TWL_ADJUSTABLE_LDO(label, offset, num, TWL4030) 442 TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \
419#define TWL4030_FIXED_LDO(label, offset, mVolts, num) \ 443 remap_conf, TWL4030)
420 TWL_FIXED_LDO(label, offset, mVolts, num, TWL4030) 444#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
421#define TWL6030_ADJUSTABLE_LDO(label, offset, num) \ 445 remap_conf) \
422 TWL_ADJUSTABLE_LDO(label, offset, num, TWL6030) 446 TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
423#define TWL6030_FIXED_LDO(label, offset, mVolts, num) \ 447 remap_conf, TWL4030)
424 TWL_FIXED_LDO(label, offset, mVolts, num, TWL6030) 448#define TWL6030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \
425 449 remap_conf) \
426#define TWL_ADJUSTABLE_LDO(label, offset, num, family) { \ 450 TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \
451 remap_conf, TWL6030)
452#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
453 remap_conf) \
454 TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
455 remap_conf, TWL6030)
456
457#define TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf, \
458 family) { \
427 .base = offset, \ 459 .base = offset, \
428 .id = num, \ 460 .id = num, \
429 .table_len = ARRAY_SIZE(label##_VSEL_table), \ 461 .table_len = ARRAY_SIZE(label##_VSEL_table), \
430 .table = label##_VSEL_table, \ 462 .table = label##_VSEL_table, \
463 .delay = turnon_delay, \
464 .remap = remap_conf, \
431 .desc = { \ 465 .desc = { \
432 .name = #label, \ 466 .name = #label, \
433 .id = family##_REG_##label, \ 467 .id = family##_REG_##label, \
@@ -438,10 +472,13 @@ static struct regulator_ops twlfixed_ops = {
438 }, \ 472 }, \
439 } 473 }
440 474
441#define TWL_FIXED_LDO(label, offset, mVolts, num, family) { \ 475#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \
476 family) { \
442 .base = offset, \ 477 .base = offset, \
443 .id = num, \ 478 .id = num, \
444 .min_mV = mVolts, \ 479 .min_mV = mVolts, \
480 .delay = turnon_delay, \
481 .remap = remap_conf, \
445 .desc = { \ 482 .desc = { \
446 .name = #label, \ 483 .name = #label, \
447 .id = family##_REG_##label, \ 484 .id = family##_REG_##label, \
@@ -457,43 +494,41 @@ static struct regulator_ops twlfixed_ops = {
457 * software control over them after boot. 494 * software control over them after boot.
458 */ 495 */
459static struct twlreg_info twl_regs[] = { 496static struct twlreg_info twl_regs[] = {
460 TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1), 497 TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08),
461 TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2), 498 TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08),
462 TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2), 499 TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08),
463 TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3), 500 TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08),
464 TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4), 501 TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08),
465 TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5), 502 TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08),
466 TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6), 503 TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08),
467 /* 504 TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00),
468 TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7), 505 TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08),
469 */ 506 TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00),
470 TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8), 507 TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08),
471 TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9), 508 TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08),
472 TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10), 509 TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08),
473 /* 510 TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08),
474 TWL4030_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11), 511 TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08),
475 TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12), 512 TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15, 1000, 0x08),
476 TWL4030_ADJUSTABLE_LDO(VINTDIG, 0x47, 13), 513 TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16, 1000, 0x08),
477 TWL4030_SMPS(VIO, 0x4b, 14), 514 TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08),
478 TWL4030_SMPS(VDD1, 0x55, 15), 515 TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08),
479 TWL4030_SMPS(VDD2, 0x63, 16), 516 TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08),
480 */
481 TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
482 TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
483 TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
484 /* VUSBCP is managed *only* by the USB subchip */ 517 /* VUSBCP is managed *only* by the USB subchip */
485 518
486 /* 6030 REG with base as PMC Slave Misc : 0x0030 */ 519 /* 6030 REG with base as PMC Slave Misc : 0x0030 */
487 TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1), 520 /* Turnon-delay and remap configuration values for 6030 are not
488 TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2), 521 verified since the specification is not public */
489 TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3), 522 TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x08),
490 TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4), 523 TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x08),
491 TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5), 524 TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x08),
492 TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7), 525 TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x08),
493 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15), 526 TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x08),
494 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16), 527 TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x08),
495 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17), 528 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x08),
496 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18) 529 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x08),
530 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x08),
531 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x08)
497}; 532};
498 533
499static int twlreg_probe(struct platform_device *pdev) 534static int twlreg_probe(struct platform_device *pdev)
@@ -525,6 +560,19 @@ static int twlreg_probe(struct platform_device *pdev)
525 c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE 560 c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
526 | REGULATOR_CHANGE_MODE 561 | REGULATOR_CHANGE_MODE
527 | REGULATOR_CHANGE_STATUS; 562 | REGULATOR_CHANGE_STATUS;
563 switch (pdev->id) {
564 case TWL4030_REG_VIO:
565 case TWL4030_REG_VDD1:
566 case TWL4030_REG_VDD2:
567 case TWL4030_REG_VPLL1:
568 case TWL4030_REG_VINTANA1:
569 case TWL4030_REG_VINTANA2:
570 case TWL4030_REG_VINTDIG:
571 c->always_on = true;
572 break;
573 default:
574 break;
575 }
528 576
529 rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); 577 rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
530 if (IS_ERR(rdev)) { 578 if (IS_ERR(rdev)) {
@@ -534,6 +582,9 @@ static int twlreg_probe(struct platform_device *pdev)
534 } 582 }
535 platform_set_drvdata(pdev, rdev); 583 platform_set_drvdata(pdev, rdev);
536 584
585 twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
586 info->remap);
587
537 /* NOTE: many regulators support short-circuit IRQs (presentable 588 /* NOTE: many regulators support short-circuit IRQs (presentable
538 * as REGULATOR_OVER_CURRENT notifications?) configured via: 589 * as REGULATOR_OVER_CURRENT notifications?) configured via:
539 * - SC_CONFIG 590 * - SC_CONFIG
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 2eefc1a0cf08..0a6577577e8d 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -19,6 +19,8 @@
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/regulator/driver.h> 21#include <linux/regulator/driver.h>
22#include <linux/regulator/machine.h>
23#include <linux/gpio.h>
22 24
23#include <linux/mfd/wm831x/core.h> 25#include <linux/mfd/wm831x/core.h>
24#include <linux/mfd/wm831x/regulator.h> 26#include <linux/mfd/wm831x/regulator.h>
@@ -39,6 +41,7 @@
39#define WM831X_DCDC_CONTROL_2 1 41#define WM831X_DCDC_CONTROL_2 1
40#define WM831X_DCDC_ON_CONFIG 2 42#define WM831X_DCDC_ON_CONFIG 2
41#define WM831X_DCDC_SLEEP_CONTROL 3 43#define WM831X_DCDC_SLEEP_CONTROL 3
44#define WM831X_DCDC_DVS_CONTROL 4
42 45
43/* 46/*
44 * Shared 47 * Shared
@@ -50,6 +53,10 @@ struct wm831x_dcdc {
50 int base; 53 int base;
51 struct wm831x *wm831x; 54 struct wm831x *wm831x;
52 struct regulator_dev *regulator; 55 struct regulator_dev *regulator;
56 int dvs_gpio;
57 int dvs_gpio_state;
58 int on_vsel;
59 int dvs_vsel;
53}; 60};
54 61
55static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev) 62static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
@@ -240,11 +247,9 @@ static int wm831x_buckv_list_voltage(struct regulator_dev *rdev,
240 return -EINVAL; 247 return -EINVAL;
241} 248}
242 249
243static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg, 250static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev,
244 int min_uV, int max_uV) 251 int min_uV, int max_uV)
245{ 252{
246 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
247 struct wm831x *wm831x = dcdc->wm831x;
248 u16 vsel; 253 u16 vsel;
249 254
250 if (min_uV < 600000) 255 if (min_uV < 600000)
@@ -257,39 +262,126 @@ static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg,
257 if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV) 262 if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV)
258 return -EINVAL; 263 return -EINVAL;
259 264
260 return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_VSEL_MASK, vsel); 265 return vsel;
266}
267
268static int wm831x_buckv_select_max_voltage(struct regulator_dev *rdev,
269 int min_uV, int max_uV)
270{
271 u16 vsel;
272
273 if (max_uV < 600000 || max_uV > 1800000)
274 return -EINVAL;
275
276 vsel = ((max_uV - 600000) / 12500) + 8;
277
278 if (wm831x_buckv_list_voltage(rdev, vsel) < min_uV ||
279 wm831x_buckv_list_voltage(rdev, vsel) < max_uV)
280 return -EINVAL;
281
282 return vsel;
283}
284
285static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state)
286{
287 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
288
289 if (state == dcdc->dvs_gpio_state)
290 return 0;
291
292 dcdc->dvs_gpio_state = state;
293 gpio_set_value(dcdc->dvs_gpio, state);
294
295 /* Should wait for DVS state change to be asserted if we have
296 * a GPIO for it, for now assume the device is configured
297 * for the fastest possible transition.
298 */
299
300 return 0;
261} 301}
262 302
263static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, 303static int wm831x_buckv_set_voltage(struct regulator_dev *rdev,
264 int min_uV, int max_uV) 304 int min_uV, int max_uV)
265{ 305{
266 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); 306 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
267 u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; 307 struct wm831x *wm831x = dcdc->wm831x;
308 int on_reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
309 int dvs_reg = dcdc->base + WM831X_DCDC_DVS_CONTROL;
310 int vsel, ret;
311
312 vsel = wm831x_buckv_select_min_voltage(rdev, min_uV, max_uV);
313 if (vsel < 0)
314 return vsel;
315
316 /* If this value is already set then do a GPIO update if we can */
317 if (dcdc->dvs_gpio && dcdc->on_vsel == vsel)
318 return wm831x_buckv_set_dvs(rdev, 0);
319
320 if (dcdc->dvs_gpio && dcdc->dvs_vsel == vsel)
321 return wm831x_buckv_set_dvs(rdev, 1);
322
323 /* Always set the ON status to the minimum voltage */
324 ret = wm831x_set_bits(wm831x, on_reg, WM831X_DC1_ON_VSEL_MASK, vsel);
325 if (ret < 0)
326 return ret;
327 dcdc->on_vsel = vsel;
328
329 if (!dcdc->dvs_gpio)
330 return ret;
331
332 /* Kick the voltage transition now */
333 ret = wm831x_buckv_set_dvs(rdev, 0);
334 if (ret < 0)
335 return ret;
336
337 /* Set the high voltage as the DVS voltage. This is optimised
338 * for CPUfreq usage, most processors will keep the maximum
339 * voltage constant and lower the minimum with the frequency. */
340 vsel = wm831x_buckv_select_max_voltage(rdev, min_uV, max_uV);
341 if (vsel < 0) {
342 /* This should never happen - at worst the same vsel
343 * should be chosen */
344 WARN_ON(vsel < 0);
345 return 0;
346 }
347
348 /* Don't bother if it's the same VSEL we're already using */
349 if (vsel == dcdc->on_vsel)
350 return 0;
268 351
269 return wm831x_buckv_set_voltage_int(rdev, reg, min_uV, max_uV); 352 ret = wm831x_set_bits(wm831x, dvs_reg, WM831X_DC1_DVS_VSEL_MASK, vsel);
353 if (ret == 0)
354 dcdc->dvs_vsel = vsel;
355 else
356 dev_warn(wm831x->dev, "Failed to set DCDC DVS VSEL: %d\n",
357 ret);
358
359 return 0;
270} 360}
271 361
272static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev, 362static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev,
273 int uV) 363 int uV)
274{ 364{
275 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); 365 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
366 struct wm831x *wm831x = dcdc->wm831x;
276 u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; 367 u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
368 int vsel;
369
370 vsel = wm831x_buckv_select_min_voltage(rdev, uV, uV);
371 if (vsel < 0)
372 return vsel;
277 373
278 return wm831x_buckv_set_voltage_int(rdev, reg, uV, uV); 374 return wm831x_set_bits(wm831x, reg, WM831X_DC1_SLP_VSEL_MASK, vsel);
279} 375}
280 376
281static int wm831x_buckv_get_voltage(struct regulator_dev *rdev) 377static int wm831x_buckv_get_voltage(struct regulator_dev *rdev)
282{ 378{
283 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); 379 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
284 struct wm831x *wm831x = dcdc->wm831x;
285 u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
286 int val;
287 380
288 val = wm831x_reg_read(wm831x, reg); 381 if (dcdc->dvs_gpio && dcdc->dvs_gpio_state)
289 if (val < 0) 382 return wm831x_buckv_list_voltage(rdev, dcdc->dvs_vsel);
290 return val; 383 else
291 384 return wm831x_buckv_list_voltage(rdev, dcdc->on_vsel);
292 return wm831x_buckv_list_voltage(rdev, val & WM831X_DC1_ON_VSEL_MASK);
293} 385}
294 386
295/* Current limit options */ 387/* Current limit options */
@@ -346,6 +438,64 @@ static struct regulator_ops wm831x_buckv_ops = {
346 .set_suspend_mode = wm831x_dcdc_set_suspend_mode, 438 .set_suspend_mode = wm831x_dcdc_set_suspend_mode,
347}; 439};
348 440
441/*
442 * Set up DVS control. We just log errors since we can still run
443 * (with reduced performance) if we fail.
444 */
445static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
446 struct wm831x_buckv_pdata *pdata)
447{
448 struct wm831x *wm831x = dcdc->wm831x;
449 int ret;
450 u16 ctrl;
451
452 if (!pdata || !pdata->dvs_gpio)
453 return;
454
455 switch (pdata->dvs_control_src) {
456 case 1:
457 ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT;
458 break;
459 case 2:
460 ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT;
461 break;
462 default:
463 dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n",
464 pdata->dvs_control_src, dcdc->name);
465 return;
466 }
467
468 ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL,
469 WM831X_DC1_DVS_SRC_MASK, ctrl);
470 if (ret < 0) {
471 dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n",
472 dcdc->name, ret);
473 return;
474 }
475
476 ret = gpio_request(pdata->dvs_gpio, "DCDC DVS");
477 if (ret < 0) {
478 dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n",
479 dcdc->name, ret);
480 return;
481 }
482
483 /* gpiolib won't let us read the GPIO status so pick the higher
484 * of the two existing voltages so we take it as platform data.
485 */
486 dcdc->dvs_gpio_state = pdata->dvs_init_state;
487
488 ret = gpio_direction_output(pdata->dvs_gpio, dcdc->dvs_gpio_state);
489 if (ret < 0) {
490 dev_err(wm831x->dev, "Failed to enable %s DVS GPIO: %d\n",
491 dcdc->name, ret);
492 gpio_free(pdata->dvs_gpio);
493 return;
494 }
495
496 dcdc->dvs_gpio = pdata->dvs_gpio;
497}
498
349static __devinit int wm831x_buckv_probe(struct platform_device *pdev) 499static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
350{ 500{
351 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); 501 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
@@ -384,6 +534,23 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
384 dcdc->desc.ops = &wm831x_buckv_ops; 534 dcdc->desc.ops = &wm831x_buckv_ops;
385 dcdc->desc.owner = THIS_MODULE; 535 dcdc->desc.owner = THIS_MODULE;
386 536
537 ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
538 if (ret < 0) {
539 dev_err(wm831x->dev, "Failed to read ON VSEL: %d\n", ret);
540 goto err;
541 }
542 dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK;
543
544 ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
545 if (ret < 0) {
546 dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret);
547 goto err;
548 }
549 dcdc->dvs_vsel = ret & WM831X_DC1_DVS_VSEL_MASK;
550
551 if (pdata->dcdc[id])
552 wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data);
553
387 dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, 554 dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
388 pdata->dcdc[id], dcdc); 555 pdata->dcdc[id], dcdc);
389 if (IS_ERR(dcdc->regulator)) { 556 if (IS_ERR(dcdc->regulator)) {
@@ -422,6 +589,8 @@ err_uv:
422err_regulator: 589err_regulator:
423 regulator_unregister(dcdc->regulator); 590 regulator_unregister(dcdc->regulator);
424err: 591err:
592 if (dcdc->dvs_gpio)
593 gpio_free(dcdc->dvs_gpio);
425 kfree(dcdc); 594 kfree(dcdc);
426 return ret; 595 return ret;
427} 596}
@@ -434,6 +603,8 @@ static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
434 wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc); 603 wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc);
435 wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); 604 wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
436 regulator_unregister(dcdc->regulator); 605 regulator_unregister(dcdc->regulator);
606 if (dcdc->dvs_gpio)
607 gpio_free(dcdc->dvs_gpio);
437 kfree(dcdc); 608 kfree(dcdc);
438 609
439 return 0; 610 return 0;
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 902db56ce099..61e02ac2fda3 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -470,7 +470,7 @@ static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev)
470 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); 470 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
471 struct wm831x *wm831x = ldo->wm831x; 471 struct wm831x *wm831x = ldo->wm831x;
472 int on_reg = ldo->base + WM831X_LDO_ON_CONTROL; 472 int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
473 unsigned int ret; 473 int ret;
474 474
475 ret = wm831x_reg_read(wm831x, on_reg); 475 ret = wm831x_reg_read(wm831x, on_reg);
476 if (ret < 0) 476 if (ret < 0)
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
index 259db7f3535b..9630e7d3314e 100644
--- a/drivers/rtc/rtc-ds1305.c
+++ b/drivers/rtc/rtc-ds1305.c
@@ -778,6 +778,8 @@ static int __devinit ds1305_probe(struct spi_device *spi)
778 spi->irq, status); 778 spi->irq, status);
779 goto fail1; 779 goto fail1;
780 } 780 }
781
782 device_set_wakeup_capable(&spi->dev, 1);
781 } 783 }
782 784
783 /* export NVRAM */ 785 /* export NVRAM */
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 8a99da6f2f24..c4ec5c158aa1 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -881,6 +881,8 @@ read_rtc:
881 "unable to request IRQ!\n"); 881 "unable to request IRQ!\n");
882 goto exit_irq; 882 goto exit_irq;
883 } 883 }
884
885 device_set_wakeup_capable(&client->dev, 1);
884 set_bit(HAS_ALARM, &ds1307->flags); 886 set_bit(HAS_ALARM, &ds1307->flags);
885 dev_dbg(&client->dev, "got IRQ %d\n", client->irq); 887 dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
886 } 888 }
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 713f7bf5afb3..5317bbcbc7a0 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -383,6 +383,8 @@ static int ds1374_probe(struct i2c_client *client,
383 dev_err(&client->dev, "unable to request IRQ\n"); 383 dev_err(&client->dev, "unable to request IRQ\n");
384 goto out_free; 384 goto out_free;
385 } 385 }
386
387 device_set_wakeup_capable(&client->dev, 1);
386 } 388 }
387 389
388 ds1374->rtc = rtc_device_register(client->name, &client->dev, 390 ds1374->rtc = rtc_device_register(client->name, &client->dev,
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 2d9d70359360..f55eb0107336 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -216,6 +216,17 @@ config SPI_S3C24XX
216 help 216 help
217 SPI driver for Samsung S3C24XX series ARM SoCs 217 SPI driver for Samsung S3C24XX series ARM SoCs
218 218
219config SPI_S3C24XX_FIQ
220 bool "S3C24XX driver with FIQ pseudo-DMA"
221 depends on SPI_S3C24XX
222 select FIQ
223 help
224 Enable FIQ support for the S3C24XX SPI driver to provide pseudo
225 DMA by using the fast-interrupt request framework, This allows
226 the driver to get DMA-like performance when there are either
227 no free DMA channels, or when doing transfers that required both
228 TX and RX data paths.
229
219config SPI_S3C24XX_GPIO 230config SPI_S3C24XX_GPIO
220 tristate "Samsung S3C24XX series SPI by GPIO" 231 tristate "Samsung S3C24XX series SPI by GPIO"
221 depends on ARCH_S3C2410 && EXPERIMENTAL 232 depends on ARCH_S3C2410 && EXPERIMENTAL
@@ -226,6 +237,13 @@ config SPI_S3C24XX_GPIO
226 the inbuilt hardware cannot provide the transfer mode, or 237 the inbuilt hardware cannot provide the transfer mode, or
227 where the board is using non hardware connected pins. 238 where the board is using non hardware connected pins.
228 239
240config SPI_S3C64XX
241 tristate "Samsung S3C64XX series type SPI"
242 depends on ARCH_S3C64XX && EXPERIMENTAL
243 select S3C64XX_DMA
244 help
245 SPI driver for Samsung S3C64XX and newer SoCs.
246
229config SPI_SH_MSIOF 247config SPI_SH_MSIOF
230 tristate "SuperH MSIOF SPI controller" 248 tristate "SuperH MSIOF SPI controller"
231 depends on SUPERH && HAVE_CLK 249 depends on SUPERH && HAVE_CLK
@@ -289,6 +307,16 @@ config SPI_NUC900
289# Add new SPI master controllers in alphabetical order above this line 307# Add new SPI master controllers in alphabetical order above this line
290# 308#
291 309
310config SPI_DESIGNWARE
311 bool "DesignWare SPI controller core support"
312 depends on SPI_MASTER
313 help
314 general driver for SPI controller core from DesignWare
315
316config SPI_DW_PCI
317 tristate "PCI interface driver for DW SPI core"
318 depends on SPI_DESIGNWARE && PCI
319
292# 320#
293# There are lots of SPI device types, with sensors and memory 321# There are lots of SPI device types, with sensors and memory
294# being probably the most widely used ones. 322# being probably the most widely used ones.
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index ed8c1675b52f..f3d2810ba11c 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -16,6 +16,8 @@ obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
16obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o 16obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
17obj-$(CONFIG_SPI_AU1550) += au1550_spi.o 17obj-$(CONFIG_SPI_AU1550) += au1550_spi.o
18obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o 18obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
19obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.o
20obj-$(CONFIG_SPI_DW_PCI) += dw_spi_pci.o
19obj-$(CONFIG_SPI_GPIO) += spi_gpio.o 21obj-$(CONFIG_SPI_GPIO) += spi_gpio.o
20obj-$(CONFIG_SPI_IMX) += spi_imx.o 22obj-$(CONFIG_SPI_IMX) += spi_imx.o
21obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o 23obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o
@@ -30,7 +32,8 @@ obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o
30obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o 32obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o
31obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o 33obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o
32obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o 34obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
33obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o 35obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o
36obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o
34obj-$(CONFIG_SPI_TXX9) += spi_txx9.o 37obj-$(CONFIG_SPI_TXX9) += spi_txx9.o
35obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o 38obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o
36obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o 39obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o
@@ -39,6 +42,11 @@ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
39obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o 42obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o
40obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o 43obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o
41obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o 44obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o
45
46# special build for s3c24xx spi driver with fiq support
47spi_s3c24xx_hw-y := spi_s3c24xx.o
48spi_s3c24xx_hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi_s3c24xx_fiq.o
49
42# ... add above this line ... 50# ... add above this line ...
43 51
44# SPI protocol drivers (device/link on bus) 52# SPI protocol drivers (device/link on bus)
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index f5b3fdbb1e27..d21c24eaf0a9 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -189,14 +189,14 @@ static void atmel_spi_next_xfer_data(struct spi_master *master,
189 189
190 /* use scratch buffer only when rx or tx data is unspecified */ 190 /* use scratch buffer only when rx or tx data is unspecified */
191 if (xfer->rx_buf) 191 if (xfer->rx_buf)
192 *rx_dma = xfer->rx_dma + xfer->len - len; 192 *rx_dma = xfer->rx_dma + xfer->len - *plen;
193 else { 193 else {
194 *rx_dma = as->buffer_dma; 194 *rx_dma = as->buffer_dma;
195 if (len > BUFFER_SIZE) 195 if (len > BUFFER_SIZE)
196 len = BUFFER_SIZE; 196 len = BUFFER_SIZE;
197 } 197 }
198 if (xfer->tx_buf) 198 if (xfer->tx_buf)
199 *tx_dma = xfer->tx_dma + xfer->len - len; 199 *tx_dma = xfer->tx_dma + xfer->len - *plen;
200 else { 200 else {
201 *tx_dma = as->buffer_dma; 201 *tx_dma = as->buffer_dma;
202 if (len > BUFFER_SIZE) 202 if (len > BUFFER_SIZE)
@@ -788,7 +788,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev)
788 spin_lock_init(&as->lock); 788 spin_lock_init(&as->lock);
789 INIT_LIST_HEAD(&as->queue); 789 INIT_LIST_HEAD(&as->queue);
790 as->pdev = pdev; 790 as->pdev = pdev;
791 as->regs = ioremap(regs->start, (regs->end - regs->start) + 1); 791 as->regs = ioremap(regs->start, resource_size(regs));
792 if (!as->regs) 792 if (!as->regs)
793 goto out_free_buffer; 793 goto out_free_buffer;
794 as->irq = irq; 794 as->irq = irq;
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c
new file mode 100644
index 000000000000..31620fae77be
--- /dev/null
+++ b/drivers/spi/dw_spi.c
@@ -0,0 +1,944 @@
1/*
2 * dw_spi.c - Designware SPI core controller driver (refer pxa2xx_spi.c)
3 *
4 * Copyright (c) 2009, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include <linux/dma-mapping.h>
21#include <linux/interrupt.h>
22#include <linux/highmem.h>
23#include <linux/delay.h>
24
25#include <linux/spi/dw_spi.h>
26#include <linux/spi/spi.h>
27
28#ifdef CONFIG_DEBUG_FS
29#include <linux/debugfs.h>
30#endif
31
32#define START_STATE ((void *)0)
33#define RUNNING_STATE ((void *)1)
34#define DONE_STATE ((void *)2)
35#define ERROR_STATE ((void *)-1)
36
37#define QUEUE_RUNNING 0
38#define QUEUE_STOPPED 1
39
40#define MRST_SPI_DEASSERT 0
41#define MRST_SPI_ASSERT 1
42
43/* Slave spi_dev related */
44struct chip_data {
45 u16 cr0;
46 u8 cs; /* chip select pin */
47 u8 n_bytes; /* current is a 1/2/4 byte op */
48 u8 tmode; /* TR/TO/RO/EEPROM */
49 u8 type; /* SPI/SSP/MicroWire */
50
51 u8 poll_mode; /* 1 means use poll mode */
52
53 u32 dma_width;
54 u32 rx_threshold;
55 u32 tx_threshold;
56 u8 enable_dma;
57 u8 bits_per_word;
58 u16 clk_div; /* baud rate divider */
59 u32 speed_hz; /* baud rate */
60 int (*write)(struct dw_spi *dws);
61 int (*read)(struct dw_spi *dws);
62 void (*cs_control)(u32 command);
63};
64
65#ifdef CONFIG_DEBUG_FS
66static int spi_show_regs_open(struct inode *inode, struct file *file)
67{
68 file->private_data = inode->i_private;
69 return 0;
70}
71
72#define SPI_REGS_BUFSIZE 1024
73static ssize_t spi_show_regs(struct file *file, char __user *user_buf,
74 size_t count, loff_t *ppos)
75{
76 struct dw_spi *dws;
77 char *buf;
78 u32 len = 0;
79 ssize_t ret;
80
81 dws = file->private_data;
82
83 buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL);
84 if (!buf)
85 return 0;
86
87 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
88 "MRST SPI0 registers:\n");
89 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
90 "=================================\n");
91 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
92 "CTRL0: \t\t0x%08x\n", dw_readl(dws, ctrl0));
93 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
94 "CTRL1: \t\t0x%08x\n", dw_readl(dws, ctrl1));
95 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
96 "SSIENR: \t0x%08x\n", dw_readl(dws, ssienr));
97 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
98 "SER: \t\t0x%08x\n", dw_readl(dws, ser));
99 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
100 "BAUDR: \t\t0x%08x\n", dw_readl(dws, baudr));
101 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
102 "TXFTLR: \t0x%08x\n", dw_readl(dws, txfltr));
103 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
104 "RXFTLR: \t0x%08x\n", dw_readl(dws, rxfltr));
105 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
106 "TXFLR: \t\t0x%08x\n", dw_readl(dws, txflr));
107 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
108 "RXFLR: \t\t0x%08x\n", dw_readl(dws, rxflr));
109 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
110 "SR: \t\t0x%08x\n", dw_readl(dws, sr));
111 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
112 "IMR: \t\t0x%08x\n", dw_readl(dws, imr));
113 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
114 "ISR: \t\t0x%08x\n", dw_readl(dws, isr));
115 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
116 "DMACR: \t\t0x%08x\n", dw_readl(dws, dmacr));
117 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
118 "DMATDLR: \t0x%08x\n", dw_readl(dws, dmatdlr));
119 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
120 "DMARDLR: \t0x%08x\n", dw_readl(dws, dmardlr));
121 len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
122 "=================================\n");
123
124 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
125 kfree(buf);
126 return ret;
127}
128
129static const struct file_operations mrst_spi_regs_ops = {
130 .owner = THIS_MODULE,
131 .open = spi_show_regs_open,
132 .read = spi_show_regs,
133};
134
135static int mrst_spi_debugfs_init(struct dw_spi *dws)
136{
137 dws->debugfs = debugfs_create_dir("mrst_spi", NULL);
138 if (!dws->debugfs)
139 return -ENOMEM;
140
141 debugfs_create_file("registers", S_IFREG | S_IRUGO,
142 dws->debugfs, (void *)dws, &mrst_spi_regs_ops);
143 return 0;
144}
145
146static void mrst_spi_debugfs_remove(struct dw_spi *dws)
147{
148 if (dws->debugfs)
149 debugfs_remove_recursive(dws->debugfs);
150}
151
152#else
153static inline int mrst_spi_debugfs_init(struct dw_spi *dws)
154{
155}
156
157static inline void mrst_spi_debugfs_remove(struct dw_spi *dws)
158{
159}
160#endif /* CONFIG_DEBUG_FS */
161
162static void wait_till_not_busy(struct dw_spi *dws)
163{
164 unsigned long end = jiffies + usecs_to_jiffies(1000);
165
166 while (time_before(jiffies, end)) {
167 if (!(dw_readw(dws, sr) & SR_BUSY))
168 return;
169 }
170 dev_err(&dws->master->dev,
171 "DW SPI: Stutus keeps busy for 1000us after a read/write!\n");
172}
173
174static void flush(struct dw_spi *dws)
175{
176 while (dw_readw(dws, sr) & SR_RF_NOT_EMPT)
177 dw_readw(dws, dr);
178
179 wait_till_not_busy(dws);
180}
181
182static void null_cs_control(u32 command)
183{
184}
185
186static int null_writer(struct dw_spi *dws)
187{
188 u8 n_bytes = dws->n_bytes;
189
190 if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL)
191 || (dws->tx == dws->tx_end))
192 return 0;
193 dw_writew(dws, dr, 0);
194 dws->tx += n_bytes;
195
196 wait_till_not_busy(dws);
197 return 1;
198}
199
200static int null_reader(struct dw_spi *dws)
201{
202 u8 n_bytes = dws->n_bytes;
203
204 while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT)
205 && (dws->rx < dws->rx_end)) {
206 dw_readw(dws, dr);
207 dws->rx += n_bytes;
208 }
209 wait_till_not_busy(dws);
210 return dws->rx == dws->rx_end;
211}
212
213static int u8_writer(struct dw_spi *dws)
214{
215 if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL)
216 || (dws->tx == dws->tx_end))
217 return 0;
218
219 dw_writew(dws, dr, *(u8 *)(dws->tx));
220 ++dws->tx;
221
222 wait_till_not_busy(dws);
223 return 1;
224}
225
226static int u8_reader(struct dw_spi *dws)
227{
228 while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT)
229 && (dws->rx < dws->rx_end)) {
230 *(u8 *)(dws->rx) = dw_readw(dws, dr);
231 ++dws->rx;
232 }
233
234 wait_till_not_busy(dws);
235 return dws->rx == dws->rx_end;
236}
237
238static int u16_writer(struct dw_spi *dws)
239{
240 if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL)
241 || (dws->tx == dws->tx_end))
242 return 0;
243
244 dw_writew(dws, dr, *(u16 *)(dws->tx));
245 dws->tx += 2;
246
247 wait_till_not_busy(dws);
248 return 1;
249}
250
251static int u16_reader(struct dw_spi *dws)
252{
253 u16 temp;
254
255 while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT)
256 && (dws->rx < dws->rx_end)) {
257 temp = dw_readw(dws, dr);
258 *(u16 *)(dws->rx) = temp;
259 dws->rx += 2;
260 }
261
262 wait_till_not_busy(dws);
263 return dws->rx == dws->rx_end;
264}
265
266static void *next_transfer(struct dw_spi *dws)
267{
268 struct spi_message *msg = dws->cur_msg;
269 struct spi_transfer *trans = dws->cur_transfer;
270
271 /* Move to next transfer */
272 if (trans->transfer_list.next != &msg->transfers) {
273 dws->cur_transfer =
274 list_entry(trans->transfer_list.next,
275 struct spi_transfer,
276 transfer_list);
277 return RUNNING_STATE;
278 } else
279 return DONE_STATE;
280}
281
282/*
283 * Note: first step is the protocol driver prepares
284 * a dma-capable memory, and this func just need translate
285 * the virt addr to physical
286 */
287static int map_dma_buffers(struct dw_spi *dws)
288{
289 if (!dws->cur_msg->is_dma_mapped || !dws->dma_inited
290 || !dws->cur_chip->enable_dma)
291 return 0;
292
293 if (dws->cur_transfer->tx_dma)
294 dws->tx_dma = dws->cur_transfer->tx_dma;
295
296 if (dws->cur_transfer->rx_dma)
297 dws->rx_dma = dws->cur_transfer->rx_dma;
298
299 return 1;
300}
301
302/* Caller already set message->status; dma and pio irqs are blocked */
303static void giveback(struct dw_spi *dws)
304{
305 struct spi_transfer *last_transfer;
306 unsigned long flags;
307 struct spi_message *msg;
308
309 spin_lock_irqsave(&dws->lock, flags);
310 msg = dws->cur_msg;
311 dws->cur_msg = NULL;
312 dws->cur_transfer = NULL;
313 dws->prev_chip = dws->cur_chip;
314 dws->cur_chip = NULL;
315 dws->dma_mapped = 0;
316 queue_work(dws->workqueue, &dws->pump_messages);
317 spin_unlock_irqrestore(&dws->lock, flags);
318
319 last_transfer = list_entry(msg->transfers.prev,
320 struct spi_transfer,
321 transfer_list);
322
323 if (!last_transfer->cs_change)
324 dws->cs_control(MRST_SPI_DEASSERT);
325
326 msg->state = NULL;
327 if (msg->complete)
328 msg->complete(msg->context);
329}
330
331static void int_error_stop(struct dw_spi *dws, const char *msg)
332{
333 /* Stop and reset hw */
334 flush(dws);
335 spi_enable_chip(dws, 0);
336
337 dev_err(&dws->master->dev, "%s\n", msg);
338 dws->cur_msg->state = ERROR_STATE;
339 tasklet_schedule(&dws->pump_transfers);
340}
341
342static void transfer_complete(struct dw_spi *dws)
343{
344 /* Update total byte transfered return count actual bytes read */
345 dws->cur_msg->actual_length += dws->len;
346
347 /* Move to next transfer */
348 dws->cur_msg->state = next_transfer(dws);
349
350 /* Handle end of message */
351 if (dws->cur_msg->state == DONE_STATE) {
352 dws->cur_msg->status = 0;
353 giveback(dws);
354 } else
355 tasklet_schedule(&dws->pump_transfers);
356}
357
358static irqreturn_t interrupt_transfer(struct dw_spi *dws)
359{
360 u16 irq_status, irq_mask = 0x3f;
361
362 irq_status = dw_readw(dws, isr) & irq_mask;
363 /* Error handling */
364 if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) {
365 dw_readw(dws, txoicr);
366 dw_readw(dws, rxoicr);
367 dw_readw(dws, rxuicr);
368 int_error_stop(dws, "interrupt_transfer: fifo overrun");
369 return IRQ_HANDLED;
370 }
371
372 /* INT comes from tx */
373 if (dws->tx && (irq_status & SPI_INT_TXEI)) {
374 while (dws->tx < dws->tx_end)
375 dws->write(dws);
376
377 if (dws->tx == dws->tx_end) {
378 spi_mask_intr(dws, SPI_INT_TXEI);
379 transfer_complete(dws);
380 }
381 }
382
383 /* INT comes from rx */
384 if (dws->rx && (irq_status & SPI_INT_RXFI)) {
385 if (dws->read(dws))
386 transfer_complete(dws);
387 }
388 return IRQ_HANDLED;
389}
390
391static irqreturn_t dw_spi_irq(int irq, void *dev_id)
392{
393 struct dw_spi *dws = dev_id;
394
395 if (!dws->cur_msg) {
396 spi_mask_intr(dws, SPI_INT_TXEI);
397 /* Never fail */
398 return IRQ_HANDLED;
399 }
400
401 return dws->transfer_handler(dws);
402}
403
404/* Must be called inside pump_transfers() */
405static void poll_transfer(struct dw_spi *dws)
406{
407 if (dws->tx) {
408 while (dws->write(dws))
409 dws->read(dws);
410 }
411
412 dws->read(dws);
413 transfer_complete(dws);
414}
415
416static void dma_transfer(struct dw_spi *dws, int cs_change)
417{
418}
419
420static void pump_transfers(unsigned long data)
421{
422 struct dw_spi *dws = (struct dw_spi *)data;
423 struct spi_message *message = NULL;
424 struct spi_transfer *transfer = NULL;
425 struct spi_transfer *previous = NULL;
426 struct spi_device *spi = NULL;
427 struct chip_data *chip = NULL;
428 u8 bits = 0;
429 u8 imask = 0;
430 u8 cs_change = 0;
431 u16 clk_div = 0;
432 u32 speed = 0;
433 u32 cr0 = 0;
434
435 /* Get current state information */
436 message = dws->cur_msg;
437 transfer = dws->cur_transfer;
438 chip = dws->cur_chip;
439 spi = message->spi;
440
441 if (message->state == ERROR_STATE) {
442 message->status = -EIO;
443 goto early_exit;
444 }
445
446 /* Handle end of message */
447 if (message->state == DONE_STATE) {
448 message->status = 0;
449 goto early_exit;
450 }
451
452 /* Delay if requested at end of transfer*/
453 if (message->state == RUNNING_STATE) {
454 previous = list_entry(transfer->transfer_list.prev,
455 struct spi_transfer,
456 transfer_list);
457 if (previous->delay_usecs)
458 udelay(previous->delay_usecs);
459 }
460
461 dws->n_bytes = chip->n_bytes;
462 dws->dma_width = chip->dma_width;
463 dws->cs_control = chip->cs_control;
464
465 dws->rx_dma = transfer->rx_dma;
466 dws->tx_dma = transfer->tx_dma;
467 dws->tx = (void *)transfer->tx_buf;
468 dws->tx_end = dws->tx + transfer->len;
469 dws->rx = transfer->rx_buf;
470 dws->rx_end = dws->rx + transfer->len;
471 dws->write = dws->tx ? chip->write : null_writer;
472 dws->read = dws->rx ? chip->read : null_reader;
473 dws->cs_change = transfer->cs_change;
474 dws->len = dws->cur_transfer->len;
475 if (chip != dws->prev_chip)
476 cs_change = 1;
477
478 cr0 = chip->cr0;
479
480 /* Handle per transfer options for bpw and speed */
481 if (transfer->speed_hz) {
482 speed = chip->speed_hz;
483
484 if (transfer->speed_hz != speed) {
485 speed = transfer->speed_hz;
486 if (speed > dws->max_freq) {
487 printk(KERN_ERR "MRST SPI0: unsupported"
488 "freq: %dHz\n", speed);
489 message->status = -EIO;
490 goto early_exit;
491 }
492
493 /* clk_div doesn't support odd number */
494 clk_div = dws->max_freq / speed;
495 clk_div = (clk_div >> 1) << 1;
496
497 chip->speed_hz = speed;
498 chip->clk_div = clk_div;
499 }
500 }
501 if (transfer->bits_per_word) {
502 bits = transfer->bits_per_word;
503
504 switch (bits) {
505 case 8:
506 dws->n_bytes = 1;
507 dws->dma_width = 1;
508 dws->read = (dws->read != null_reader) ?
509 u8_reader : null_reader;
510 dws->write = (dws->write != null_writer) ?
511 u8_writer : null_writer;
512 break;
513 case 16:
514 dws->n_bytes = 2;
515 dws->dma_width = 2;
516 dws->read = (dws->read != null_reader) ?
517 u16_reader : null_reader;
518 dws->write = (dws->write != null_writer) ?
519 u16_writer : null_writer;
520 break;
521 default:
522 printk(KERN_ERR "MRST SPI0: unsupported bits:"
523 "%db\n", bits);
524 message->status = -EIO;
525 goto early_exit;
526 }
527
528 cr0 = (bits - 1)
529 | (chip->type << SPI_FRF_OFFSET)
530 | (spi->mode << SPI_MODE_OFFSET)
531 | (chip->tmode << SPI_TMOD_OFFSET);
532 }
533 message->state = RUNNING_STATE;
534
535 /* Check if current transfer is a DMA transaction */
536 dws->dma_mapped = map_dma_buffers(dws);
537
538 if (!dws->dma_mapped && !chip->poll_mode) {
539 if (dws->rx)
540 imask |= SPI_INT_RXFI;
541 if (dws->tx)
542 imask |= SPI_INT_TXEI;
543 dws->transfer_handler = interrupt_transfer;
544 }
545
546 /*
547 * Reprogram registers only if
548 * 1. chip select changes
549 * 2. clk_div is changed
550 * 3. control value changes
551 */
552 if (dw_readw(dws, ctrl0) != cr0 || cs_change || clk_div) {
553 spi_enable_chip(dws, 0);
554
555 if (dw_readw(dws, ctrl0) != cr0)
556 dw_writew(dws, ctrl0, cr0);
557
558 /* Set the interrupt mask, for poll mode just diable all int */
559 spi_mask_intr(dws, 0xff);
560 if (!chip->poll_mode)
561 spi_umask_intr(dws, imask);
562
563 spi_set_clk(dws, clk_div ? clk_div : chip->clk_div);
564 spi_chip_sel(dws, spi->chip_select);
565 spi_enable_chip(dws, 1);
566
567 if (cs_change)
568 dws->prev_chip = chip;
569 }
570
571 if (dws->dma_mapped)
572 dma_transfer(dws, cs_change);
573
574 if (chip->poll_mode)
575 poll_transfer(dws);
576
577 return;
578
579early_exit:
580 giveback(dws);
581 return;
582}
583
584static void pump_messages(struct work_struct *work)
585{
586 struct dw_spi *dws =
587 container_of(work, struct dw_spi, pump_messages);
588 unsigned long flags;
589
590 /* Lock queue and check for queue work */
591 spin_lock_irqsave(&dws->lock, flags);
592 if (list_empty(&dws->queue) || dws->run == QUEUE_STOPPED) {
593 dws->busy = 0;
594 spin_unlock_irqrestore(&dws->lock, flags);
595 return;
596 }
597
598 /* Make sure we are not already running a message */
599 if (dws->cur_msg) {
600 spin_unlock_irqrestore(&dws->lock, flags);
601 return;
602 }
603
604 /* Extract head of queue */
605 dws->cur_msg = list_entry(dws->queue.next, struct spi_message, queue);
606 list_del_init(&dws->cur_msg->queue);
607
608 /* Initial message state*/
609 dws->cur_msg->state = START_STATE;
610 dws->cur_transfer = list_entry(dws->cur_msg->transfers.next,
611 struct spi_transfer,
612 transfer_list);
613 dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi);
614
615 /* Mark as busy and launch transfers */
616 tasklet_schedule(&dws->pump_transfers);
617
618 dws->busy = 1;
619 spin_unlock_irqrestore(&dws->lock, flags);
620}
621
622/* spi_device use this to queue in their spi_msg */
623static int dw_spi_transfer(struct spi_device *spi, struct spi_message *msg)
624{
625 struct dw_spi *dws = spi_master_get_devdata(spi->master);
626 unsigned long flags;
627
628 spin_lock_irqsave(&dws->lock, flags);
629
630 if (dws->run == QUEUE_STOPPED) {
631 spin_unlock_irqrestore(&dws->lock, flags);
632 return -ESHUTDOWN;
633 }
634
635 msg->actual_length = 0;
636 msg->status = -EINPROGRESS;
637 msg->state = START_STATE;
638
639 list_add_tail(&msg->queue, &dws->queue);
640
641 if (dws->run == QUEUE_RUNNING && !dws->busy) {
642
643 if (dws->cur_transfer || dws->cur_msg)
644 queue_work(dws->workqueue,
645 &dws->pump_messages);
646 else {
647 /* If no other data transaction in air, just go */
648 spin_unlock_irqrestore(&dws->lock, flags);
649 pump_messages(&dws->pump_messages);
650 return 0;
651 }
652 }
653
654 spin_unlock_irqrestore(&dws->lock, flags);
655 return 0;
656}
657
658/* This may be called twice for each spi dev */
659static int dw_spi_setup(struct spi_device *spi)
660{
661 struct dw_spi_chip *chip_info = NULL;
662 struct chip_data *chip;
663
664 if (spi->bits_per_word != 8 && spi->bits_per_word != 16)
665 return -EINVAL;
666
667 /* Only alloc on first setup */
668 chip = spi_get_ctldata(spi);
669 if (!chip) {
670 chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
671 if (!chip)
672 return -ENOMEM;
673
674 chip->cs_control = null_cs_control;
675 chip->enable_dma = 0;
676 }
677
678 /*
679 * Protocol drivers may change the chip settings, so...
680 * if chip_info exists, use it
681 */
682 chip_info = spi->controller_data;
683
684 /* chip_info doesn't always exist */
685 if (chip_info) {
686 if (chip_info->cs_control)
687 chip->cs_control = chip_info->cs_control;
688
689 chip->poll_mode = chip_info->poll_mode;
690 chip->type = chip_info->type;
691
692 chip->rx_threshold = 0;
693 chip->tx_threshold = 0;
694
695 chip->enable_dma = chip_info->enable_dma;
696 }
697
698 if (spi->bits_per_word <= 8) {
699 chip->n_bytes = 1;
700 chip->dma_width = 1;
701 chip->read = u8_reader;
702 chip->write = u8_writer;
703 } else if (spi->bits_per_word <= 16) {
704 chip->n_bytes = 2;
705 chip->dma_width = 2;
706 chip->read = u16_reader;
707 chip->write = u16_writer;
708 } else {
709 /* Never take >16b case for MRST SPIC */
710 dev_err(&spi->dev, "invalid wordsize\n");
711 return -EINVAL;
712 }
713 chip->bits_per_word = spi->bits_per_word;
714
715 chip->speed_hz = spi->max_speed_hz;
716 if (chip->speed_hz)
717 chip->clk_div = 25000000 / chip->speed_hz;
718 else
719 chip->clk_div = 8; /* default value */
720
721 chip->tmode = 0; /* Tx & Rx */
722 /* Default SPI mode is SCPOL = 0, SCPH = 0 */
723 chip->cr0 = (chip->bits_per_word - 1)
724 | (chip->type << SPI_FRF_OFFSET)
725 | (spi->mode << SPI_MODE_OFFSET)
726 | (chip->tmode << SPI_TMOD_OFFSET);
727
728 spi_set_ctldata(spi, chip);
729 return 0;
730}
731
732static void dw_spi_cleanup(struct spi_device *spi)
733{
734 struct chip_data *chip = spi_get_ctldata(spi);
735 kfree(chip);
736}
737
738static int __init init_queue(struct dw_spi *dws)
739{
740 INIT_LIST_HEAD(&dws->queue);
741 spin_lock_init(&dws->lock);
742
743 dws->run = QUEUE_STOPPED;
744 dws->busy = 0;
745
746 tasklet_init(&dws->pump_transfers,
747 pump_transfers, (unsigned long)dws);
748
749 INIT_WORK(&dws->pump_messages, pump_messages);
750 dws->workqueue = create_singlethread_workqueue(
751 dev_name(dws->master->dev.parent));
752 if (dws->workqueue == NULL)
753 return -EBUSY;
754
755 return 0;
756}
757
758static int start_queue(struct dw_spi *dws)
759{
760 unsigned long flags;
761
762 spin_lock_irqsave(&dws->lock, flags);
763
764 if (dws->run == QUEUE_RUNNING || dws->busy) {
765 spin_unlock_irqrestore(&dws->lock, flags);
766 return -EBUSY;
767 }
768
769 dws->run = QUEUE_RUNNING;
770 dws->cur_msg = NULL;
771 dws->cur_transfer = NULL;
772 dws->cur_chip = NULL;
773 dws->prev_chip = NULL;
774 spin_unlock_irqrestore(&dws->lock, flags);
775
776 queue_work(dws->workqueue, &dws->pump_messages);
777
778 return 0;
779}
780
781static int stop_queue(struct dw_spi *dws)
782{
783 unsigned long flags;
784 unsigned limit = 50;
785 int status = 0;
786
787 spin_lock_irqsave(&dws->lock, flags);
788 dws->run = QUEUE_STOPPED;
789 while (!list_empty(&dws->queue) && dws->busy && limit--) {
790 spin_unlock_irqrestore(&dws->lock, flags);
791 msleep(10);
792 spin_lock_irqsave(&dws->lock, flags);
793 }
794
795 if (!list_empty(&dws->queue) || dws->busy)
796 status = -EBUSY;
797 spin_unlock_irqrestore(&dws->lock, flags);
798
799 return status;
800}
801
802static int destroy_queue(struct dw_spi *dws)
803{
804 int status;
805
806 status = stop_queue(dws);
807 if (status != 0)
808 return status;
809 destroy_workqueue(dws->workqueue);
810 return 0;
811}
812
813/* Restart the controller, disable all interrupts, clean rx fifo */
814static void spi_hw_init(struct dw_spi *dws)
815{
816 spi_enable_chip(dws, 0);
817 spi_mask_intr(dws, 0xff);
818 spi_enable_chip(dws, 1);
819 flush(dws);
820}
821
822int __devinit dw_spi_add_host(struct dw_spi *dws)
823{
824 struct spi_master *master;
825 int ret;
826
827 BUG_ON(dws == NULL);
828
829 master = spi_alloc_master(dws->parent_dev, 0);
830 if (!master) {
831 ret = -ENOMEM;
832 goto exit;
833 }
834
835 dws->master = master;
836 dws->type = SSI_MOTO_SPI;
837 dws->prev_chip = NULL;
838 dws->dma_inited = 0;
839 dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60);
840
841 ret = request_irq(dws->irq, dw_spi_irq, 0,
842 "dw_spi", dws);
843 if (ret < 0) {
844 dev_err(&master->dev, "can not get IRQ\n");
845 goto err_free_master;
846 }
847
848 master->mode_bits = SPI_CPOL | SPI_CPHA;
849 master->bus_num = dws->bus_num;
850 master->num_chipselect = dws->num_cs;
851 master->cleanup = dw_spi_cleanup;
852 master->setup = dw_spi_setup;
853 master->transfer = dw_spi_transfer;
854
855 dws->dma_inited = 0;
856
857 /* Basic HW init */
858 spi_hw_init(dws);
859
860 /* Initial and start queue */
861 ret = init_queue(dws);
862 if (ret) {
863 dev_err(&master->dev, "problem initializing queue\n");
864 goto err_diable_hw;
865 }
866 ret = start_queue(dws);
867 if (ret) {
868 dev_err(&master->dev, "problem starting queue\n");
869 goto err_diable_hw;
870 }
871
872 spi_master_set_devdata(master, dws);
873 ret = spi_register_master(master);
874 if (ret) {
875 dev_err(&master->dev, "problem registering spi master\n");
876 goto err_queue_alloc;
877 }
878
879 mrst_spi_debugfs_init(dws);
880 return 0;
881
882err_queue_alloc:
883 destroy_queue(dws);
884err_diable_hw:
885 spi_enable_chip(dws, 0);
886 free_irq(dws->irq, dws);
887err_free_master:
888 spi_master_put(master);
889exit:
890 return ret;
891}
892EXPORT_SYMBOL(dw_spi_add_host);
893
894void __devexit dw_spi_remove_host(struct dw_spi *dws)
895{
896 int status = 0;
897
898 if (!dws)
899 return;
900 mrst_spi_debugfs_remove(dws);
901
902 /* Remove the queue */
903 status = destroy_queue(dws);
904 if (status != 0)
905 dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not "
906 "complete, message memory not freed\n");
907
908 spi_enable_chip(dws, 0);
909 /* Disable clk */
910 spi_set_clk(dws, 0);
911 free_irq(dws->irq, dws);
912
913 /* Disconnect from the SPI framework */
914 spi_unregister_master(dws->master);
915}
916
917int dw_spi_suspend_host(struct dw_spi *dws)
918{
919 int ret = 0;
920
921 ret = stop_queue(dws);
922 if (ret)
923 return ret;
924 spi_enable_chip(dws, 0);
925 spi_set_clk(dws, 0);
926 return ret;
927}
928EXPORT_SYMBOL(dw_spi_suspend_host);
929
930int dw_spi_resume_host(struct dw_spi *dws)
931{
932 int ret;
933
934 spi_hw_init(dws);
935 ret = start_queue(dws);
936 if (ret)
937 dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret);
938 return ret;
939}
940EXPORT_SYMBOL(dw_spi_resume_host);
941
942MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>");
943MODULE_DESCRIPTION("Driver for DesignWare SPI controller core");
944MODULE_LICENSE("GPL v2");
diff --git a/drivers/spi/dw_spi_pci.c b/drivers/spi/dw_spi_pci.c
new file mode 100644
index 000000000000..34ba69161734
--- /dev/null
+++ b/drivers/spi/dw_spi_pci.c
@@ -0,0 +1,169 @@
1/*
2 * mrst_spi_pci.c - PCI interface driver for DW SPI Core
3 *
4 * Copyright (c) 2009, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include <linux/interrupt.h>
21#include <linux/pci.h>
22#include <linux/spi/dw_spi.h>
23#include <linux/spi/spi.h>
24
25#define DRIVER_NAME "dw_spi_pci"
26
27struct dw_spi_pci {
28 struct pci_dev *pdev;
29 struct dw_spi dws;
30};
31
32static int __devinit spi_pci_probe(struct pci_dev *pdev,
33 const struct pci_device_id *ent)
34{
35 struct dw_spi_pci *dwpci;
36 struct dw_spi *dws;
37 int pci_bar = 0;
38 int ret;
39
40 printk(KERN_INFO "DW: found PCI SPI controller(ID: %04x:%04x)\n",
41 pdev->vendor, pdev->device);
42
43 ret = pci_enable_device(pdev);
44 if (ret)
45 return ret;
46
47 dwpci = kzalloc(sizeof(struct dw_spi_pci), GFP_KERNEL);
48 if (!dwpci) {
49 ret = -ENOMEM;
50 goto err_disable;
51 }
52
53 dwpci->pdev = pdev;
54 dws = &dwpci->dws;
55
56 /* Get basic io resource and map it */
57 dws->paddr = pci_resource_start(pdev, pci_bar);
58 dws->iolen = pci_resource_len(pdev, pci_bar);
59
60 ret = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev));
61 if (ret)
62 goto err_kfree;
63
64 dws->regs = ioremap_nocache((unsigned long)dws->paddr,
65 pci_resource_len(pdev, pci_bar));
66 if (!dws->regs) {
67 ret = -ENOMEM;
68 goto err_release_reg;
69 }
70
71 dws->parent_dev = &pdev->dev;
72 dws->bus_num = 0;
73 dws->num_cs = 4;
74 dws->max_freq = 25000000; /* for Moorestwon */
75 dws->irq = pdev->irq;
76
77 ret = dw_spi_add_host(dws);
78 if (ret)
79 goto err_unmap;
80
81 /* PCI hook and SPI hook use the same drv data */
82 pci_set_drvdata(pdev, dwpci);
83 return 0;
84
85err_unmap:
86 iounmap(dws->regs);
87err_release_reg:
88 pci_release_region(pdev, pci_bar);
89err_kfree:
90 kfree(dwpci);
91err_disable:
92 pci_disable_device(pdev);
93 return ret;
94}
95
96static void __devexit spi_pci_remove(struct pci_dev *pdev)
97{
98 struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
99
100 pci_set_drvdata(pdev, NULL);
101 iounmap(dwpci->dws.regs);
102 pci_release_region(pdev, 0);
103 kfree(dwpci);
104 pci_disable_device(pdev);
105}
106
107#ifdef CONFIG_PM
108static int spi_suspend(struct pci_dev *pdev, pm_message_t state)
109{
110 struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
111 int ret;
112
113 ret = dw_spi_suspend_host(&dwpci->dws);
114 if (ret)
115 return ret;
116 pci_save_state(pdev);
117 pci_disable_device(pdev);
118 pci_set_power_state(pdev, pci_choose_state(pdev, state));
119 return ret;
120}
121
122static int spi_resume(struct pci_dev *pdev)
123{
124 struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
125 int ret;
126
127 pci_set_power_state(pdev, PCI_D0);
128 pci_restore_state(pdev);
129 ret = pci_enable_device(pdev);
130 if (ret)
131 return ret;
132 return dw_spi_resume_host(&dwpci->dws);
133}
134#else
135#define spi_suspend NULL
136#define spi_resume NULL
137#endif
138
139static const struct pci_device_id pci_ids[] __devinitdata = {
140 /* Intel Moorestown platform SPI controller 0 */
141 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) },
142 {},
143};
144
145static struct pci_driver dw_spi_driver = {
146 .name = DRIVER_NAME,
147 .id_table = pci_ids,
148 .probe = spi_pci_probe,
149 .remove = __devexit_p(spi_pci_remove),
150 .suspend = spi_suspend,
151 .resume = spi_resume,
152};
153
154static int __init mrst_spi_init(void)
155{
156 return pci_register_driver(&dw_spi_driver);
157}
158
159static void __exit mrst_spi_exit(void)
160{
161 pci_unregister_driver(&dw_spi_driver);
162}
163
164module_init(mrst_spi_init);
165module_exit(mrst_spi_exit);
166
167MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>");
168MODULE_DESCRIPTION("PCI interface driver for DW SPI Core");
169MODULE_LICENSE("GPL v2");
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 73e24ef5a2f9..1d41058bbab2 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1294,7 +1294,7 @@ static int __init bfin_spi_probe(struct platform_device *pdev)
1294 goto out_error_get_res; 1294 goto out_error_get_res;
1295 } 1295 }
1296 1296
1297 drv_data->regs_base = ioremap(res->start, (res->end - res->start + 1)); 1297 drv_data->regs_base = ioremap(res->start, resource_size(res));
1298 if (drv_data->regs_base == NULL) { 1298 if (drv_data->regs_base == NULL) {
1299 dev_err(dev, "Cannot map IO\n"); 1299 dev_err(dev, "Cannot map IO\n");
1300 status = -ENXIO; 1300 status = -ENXIO;
diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c
index e9390d747bfc..1fb2a6ea328c 100644
--- a/drivers/spi/spi_mpc8xxx.c
+++ b/drivers/spi/spi_mpc8xxx.c
@@ -1013,7 +1013,7 @@ mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
1013 1013
1014 init_completion(&mpc8xxx_spi->done); 1014 init_completion(&mpc8xxx_spi->done);
1015 1015
1016 mpc8xxx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); 1016 mpc8xxx_spi->base = ioremap(mem->start, resource_size(mem));
1017 if (mpc8xxx_spi->base == NULL) { 1017 if (mpc8xxx_spi->base == NULL) {
1018 ret = -ENOMEM; 1018 ret = -ENOMEM;
1019 goto err_ioremap; 1019 goto err_ioremap;
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 276591569c8b..c010733877ae 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -1,7 +1,7 @@
1/* linux/drivers/spi/spi_s3c24xx.c 1/* linux/drivers/spi/spi_s3c24xx.c
2 * 2 *
3 * Copyright (c) 2006 Ben Dooks 3 * Copyright (c) 2006 Ben Dooks
4 * Copyright (c) 2006 Simtec Electronics 4 * Copyright 2006-2009 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk> 5 * Ben Dooks <ben@simtec.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -28,6 +28,11 @@
28#include <plat/regs-spi.h> 28#include <plat/regs-spi.h>
29#include <mach/spi.h> 29#include <mach/spi.h>
30 30
31#include <plat/fiq.h>
32#include <asm/fiq.h>
33
34#include "spi_s3c24xx_fiq.h"
35
31/** 36/**
32 * s3c24xx_spi_devstate - per device data 37 * s3c24xx_spi_devstate - per device data
33 * @hz: Last frequency calculated for @sppre field. 38 * @hz: Last frequency calculated for @sppre field.
@@ -42,6 +47,13 @@ struct s3c24xx_spi_devstate {
42 u8 sppre; 47 u8 sppre;
43}; 48};
44 49
50enum spi_fiq_mode {
51 FIQ_MODE_NONE = 0,
52 FIQ_MODE_TX = 1,
53 FIQ_MODE_RX = 2,
54 FIQ_MODE_TXRX = 3,
55};
56
45struct s3c24xx_spi { 57struct s3c24xx_spi {
46 /* bitbang has to be first */ 58 /* bitbang has to be first */
47 struct spi_bitbang bitbang; 59 struct spi_bitbang bitbang;
@@ -52,6 +64,11 @@ struct s3c24xx_spi {
52 int len; 64 int len;
53 int count; 65 int count;
54 66
67 struct fiq_handler fiq_handler;
68 enum spi_fiq_mode fiq_mode;
69 unsigned char fiq_inuse;
70 unsigned char fiq_claimed;
71
55 void (*set_cs)(struct s3c2410_spi_info *spi, 72 void (*set_cs)(struct s3c2410_spi_info *spi,
56 int cs, int pol); 73 int cs, int pol);
57 74
@@ -67,6 +84,7 @@ struct s3c24xx_spi {
67 struct s3c2410_spi_info *pdata; 84 struct s3c2410_spi_info *pdata;
68}; 85};
69 86
87
70#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT) 88#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT)
71#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP) 89#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP)
72 90
@@ -127,7 +145,7 @@ static int s3c24xx_spi_update_state(struct spi_device *spi,
127 } 145 }
128 146
129 if (spi->mode != cs->mode) { 147 if (spi->mode != cs->mode) {
130 u8 spcon = SPCON_DEFAULT; 148 u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK;
131 149
132 if (spi->mode & SPI_CPHA) 150 if (spi->mode & SPI_CPHA)
133 spcon |= S3C2410_SPCON_CPHA_FMTB; 151 spcon |= S3C2410_SPCON_CPHA_FMTB;
@@ -214,13 +232,196 @@ static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count)
214 return hw->tx ? hw->tx[count] : 0; 232 return hw->tx ? hw->tx[count] : 0;
215} 233}
216 234
235#ifdef CONFIG_SPI_S3C24XX_FIQ
236/* Support for FIQ based pseudo-DMA to improve the transfer speed.
237 *
238 * This code uses the assembly helper in spi_s3c24xx_spi.S which is
239 * used by the FIQ core to move data between main memory and the peripheral
240 * block. Since this is code running on the processor, there is no problem
241 * with cache coherency of the buffers, so we can use any buffer we like.
242 */
243
244/**
245 * struct spi_fiq_code - FIQ code and header
246 * @length: The length of the code fragment, excluding this header.
247 * @ack_offset: The offset from @data to the word to place the IRQ ACK bit at.
248 * @data: The code itself to install as a FIQ handler.
249 */
250struct spi_fiq_code {
251 u32 length;
252 u32 ack_offset;
253 u8 data[0];
254};
255
256extern struct spi_fiq_code s3c24xx_spi_fiq_txrx;
257extern struct spi_fiq_code s3c24xx_spi_fiq_tx;
258extern struct spi_fiq_code s3c24xx_spi_fiq_rx;
259
260/**
261 * ack_bit - turn IRQ into IRQ acknowledgement bit
262 * @irq: The interrupt number
263 *
264 * Returns the bit to write to the interrupt acknowledge register.
265 */
266static inline u32 ack_bit(unsigned int irq)
267{
268 return 1 << (irq - IRQ_EINT0);
269}
270
271/**
272 * s3c24xx_spi_tryfiq - attempt to claim and setup FIQ for transfer
273 * @hw: The hardware state.
274 *
275 * Claim the FIQ handler (only one can be active at any one time) and
276 * then setup the correct transfer code for this transfer.
277 *
278 * This call updates all the necessary state information if sucessful,
279 * so the caller does not need to do anything more than start the transfer
280 * as normal, since the IRQ will have been re-routed to the FIQ handler.
281*/
282void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw)
283{
284 struct pt_regs regs;
285 enum spi_fiq_mode mode;
286 struct spi_fiq_code *code;
287 int ret;
288
289 if (!hw->fiq_claimed) {
290 /* try and claim fiq if we haven't got it, and if not
291 * then return and simply use another transfer method */
292
293 ret = claim_fiq(&hw->fiq_handler);
294 if (ret)
295 return;
296 }
297
298 if (hw->tx && !hw->rx)
299 mode = FIQ_MODE_TX;
300 else if (hw->rx && !hw->tx)
301 mode = FIQ_MODE_RX;
302 else
303 mode = FIQ_MODE_TXRX;
304
305 regs.uregs[fiq_rspi] = (long)hw->regs;
306 regs.uregs[fiq_rrx] = (long)hw->rx;
307 regs.uregs[fiq_rtx] = (long)hw->tx + 1;
308 regs.uregs[fiq_rcount] = hw->len - 1;
309 regs.uregs[fiq_rirq] = (long)S3C24XX_VA_IRQ;
310
311 set_fiq_regs(&regs);
312
313 if (hw->fiq_mode != mode) {
314 u32 *ack_ptr;
315
316 hw->fiq_mode = mode;
317
318 switch (mode) {
319 case FIQ_MODE_TX:
320 code = &s3c24xx_spi_fiq_tx;
321 break;
322 case FIQ_MODE_RX:
323 code = &s3c24xx_spi_fiq_rx;
324 break;
325 case FIQ_MODE_TXRX:
326 code = &s3c24xx_spi_fiq_txrx;
327 break;
328 default:
329 code = NULL;
330 }
331
332 BUG_ON(!code);
333
334 ack_ptr = (u32 *)&code->data[code->ack_offset];
335 *ack_ptr = ack_bit(hw->irq);
336
337 set_fiq_handler(&code->data, code->length);
338 }
339
340 s3c24xx_set_fiq(hw->irq, true);
341
342 hw->fiq_mode = mode;
343 hw->fiq_inuse = 1;
344}
345
346/**
347 * s3c24xx_spi_fiqop - FIQ core code callback
348 * @pw: Data registered with the handler
349 * @release: Whether this is a release or a return.
350 *
351 * Called by the FIQ code when another module wants to use the FIQ, so
352 * return whether we are currently using this or not and then update our
353 * internal state.
354 */
355static int s3c24xx_spi_fiqop(void *pw, int release)
356{
357 struct s3c24xx_spi *hw = pw;
358 int ret = 0;
359
360 if (release) {
361 if (hw->fiq_inuse)
362 ret = -EBUSY;
363
364 /* note, we do not need to unroute the FIQ, as the FIQ
365 * vector code de-routes it to signal the end of transfer */
366
367 hw->fiq_mode = FIQ_MODE_NONE;
368 hw->fiq_claimed = 0;
369 } else {
370 hw->fiq_claimed = 1;
371 }
372
373 return ret;
374}
375
376/**
377 * s3c24xx_spi_initfiq - setup the information for the FIQ core
378 * @hw: The hardware state.
379 *
380 * Setup the fiq_handler block to pass to the FIQ core.
381 */
382static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *hw)
383{
384 hw->fiq_handler.dev_id = hw;
385 hw->fiq_handler.name = dev_name(hw->dev);
386 hw->fiq_handler.fiq_op = s3c24xx_spi_fiqop;
387}
388
389/**
390 * s3c24xx_spi_usefiq - return if we should be using FIQ.
391 * @hw: The hardware state.
392 *
393 * Return true if the platform data specifies whether this channel is
394 * allowed to use the FIQ.
395 */
396static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *hw)
397{
398 return hw->pdata->use_fiq;
399}
400
401/**
402 * s3c24xx_spi_usingfiq - return if channel is using FIQ
403 * @spi: The hardware state.
404 *
405 * Return whether the channel is currently using the FIQ (separate from
406 * whether the FIQ is claimed).
407 */
408static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *spi)
409{
410 return spi->fiq_inuse;
411}
412#else
413
414static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *s) { }
415static inline void s3c24xx_spi_tryfiq(struct s3c24xx_spi *s) { }
416static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *s) { return false; }
417static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *s) { return false; }
418
419#endif /* CONFIG_SPI_S3C24XX_FIQ */
420
217static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) 421static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
218{ 422{
219 struct s3c24xx_spi *hw = to_hw(spi); 423 struct s3c24xx_spi *hw = to_hw(spi);
220 424
221 dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
222 t->tx_buf, t->rx_buf, t->len);
223
224 hw->tx = t->tx_buf; 425 hw->tx = t->tx_buf;
225 hw->rx = t->rx_buf; 426 hw->rx = t->rx_buf;
226 hw->len = t->len; 427 hw->len = t->len;
@@ -228,11 +429,14 @@ static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
228 429
229 init_completion(&hw->done); 430 init_completion(&hw->done);
230 431
432 hw->fiq_inuse = 0;
433 if (s3c24xx_spi_usefiq(hw) && t->len >= 3)
434 s3c24xx_spi_tryfiq(hw);
435
231 /* send the first byte */ 436 /* send the first byte */
232 writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT); 437 writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT);
233 438
234 wait_for_completion(&hw->done); 439 wait_for_completion(&hw->done);
235
236 return hw->count; 440 return hw->count;
237} 441}
238 442
@@ -254,17 +458,27 @@ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
254 goto irq_done; 458 goto irq_done;
255 } 459 }
256 460
257 hw->count++; 461 if (!s3c24xx_spi_usingfiq(hw)) {
462 hw->count++;
258 463
259 if (hw->rx) 464 if (hw->rx)
260 hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); 465 hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
261 466
262 count++; 467 count++;
468
469 if (count < hw->len)
470 writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
471 else
472 complete(&hw->done);
473 } else {
474 hw->count = hw->len;
475 hw->fiq_inuse = 0;
476
477 if (hw->rx)
478 hw->rx[hw->len-1] = readb(hw->regs + S3C2410_SPRDAT);
263 479
264 if (count < hw->len)
265 writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
266 else
267 complete(&hw->done); 480 complete(&hw->done);
481 }
268 482
269 irq_done: 483 irq_done:
270 return IRQ_HANDLED; 484 return IRQ_HANDLED;
@@ -322,6 +536,10 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev)
322 platform_set_drvdata(pdev, hw); 536 platform_set_drvdata(pdev, hw);
323 init_completion(&hw->done); 537 init_completion(&hw->done);
324 538
539 /* initialise fiq handler */
540
541 s3c24xx_spi_initfiq(hw);
542
325 /* setup the master state. */ 543 /* setup the master state. */
326 544
327 /* the spi->mode bits understood by this driver: */ 545 /* the spi->mode bits understood by this driver: */
diff --git a/drivers/spi/spi_s3c24xx_fiq.S b/drivers/spi/spi_s3c24xx_fiq.S
new file mode 100644
index 000000000000..3793cae361db
--- /dev/null
+++ b/drivers/spi/spi_s3c24xx_fiq.S
@@ -0,0 +1,116 @@
1/* linux/drivers/spi/spi_s3c24xx_fiq.S
2 *
3 * Copyright 2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C24XX SPI - FIQ pseudo-DMA transfer code
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15
16#include <mach/map.h>
17#include <mach/regs-irq.h>
18#include <plat/regs-spi.h>
19
20#include "spi_s3c24xx_fiq.h"
21
22 .text
23
24 @ entry to these routines is as follows, with the register names
25 @ defined in fiq.h so that they can be shared with the C files which
26 @ setup the calling registers.
27 @
28 @ fiq_rirq The base of the IRQ registers to find S3C2410_SRCPND
29 @ fiq_rtmp Temporary register to hold tx/rx data
30 @ fiq_rspi The base of the SPI register block
31 @ fiq_rtx The tx buffer pointer
32 @ fiq_rrx The rx buffer pointer
33 @ fiq_rcount The number of bytes to move
34
35 @ each entry starts with a word entry of how long it is
36 @ and an offset to the irq acknowledgment word
37
38ENTRY(s3c24xx_spi_fiq_rx)
39s3c24xx_spi_fix_rx:
40 .word fiq_rx_end - fiq_rx_start
41 .word fiq_rx_irq_ack - fiq_rx_start
42fiq_rx_start:
43 ldr fiq_rtmp, fiq_rx_irq_ack
44 str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ]
45
46 ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ]
47 strb fiq_rtmp, [ fiq_rrx ], #1
48
49 mov fiq_rtmp, #0xff
50 strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ]
51
52 subs fiq_rcount, fiq_rcount, #1
53 subnes pc, lr, #4 @@ return, still have work to do
54
55 @@ set IRQ controller so that next op will trigger IRQ
56 mov fiq_rtmp, #0
57 str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ]
58 subs pc, lr, #4
59
60fiq_rx_irq_ack:
61 .word 0
62fiq_rx_end:
63
64ENTRY(s3c24xx_spi_fiq_txrx)
65s3c24xx_spi_fiq_txrx:
66 .word fiq_txrx_end - fiq_txrx_start
67 .word fiq_txrx_irq_ack - fiq_txrx_start
68fiq_txrx_start:
69
70 ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ]
71 strb fiq_rtmp, [ fiq_rrx ], #1
72
73 ldr fiq_rtmp, fiq_txrx_irq_ack
74 str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ]
75
76 ldrb fiq_rtmp, [ fiq_rtx ], #1
77 strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ]
78
79 subs fiq_rcount, fiq_rcount, #1
80 subnes pc, lr, #4 @@ return, still have work to do
81
82 mov fiq_rtmp, #0
83 str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ]
84 subs pc, lr, #4
85
86fiq_txrx_irq_ack:
87 .word 0
88
89fiq_txrx_end:
90
91ENTRY(s3c24xx_spi_fiq_tx)
92s3c24xx_spi_fix_tx:
93 .word fiq_tx_end - fiq_tx_start
94 .word fiq_tx_irq_ack - fiq_tx_start
95fiq_tx_start:
96 ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ]
97
98 ldr fiq_rtmp, fiq_tx_irq_ack
99 str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ]
100
101 ldrb fiq_rtmp, [ fiq_rtx ], #1
102 strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ]
103
104 subs fiq_rcount, fiq_rcount, #1
105 subnes pc, lr, #4 @@ return, still have work to do
106
107 mov fiq_rtmp, #0
108 str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ]
109 subs pc, lr, #4
110
111fiq_tx_irq_ack:
112 .word 0
113
114fiq_tx_end:
115
116 .end
diff --git a/drivers/spi/spi_s3c24xx_fiq.h b/drivers/spi/spi_s3c24xx_fiq.h
new file mode 100644
index 000000000000..a5950bb25b51
--- /dev/null
+++ b/drivers/spi/spi_s3c24xx_fiq.h
@@ -0,0 +1,26 @@
1/* linux/drivers/spi/spi_s3c24xx_fiq.h
2 *
3 * Copyright 2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C24XX SPI - FIQ pseudo-DMA transfer support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13/* We have R8 through R13 to play with */
14
15#ifdef __ASSEMBLY__
16#define __REG_NR(x) r##x
17#else
18#define __REG_NR(x) (x)
19#endif
20
21#define fiq_rspi __REG_NR(8)
22#define fiq_rtmp __REG_NR(9)
23#define fiq_rrx __REG_NR(10)
24#define fiq_rtx __REG_NR(11)
25#define fiq_rcount __REG_NR(12)
26#define fiq_rirq __REG_NR(13)
diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
new file mode 100644
index 000000000000..88a456dba967
--- /dev/null
+++ b/drivers/spi/spi_s3c64xx.c
@@ -0,0 +1,1196 @@
1/* linux/drivers/spi/spi_s3c64xx.c
2 *
3 * Copyright (C) 2009 Samsung Electronics Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/workqueue.h>
24#include <linux/delay.h>
25#include <linux/clk.h>
26#include <linux/dma-mapping.h>
27#include <linux/platform_device.h>
28#include <linux/spi/spi.h>
29
30#include <mach/dma.h>
31#include <plat/spi.h>
32
33/* Registers and bit-fields */
34
35#define S3C64XX_SPI_CH_CFG 0x00
36#define S3C64XX_SPI_CLK_CFG 0x04
37#define S3C64XX_SPI_MODE_CFG 0x08
38#define S3C64XX_SPI_SLAVE_SEL 0x0C
39#define S3C64XX_SPI_INT_EN 0x10
40#define S3C64XX_SPI_STATUS 0x14
41#define S3C64XX_SPI_TX_DATA 0x18
42#define S3C64XX_SPI_RX_DATA 0x1C
43#define S3C64XX_SPI_PACKET_CNT 0x20
44#define S3C64XX_SPI_PENDING_CLR 0x24
45#define S3C64XX_SPI_SWAP_CFG 0x28
46#define S3C64XX_SPI_FB_CLK 0x2C
47
48#define S3C64XX_SPI_CH_HS_EN (1<<6) /* High Speed Enable */
49#define S3C64XX_SPI_CH_SW_RST (1<<5)
50#define S3C64XX_SPI_CH_SLAVE (1<<4)
51#define S3C64XX_SPI_CPOL_L (1<<3)
52#define S3C64XX_SPI_CPHA_B (1<<2)
53#define S3C64XX_SPI_CH_RXCH_ON (1<<1)
54#define S3C64XX_SPI_CH_TXCH_ON (1<<0)
55
56#define S3C64XX_SPI_CLKSEL_SRCMSK (3<<9)
57#define S3C64XX_SPI_CLKSEL_SRCSHFT 9
58#define S3C64XX_SPI_ENCLK_ENABLE (1<<8)
59#define S3C64XX_SPI_PSR_MASK 0xff
60
61#define S3C64XX_SPI_MODE_CH_TSZ_BYTE (0<<29)
62#define S3C64XX_SPI_MODE_CH_TSZ_HALFWORD (1<<29)
63#define S3C64XX_SPI_MODE_CH_TSZ_WORD (2<<29)
64#define S3C64XX_SPI_MODE_CH_TSZ_MASK (3<<29)
65#define S3C64XX_SPI_MODE_BUS_TSZ_BYTE (0<<17)
66#define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17)
67#define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17)
68#define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17)
69#define S3C64XX_SPI_MODE_RXDMA_ON (1<<2)
70#define S3C64XX_SPI_MODE_TXDMA_ON (1<<1)
71#define S3C64XX_SPI_MODE_4BURST (1<<0)
72
73#define S3C64XX_SPI_SLAVE_AUTO (1<<1)
74#define S3C64XX_SPI_SLAVE_SIG_INACT (1<<0)
75
76#define S3C64XX_SPI_ACT(c) writel(0, (c)->regs + S3C64XX_SPI_SLAVE_SEL)
77
78#define S3C64XX_SPI_DEACT(c) writel(S3C64XX_SPI_SLAVE_SIG_INACT, \
79 (c)->regs + S3C64XX_SPI_SLAVE_SEL)
80
81#define S3C64XX_SPI_INT_TRAILING_EN (1<<6)
82#define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5)
83#define S3C64XX_SPI_INT_RX_UNDERRUN_EN (1<<4)
84#define S3C64XX_SPI_INT_TX_OVERRUN_EN (1<<3)
85#define S3C64XX_SPI_INT_TX_UNDERRUN_EN (1<<2)
86#define S3C64XX_SPI_INT_RX_FIFORDY_EN (1<<1)
87#define S3C64XX_SPI_INT_TX_FIFORDY_EN (1<<0)
88
89#define S3C64XX_SPI_ST_RX_OVERRUN_ERR (1<<5)
90#define S3C64XX_SPI_ST_RX_UNDERRUN_ERR (1<<4)
91#define S3C64XX_SPI_ST_TX_OVERRUN_ERR (1<<3)
92#define S3C64XX_SPI_ST_TX_UNDERRUN_ERR (1<<2)
93#define S3C64XX_SPI_ST_RX_FIFORDY (1<<1)
94#define S3C64XX_SPI_ST_TX_FIFORDY (1<<0)
95
96#define S3C64XX_SPI_PACKET_CNT_EN (1<<16)
97
98#define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4)
99#define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3)
100#define S3C64XX_SPI_PND_RX_UNDERRUN_CLR (1<<2)
101#define S3C64XX_SPI_PND_RX_OVERRUN_CLR (1<<1)
102#define S3C64XX_SPI_PND_TRAILING_CLR (1<<0)
103
104#define S3C64XX_SPI_SWAP_RX_HALF_WORD (1<<7)
105#define S3C64XX_SPI_SWAP_RX_BYTE (1<<6)
106#define S3C64XX_SPI_SWAP_RX_BIT (1<<5)
107#define S3C64XX_SPI_SWAP_RX_EN (1<<4)
108#define S3C64XX_SPI_SWAP_TX_HALF_WORD (1<<3)
109#define S3C64XX_SPI_SWAP_TX_BYTE (1<<2)
110#define S3C64XX_SPI_SWAP_TX_BIT (1<<1)
111#define S3C64XX_SPI_SWAP_TX_EN (1<<0)
112
113#define S3C64XX_SPI_FBCLK_MSK (3<<0)
114
115#define S3C64XX_SPI_ST_TRLCNTZ(v, i) ((((v) >> (i)->rx_lvl_offset) & \
116 (((i)->fifo_lvl_mask + 1))) \
117 ? 1 : 0)
118
119#define S3C64XX_SPI_ST_TX_DONE(v, i) ((((v) >> (i)->rx_lvl_offset) & \
120 (((i)->fifo_lvl_mask + 1) << 1)) \
121 ? 1 : 0)
122#define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask)
123#define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask)
124
125#define S3C64XX_SPI_MAX_TRAILCNT 0x3ff
126#define S3C64XX_SPI_TRAILCNT_OFF 19
127
128#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
129
130#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
131
132#define SUSPND (1<<0)
133#define SPIBUSY (1<<1)
134#define RXBUSY (1<<2)
135#define TXBUSY (1<<3)
136
137/**
138 * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
139 * @clk: Pointer to the spi clock.
140 * @master: Pointer to the SPI Protocol master.
141 * @workqueue: Work queue for the SPI xfer requests.
142 * @cntrlr_info: Platform specific data for the controller this driver manages.
143 * @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint.
144 * @work: Work
145 * @queue: To log SPI xfer requests.
146 * @lock: Controller specific lock.
147 * @state: Set of FLAGS to indicate status.
148 * @rx_dmach: Controller's DMA channel for Rx.
149 * @tx_dmach: Controller's DMA channel for Tx.
150 * @sfr_start: BUS address of SPI controller regs.
151 * @regs: Pointer to ioremap'ed controller registers.
152 * @xfer_completion: To indicate completion of xfer task.
153 * @cur_mode: Stores the active configuration of the controller.
154 * @cur_bpw: Stores the active bits per word settings.
155 * @cur_speed: Stores the active xfer clock speed.
156 */
157struct s3c64xx_spi_driver_data {
158 void __iomem *regs;
159 struct clk *clk;
160 struct platform_device *pdev;
161 struct spi_master *master;
162 struct workqueue_struct *workqueue;
163 struct s3c64xx_spi_cntrlr_info *cntrlr_info;
164 struct spi_device *tgl_spi;
165 struct work_struct work;
166 struct list_head queue;
167 spinlock_t lock;
168 enum dma_ch rx_dmach;
169 enum dma_ch tx_dmach;
170 unsigned long sfr_start;
171 struct completion xfer_completion;
172 unsigned state;
173 unsigned cur_mode, cur_bpw;
174 unsigned cur_speed;
175};
176
177static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
178 .name = "samsung-spi-dma",
179};
180
181static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
182{
183 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
184 void __iomem *regs = sdd->regs;
185 unsigned long loops;
186 u32 val;
187
188 writel(0, regs + S3C64XX_SPI_PACKET_CNT);
189
190 val = readl(regs + S3C64XX_SPI_CH_CFG);
191 val |= S3C64XX_SPI_CH_SW_RST;
192 val &= ~S3C64XX_SPI_CH_HS_EN;
193 writel(val, regs + S3C64XX_SPI_CH_CFG);
194
195 /* Flush TxFIFO*/
196 loops = msecs_to_loops(1);
197 do {
198 val = readl(regs + S3C64XX_SPI_STATUS);
199 } while (TX_FIFO_LVL(val, sci) && loops--);
200
201 /* Flush RxFIFO*/
202 loops = msecs_to_loops(1);
203 do {
204 val = readl(regs + S3C64XX_SPI_STATUS);
205 if (RX_FIFO_LVL(val, sci))
206 readl(regs + S3C64XX_SPI_RX_DATA);
207 else
208 break;
209 } while (loops--);
210
211 val = readl(regs + S3C64XX_SPI_CH_CFG);
212 val &= ~S3C64XX_SPI_CH_SW_RST;
213 writel(val, regs + S3C64XX_SPI_CH_CFG);
214
215 val = readl(regs + S3C64XX_SPI_MODE_CFG);
216 val &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
217 writel(val, regs + S3C64XX_SPI_MODE_CFG);
218
219 val = readl(regs + S3C64XX_SPI_CH_CFG);
220 val &= ~(S3C64XX_SPI_CH_RXCH_ON | S3C64XX_SPI_CH_TXCH_ON);
221 writel(val, regs + S3C64XX_SPI_CH_CFG);
222}
223
224static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
225 struct spi_device *spi,
226 struct spi_transfer *xfer, int dma_mode)
227{
228 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
229 void __iomem *regs = sdd->regs;
230 u32 modecfg, chcfg;
231
232 modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
233 modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
234
235 chcfg = readl(regs + S3C64XX_SPI_CH_CFG);
236 chcfg &= ~S3C64XX_SPI_CH_TXCH_ON;
237
238 if (dma_mode) {
239 chcfg &= ~S3C64XX_SPI_CH_RXCH_ON;
240 } else {
241 /* Always shift in data in FIFO, even if xfer is Tx only,
242 * this helps setting PCKT_CNT value for generating clocks
243 * as exactly needed.
244 */
245 chcfg |= S3C64XX_SPI_CH_RXCH_ON;
246 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
247 | S3C64XX_SPI_PACKET_CNT_EN,
248 regs + S3C64XX_SPI_PACKET_CNT);
249 }
250
251 if (xfer->tx_buf != NULL) {
252 sdd->state |= TXBUSY;
253 chcfg |= S3C64XX_SPI_CH_TXCH_ON;
254 if (dma_mode) {
255 modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
256 s3c2410_dma_config(sdd->tx_dmach, 1);
257 s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
258 xfer->tx_dma, xfer->len);
259 s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
260 } else {
261 unsigned char *buf = (unsigned char *) xfer->tx_buf;
262 int i = 0;
263 while (i < xfer->len)
264 writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA);
265 }
266 }
267
268 if (xfer->rx_buf != NULL) {
269 sdd->state |= RXBUSY;
270
271 if (sci->high_speed && sdd->cur_speed >= 30000000UL
272 && !(sdd->cur_mode & SPI_CPHA))
273 chcfg |= S3C64XX_SPI_CH_HS_EN;
274
275 if (dma_mode) {
276 modecfg |= S3C64XX_SPI_MODE_RXDMA_ON;
277 chcfg |= S3C64XX_SPI_CH_RXCH_ON;
278 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
279 | S3C64XX_SPI_PACKET_CNT_EN,
280 regs + S3C64XX_SPI_PACKET_CNT);
281 s3c2410_dma_config(sdd->rx_dmach, 1);
282 s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
283 xfer->rx_dma, xfer->len);
284 s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
285 }
286 }
287
288 writel(modecfg, regs + S3C64XX_SPI_MODE_CFG);
289 writel(chcfg, regs + S3C64XX_SPI_CH_CFG);
290}
291
292static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
293 struct spi_device *spi)
294{
295 struct s3c64xx_spi_csinfo *cs;
296
297 if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */
298 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
299 /* Deselect the last toggled device */
300 cs = sdd->tgl_spi->controller_data;
301 cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1);
302 }
303 sdd->tgl_spi = NULL;
304 }
305
306 cs = spi->controller_data;
307 cs->set_level(spi->mode & SPI_CS_HIGH ? 1 : 0);
308}
309
310static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
311 struct spi_transfer *xfer, int dma_mode)
312{
313 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
314 void __iomem *regs = sdd->regs;
315 unsigned long val;
316 int ms;
317
318 /* millisecs to xfer 'len' bytes @ 'cur_speed' */
319 ms = xfer->len * 8 * 1000 / sdd->cur_speed;
320 ms += 5; /* some tolerance */
321
322 if (dma_mode) {
323 val = msecs_to_jiffies(ms) + 10;
324 val = wait_for_completion_timeout(&sdd->xfer_completion, val);
325 } else {
326 val = msecs_to_loops(ms);
327 do {
328 val = readl(regs + S3C64XX_SPI_STATUS);
329 } while (RX_FIFO_LVL(val, sci) < xfer->len && --val);
330 }
331
332 if (!val)
333 return -EIO;
334
335 if (dma_mode) {
336 u32 status;
337
338 /*
339 * DmaTx returns after simply writing data in the FIFO,
340 * w/o waiting for real transmission on the bus to finish.
341 * DmaRx returns only after Dma read data from FIFO which
342 * needs bus transmission to finish, so we don't worry if
343 * Xfer involved Rx(with or without Tx).
344 */
345 if (xfer->rx_buf == NULL) {
346 val = msecs_to_loops(10);
347 status = readl(regs + S3C64XX_SPI_STATUS);
348 while ((TX_FIFO_LVL(status, sci)
349 || !S3C64XX_SPI_ST_TX_DONE(status, sci))
350 && --val) {
351 cpu_relax();
352 status = readl(regs + S3C64XX_SPI_STATUS);
353 }
354
355 if (!val)
356 return -EIO;
357 }
358 } else {
359 unsigned char *buf;
360 int i;
361
362 /* If it was only Tx */
363 if (xfer->rx_buf == NULL) {
364 sdd->state &= ~TXBUSY;
365 return 0;
366 }
367
368 i = 0;
369 buf = xfer->rx_buf;
370 while (i < xfer->len)
371 buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA);
372
373 sdd->state &= ~RXBUSY;
374 }
375
376 return 0;
377}
378
379static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
380 struct spi_device *spi)
381{
382 struct s3c64xx_spi_csinfo *cs = spi->controller_data;
383
384 if (sdd->tgl_spi == spi)
385 sdd->tgl_spi = NULL;
386
387 cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1);
388}
389
390static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
391{
392 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
393 void __iomem *regs = sdd->regs;
394 u32 val;
395
396 /* Disable Clock */
397 val = readl(regs + S3C64XX_SPI_CLK_CFG);
398 val &= ~S3C64XX_SPI_ENCLK_ENABLE;
399 writel(val, regs + S3C64XX_SPI_CLK_CFG);
400
401 /* Set Polarity and Phase */
402 val = readl(regs + S3C64XX_SPI_CH_CFG);
403 val &= ~(S3C64XX_SPI_CH_SLAVE |
404 S3C64XX_SPI_CPOL_L |
405 S3C64XX_SPI_CPHA_B);
406
407 if (sdd->cur_mode & SPI_CPOL)
408 val |= S3C64XX_SPI_CPOL_L;
409
410 if (sdd->cur_mode & SPI_CPHA)
411 val |= S3C64XX_SPI_CPHA_B;
412
413 writel(val, regs + S3C64XX_SPI_CH_CFG);
414
415 /* Set Channel & DMA Mode */
416 val = readl(regs + S3C64XX_SPI_MODE_CFG);
417 val &= ~(S3C64XX_SPI_MODE_BUS_TSZ_MASK
418 | S3C64XX_SPI_MODE_CH_TSZ_MASK);
419
420 switch (sdd->cur_bpw) {
421 case 32:
422 val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
423 break;
424 case 16:
425 val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
426 break;
427 default:
428 val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
429 break;
430 }
431 val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */
432
433 writel(val, regs + S3C64XX_SPI_MODE_CFG);
434
435 /* Configure Clock */
436 val = readl(regs + S3C64XX_SPI_CLK_CFG);
437 val &= ~S3C64XX_SPI_PSR_MASK;
438 val |= ((clk_get_rate(sci->src_clk) / sdd->cur_speed / 2 - 1)
439 & S3C64XX_SPI_PSR_MASK);
440 writel(val, regs + S3C64XX_SPI_CLK_CFG);
441
442 /* Enable Clock */
443 val = readl(regs + S3C64XX_SPI_CLK_CFG);
444 val |= S3C64XX_SPI_ENCLK_ENABLE;
445 writel(val, regs + S3C64XX_SPI_CLK_CFG);
446}
447
448void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
449 int size, enum s3c2410_dma_buffresult res)
450{
451 struct s3c64xx_spi_driver_data *sdd = buf_id;
452 unsigned long flags;
453
454 spin_lock_irqsave(&sdd->lock, flags);
455
456 if (res == S3C2410_RES_OK)
457 sdd->state &= ~RXBUSY;
458 else
459 dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
460
461 /* If the other done */
462 if (!(sdd->state & TXBUSY))
463 complete(&sdd->xfer_completion);
464
465 spin_unlock_irqrestore(&sdd->lock, flags);
466}
467
468void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
469 int size, enum s3c2410_dma_buffresult res)
470{
471 struct s3c64xx_spi_driver_data *sdd = buf_id;
472 unsigned long flags;
473
474 spin_lock_irqsave(&sdd->lock, flags);
475
476 if (res == S3C2410_RES_OK)
477 sdd->state &= ~TXBUSY;
478 else
479 dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size);
480
481 /* If the other done */
482 if (!(sdd->state & RXBUSY))
483 complete(&sdd->xfer_completion);
484
485 spin_unlock_irqrestore(&sdd->lock, flags);
486}
487
488#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
489
490static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
491 struct spi_message *msg)
492{
493 struct device *dev = &sdd->pdev->dev;
494 struct spi_transfer *xfer;
495
496 if (msg->is_dma_mapped)
497 return 0;
498
499 /* First mark all xfer unmapped */
500 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
501 xfer->rx_dma = XFER_DMAADDR_INVALID;
502 xfer->tx_dma = XFER_DMAADDR_INVALID;
503 }
504
505 /* Map until end or first fail */
506 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
507
508 if (xfer->tx_buf != NULL) {
509 xfer->tx_dma = dma_map_single(dev, xfer->tx_buf,
510 xfer->len, DMA_TO_DEVICE);
511 if (dma_mapping_error(dev, xfer->tx_dma)) {
512 dev_err(dev, "dma_map_single Tx failed\n");
513 xfer->tx_dma = XFER_DMAADDR_INVALID;
514 return -ENOMEM;
515 }
516 }
517
518 if (xfer->rx_buf != NULL) {
519 xfer->rx_dma = dma_map_single(dev, xfer->rx_buf,
520 xfer->len, DMA_FROM_DEVICE);
521 if (dma_mapping_error(dev, xfer->rx_dma)) {
522 dev_err(dev, "dma_map_single Rx failed\n");
523 dma_unmap_single(dev, xfer->tx_dma,
524 xfer->len, DMA_TO_DEVICE);
525 xfer->tx_dma = XFER_DMAADDR_INVALID;
526 xfer->rx_dma = XFER_DMAADDR_INVALID;
527 return -ENOMEM;
528 }
529 }
530 }
531
532 return 0;
533}
534
535static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
536 struct spi_message *msg)
537{
538 struct device *dev = &sdd->pdev->dev;
539 struct spi_transfer *xfer;
540
541 if (msg->is_dma_mapped)
542 return;
543
544 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
545
546 if (xfer->rx_buf != NULL
547 && xfer->rx_dma != XFER_DMAADDR_INVALID)
548 dma_unmap_single(dev, xfer->rx_dma,
549 xfer->len, DMA_FROM_DEVICE);
550
551 if (xfer->tx_buf != NULL
552 && xfer->tx_dma != XFER_DMAADDR_INVALID)
553 dma_unmap_single(dev, xfer->tx_dma,
554 xfer->len, DMA_TO_DEVICE);
555 }
556}
557
558static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
559 struct spi_message *msg)
560{
561 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
562 struct spi_device *spi = msg->spi;
563 struct s3c64xx_spi_csinfo *cs = spi->controller_data;
564 struct spi_transfer *xfer;
565 int status = 0, cs_toggle = 0;
566 u32 speed;
567 u8 bpw;
568
569 /* If Master's(controller) state differs from that needed by Slave */
570 if (sdd->cur_speed != spi->max_speed_hz
571 || sdd->cur_mode != spi->mode
572 || sdd->cur_bpw != spi->bits_per_word) {
573 sdd->cur_bpw = spi->bits_per_word;
574 sdd->cur_speed = spi->max_speed_hz;
575 sdd->cur_mode = spi->mode;
576 s3c64xx_spi_config(sdd);
577 }
578
579 /* Map all the transfers if needed */
580 if (s3c64xx_spi_map_mssg(sdd, msg)) {
581 dev_err(&spi->dev,
582 "Xfer: Unable to map message buffers!\n");
583 status = -ENOMEM;
584 goto out;
585 }
586
587 /* Configure feedback delay */
588 writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK);
589
590 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
591
592 unsigned long flags;
593 int use_dma;
594
595 INIT_COMPLETION(sdd->xfer_completion);
596
597 /* Only BPW and Speed may change across transfers */
598 bpw = xfer->bits_per_word ? : spi->bits_per_word;
599 speed = xfer->speed_hz ? : spi->max_speed_hz;
600
601 if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
602 sdd->cur_bpw = bpw;
603 sdd->cur_speed = speed;
604 s3c64xx_spi_config(sdd);
605 }
606
607 /* Polling method for xfers not bigger than FIFO capacity */
608 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1))
609 use_dma = 0;
610 else
611 use_dma = 1;
612
613 spin_lock_irqsave(&sdd->lock, flags);
614
615 /* Pending only which is to be done */
616 sdd->state &= ~RXBUSY;
617 sdd->state &= ~TXBUSY;
618
619 enable_datapath(sdd, spi, xfer, use_dma);
620
621 /* Slave Select */
622 enable_cs(sdd, spi);
623
624 /* Start the signals */
625 S3C64XX_SPI_ACT(sdd);
626
627 spin_unlock_irqrestore(&sdd->lock, flags);
628
629 status = wait_for_xfer(sdd, xfer, use_dma);
630
631 /* Quiese the signals */
632 S3C64XX_SPI_DEACT(sdd);
633
634 if (status) {
635 dev_err(&spi->dev, "I/O Error: \
636 rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
637 xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
638 (sdd->state & RXBUSY) ? 'f' : 'p',
639 (sdd->state & TXBUSY) ? 'f' : 'p',
640 xfer->len);
641
642 if (use_dma) {
643 if (xfer->tx_buf != NULL
644 && (sdd->state & TXBUSY))
645 s3c2410_dma_ctrl(sdd->tx_dmach,
646 S3C2410_DMAOP_FLUSH);
647 if (xfer->rx_buf != NULL
648 && (sdd->state & RXBUSY))
649 s3c2410_dma_ctrl(sdd->rx_dmach,
650 S3C2410_DMAOP_FLUSH);
651 }
652
653 goto out;
654 }
655
656 if (xfer->delay_usecs)
657 udelay(xfer->delay_usecs);
658
659 if (xfer->cs_change) {
660 /* Hint that the next mssg is gonna be
661 for the same device */
662 if (list_is_last(&xfer->transfer_list,
663 &msg->transfers))
664 cs_toggle = 1;
665 else
666 disable_cs(sdd, spi);
667 }
668
669 msg->actual_length += xfer->len;
670
671 flush_fifo(sdd);
672 }
673
674out:
675 if (!cs_toggle || status)
676 disable_cs(sdd, spi);
677 else
678 sdd->tgl_spi = spi;
679
680 s3c64xx_spi_unmap_mssg(sdd, msg);
681
682 msg->status = status;
683
684 if (msg->complete)
685 msg->complete(msg->context);
686}
687
688static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
689{
690 if (s3c2410_dma_request(sdd->rx_dmach,
691 &s3c64xx_spi_dma_client, NULL) < 0) {
692 dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
693 return 0;
694 }
695 s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb);
696 s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW,
697 sdd->sfr_start + S3C64XX_SPI_RX_DATA);
698
699 if (s3c2410_dma_request(sdd->tx_dmach,
700 &s3c64xx_spi_dma_client, NULL) < 0) {
701 dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
702 s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
703 return 0;
704 }
705 s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb);
706 s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM,
707 sdd->sfr_start + S3C64XX_SPI_TX_DATA);
708
709 return 1;
710}
711
712static void s3c64xx_spi_work(struct work_struct *work)
713{
714 struct s3c64xx_spi_driver_data *sdd = container_of(work,
715 struct s3c64xx_spi_driver_data, work);
716 unsigned long flags;
717
718 /* Acquire DMA channels */
719 while (!acquire_dma(sdd))
720 msleep(10);
721
722 spin_lock_irqsave(&sdd->lock, flags);
723
724 while (!list_empty(&sdd->queue)
725 && !(sdd->state & SUSPND)) {
726
727 struct spi_message *msg;
728
729 msg = container_of(sdd->queue.next, struct spi_message, queue);
730
731 list_del_init(&msg->queue);
732
733 /* Set Xfer busy flag */
734 sdd->state |= SPIBUSY;
735
736 spin_unlock_irqrestore(&sdd->lock, flags);
737
738 handle_msg(sdd, msg);
739
740 spin_lock_irqsave(&sdd->lock, flags);
741
742 sdd->state &= ~SPIBUSY;
743 }
744
745 spin_unlock_irqrestore(&sdd->lock, flags);
746
747 /* Free DMA channels */
748 s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
749 s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
750}
751
752static int s3c64xx_spi_transfer(struct spi_device *spi,
753 struct spi_message *msg)
754{
755 struct s3c64xx_spi_driver_data *sdd;
756 unsigned long flags;
757
758 sdd = spi_master_get_devdata(spi->master);
759
760 spin_lock_irqsave(&sdd->lock, flags);
761
762 if (sdd->state & SUSPND) {
763 spin_unlock_irqrestore(&sdd->lock, flags);
764 return -ESHUTDOWN;
765 }
766
767 msg->status = -EINPROGRESS;
768 msg->actual_length = 0;
769
770 list_add_tail(&msg->queue, &sdd->queue);
771
772 queue_work(sdd->workqueue, &sdd->work);
773
774 spin_unlock_irqrestore(&sdd->lock, flags);
775
776 return 0;
777}
778
779/*
780 * Here we only check the validity of requested configuration
781 * and save the configuration in a local data-structure.
782 * The controller is actually configured only just before we
783 * get a message to transfer.
784 */
785static int s3c64xx_spi_setup(struct spi_device *spi)
786{
787 struct s3c64xx_spi_csinfo *cs = spi->controller_data;
788 struct s3c64xx_spi_driver_data *sdd;
789 struct s3c64xx_spi_cntrlr_info *sci;
790 struct spi_message *msg;
791 u32 psr, speed;
792 unsigned long flags;
793 int err = 0;
794
795 if (cs == NULL || cs->set_level == NULL) {
796 dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select);
797 return -ENODEV;
798 }
799
800 sdd = spi_master_get_devdata(spi->master);
801 sci = sdd->cntrlr_info;
802
803 spin_lock_irqsave(&sdd->lock, flags);
804
805 list_for_each_entry(msg, &sdd->queue, queue) {
806 /* Is some mssg is already queued for this device */
807 if (msg->spi == spi) {
808 dev_err(&spi->dev,
809 "setup: attempt while mssg in queue!\n");
810 spin_unlock_irqrestore(&sdd->lock, flags);
811 return -EBUSY;
812 }
813 }
814
815 if (sdd->state & SUSPND) {
816 spin_unlock_irqrestore(&sdd->lock, flags);
817 dev_err(&spi->dev,
818 "setup: SPI-%d not active!\n", spi->master->bus_num);
819 return -ESHUTDOWN;
820 }
821
822 spin_unlock_irqrestore(&sdd->lock, flags);
823
824 if (spi->bits_per_word != 8
825 && spi->bits_per_word != 16
826 && spi->bits_per_word != 32) {
827 dev_err(&spi->dev, "setup: %dbits/wrd not supported!\n",
828 spi->bits_per_word);
829 err = -EINVAL;
830 goto setup_exit;
831 }
832
833 /* Check if we can provide the requested rate */
834 speed = clk_get_rate(sci->src_clk) / 2 / (0 + 1); /* Max possible */
835
836 if (spi->max_speed_hz > speed)
837 spi->max_speed_hz = speed;
838
839 psr = clk_get_rate(sci->src_clk) / 2 / spi->max_speed_hz - 1;
840 psr &= S3C64XX_SPI_PSR_MASK;
841 if (psr == S3C64XX_SPI_PSR_MASK)
842 psr--;
843
844 speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1);
845 if (spi->max_speed_hz < speed) {
846 if (psr+1 < S3C64XX_SPI_PSR_MASK) {
847 psr++;
848 } else {
849 err = -EINVAL;
850 goto setup_exit;
851 }
852 }
853
854 speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1);
855 if (spi->max_speed_hz >= speed)
856 spi->max_speed_hz = speed;
857 else
858 err = -EINVAL;
859
860setup_exit:
861
862 /* setup() returns with device de-selected */
863 disable_cs(sdd, spi);
864
865 return err;
866}
867
868static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
869{
870 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
871 void __iomem *regs = sdd->regs;
872 unsigned int val;
873
874 sdd->cur_speed = 0;
875
876 S3C64XX_SPI_DEACT(sdd);
877
878 /* Disable Interrupts - we use Polling if not DMA mode */
879 writel(0, regs + S3C64XX_SPI_INT_EN);
880
881 writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT,
882 regs + S3C64XX_SPI_CLK_CFG);
883 writel(0, regs + S3C64XX_SPI_MODE_CFG);
884 writel(0, regs + S3C64XX_SPI_PACKET_CNT);
885
886 /* Clear any irq pending bits */
887 writel(readl(regs + S3C64XX_SPI_PENDING_CLR),
888 regs + S3C64XX_SPI_PENDING_CLR);
889
890 writel(0, regs + S3C64XX_SPI_SWAP_CFG);
891
892 val = readl(regs + S3C64XX_SPI_MODE_CFG);
893 val &= ~S3C64XX_SPI_MODE_4BURST;
894 val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
895 val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
896 writel(val, regs + S3C64XX_SPI_MODE_CFG);
897
898 flush_fifo(sdd);
899}
900
901static int __init s3c64xx_spi_probe(struct platform_device *pdev)
902{
903 struct resource *mem_res, *dmatx_res, *dmarx_res;
904 struct s3c64xx_spi_driver_data *sdd;
905 struct s3c64xx_spi_cntrlr_info *sci;
906 struct spi_master *master;
907 int ret;
908
909 if (pdev->id < 0) {
910 dev_err(&pdev->dev,
911 "Invalid platform device id-%d\n", pdev->id);
912 return -ENODEV;
913 }
914
915 if (pdev->dev.platform_data == NULL) {
916 dev_err(&pdev->dev, "platform_data missing!\n");
917 return -ENODEV;
918 }
919
920 /* Check for availability of necessary resource */
921
922 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
923 if (dmatx_res == NULL) {
924 dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n");
925 return -ENXIO;
926 }
927
928 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
929 if (dmarx_res == NULL) {
930 dev_err(&pdev->dev, "Unable to get SPI-Rx dma resource\n");
931 return -ENXIO;
932 }
933
934 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
935 if (mem_res == NULL) {
936 dev_err(&pdev->dev, "Unable to get SPI MEM resource\n");
937 return -ENXIO;
938 }
939
940 master = spi_alloc_master(&pdev->dev,
941 sizeof(struct s3c64xx_spi_driver_data));
942 if (master == NULL) {
943 dev_err(&pdev->dev, "Unable to allocate SPI Master\n");
944 return -ENOMEM;
945 }
946
947 sci = pdev->dev.platform_data;
948
949 platform_set_drvdata(pdev, master);
950
951 sdd = spi_master_get_devdata(master);
952 sdd->master = master;
953 sdd->cntrlr_info = sci;
954 sdd->pdev = pdev;
955 sdd->sfr_start = mem_res->start;
956 sdd->tx_dmach = dmatx_res->start;
957 sdd->rx_dmach = dmarx_res->start;
958
959 sdd->cur_bpw = 8;
960
961 master->bus_num = pdev->id;
962 master->setup = s3c64xx_spi_setup;
963 master->transfer = s3c64xx_spi_transfer;
964 master->num_chipselect = sci->num_cs;
965 master->dma_alignment = 8;
966 /* the spi->mode bits understood by this driver: */
967 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
968
969 if (request_mem_region(mem_res->start,
970 resource_size(mem_res), pdev->name) == NULL) {
971 dev_err(&pdev->dev, "Req mem region failed\n");
972 ret = -ENXIO;
973 goto err0;
974 }
975
976 sdd->regs = ioremap(mem_res->start, resource_size(mem_res));
977 if (sdd->regs == NULL) {
978 dev_err(&pdev->dev, "Unable to remap IO\n");
979 ret = -ENXIO;
980 goto err1;
981 }
982
983 if (sci->cfg_gpio == NULL || sci->cfg_gpio(pdev)) {
984 dev_err(&pdev->dev, "Unable to config gpio\n");
985 ret = -EBUSY;
986 goto err2;
987 }
988
989 /* Setup clocks */
990 sdd->clk = clk_get(&pdev->dev, "spi");
991 if (IS_ERR(sdd->clk)) {
992 dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n");
993 ret = PTR_ERR(sdd->clk);
994 goto err3;
995 }
996
997 if (clk_enable(sdd->clk)) {
998 dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n");
999 ret = -EBUSY;
1000 goto err4;
1001 }
1002
1003 if (sci->src_clk_nr == S3C64XX_SPI_SRCCLK_PCLK)
1004 sci->src_clk = sdd->clk;
1005 else
1006 sci->src_clk = clk_get(&pdev->dev, sci->src_clk_name);
1007 if (IS_ERR(sci->src_clk)) {
1008 dev_err(&pdev->dev,
1009 "Unable to acquire clock '%s'\n", sci->src_clk_name);
1010 ret = PTR_ERR(sci->src_clk);
1011 goto err5;
1012 }
1013
1014 if (sci->src_clk != sdd->clk && clk_enable(sci->src_clk)) {
1015 dev_err(&pdev->dev, "Couldn't enable clock '%s'\n",
1016 sci->src_clk_name);
1017 ret = -EBUSY;
1018 goto err6;
1019 }
1020
1021 sdd->workqueue = create_singlethread_workqueue(
1022 dev_name(master->dev.parent));
1023 if (sdd->workqueue == NULL) {
1024 dev_err(&pdev->dev, "Unable to create workqueue\n");
1025 ret = -ENOMEM;
1026 goto err7;
1027 }
1028
1029 /* Setup Deufult Mode */
1030 s3c64xx_spi_hwinit(sdd, pdev->id);
1031
1032 spin_lock_init(&sdd->lock);
1033 init_completion(&sdd->xfer_completion);
1034 INIT_WORK(&sdd->work, s3c64xx_spi_work);
1035 INIT_LIST_HEAD(&sdd->queue);
1036
1037 if (spi_register_master(master)) {
1038 dev_err(&pdev->dev, "cannot register SPI master\n");
1039 ret = -EBUSY;
1040 goto err8;
1041 }
1042
1043 dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d \
1044 with %d Slaves attached\n",
1045 pdev->id, master->num_chipselect);
1046 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\
1047 \tDMA=[Rx-%d, Tx-%d]\n",
1048 mem_res->end, mem_res->start,
1049 sdd->rx_dmach, sdd->tx_dmach);
1050
1051 return 0;
1052
1053err8:
1054 destroy_workqueue(sdd->workqueue);
1055err7:
1056 if (sci->src_clk != sdd->clk)
1057 clk_disable(sci->src_clk);
1058err6:
1059 if (sci->src_clk != sdd->clk)
1060 clk_put(sci->src_clk);
1061err5:
1062 clk_disable(sdd->clk);
1063err4:
1064 clk_put(sdd->clk);
1065err3:
1066err2:
1067 iounmap((void *) sdd->regs);
1068err1:
1069 release_mem_region(mem_res->start, resource_size(mem_res));
1070err0:
1071 platform_set_drvdata(pdev, NULL);
1072 spi_master_put(master);
1073
1074 return ret;
1075}
1076
1077static int s3c64xx_spi_remove(struct platform_device *pdev)
1078{
1079 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
1080 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1081 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
1082 struct resource *mem_res;
1083 unsigned long flags;
1084
1085 spin_lock_irqsave(&sdd->lock, flags);
1086 sdd->state |= SUSPND;
1087 spin_unlock_irqrestore(&sdd->lock, flags);
1088
1089 while (sdd->state & SPIBUSY)
1090 msleep(10);
1091
1092 spi_unregister_master(master);
1093
1094 destroy_workqueue(sdd->workqueue);
1095
1096 if (sci->src_clk != sdd->clk)
1097 clk_disable(sci->src_clk);
1098
1099 if (sci->src_clk != sdd->clk)
1100 clk_put(sci->src_clk);
1101
1102 clk_disable(sdd->clk);
1103 clk_put(sdd->clk);
1104
1105 iounmap((void *) sdd->regs);
1106
1107 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1108 release_mem_region(mem_res->start, resource_size(mem_res));
1109
1110 platform_set_drvdata(pdev, NULL);
1111 spi_master_put(master);
1112
1113 return 0;
1114}
1115
1116#ifdef CONFIG_PM
1117static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
1118{
1119 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
1120 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1121 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
1122 struct s3c64xx_spi_csinfo *cs;
1123 unsigned long flags;
1124
1125 spin_lock_irqsave(&sdd->lock, flags);
1126 sdd->state |= SUSPND;
1127 spin_unlock_irqrestore(&sdd->lock, flags);
1128
1129 while (sdd->state & SPIBUSY)
1130 msleep(10);
1131
1132 /* Disable the clock */
1133 if (sci->src_clk != sdd->clk)
1134 clk_disable(sci->src_clk);
1135
1136 clk_disable(sdd->clk);
1137
1138 sdd->cur_speed = 0; /* Output Clock is stopped */
1139
1140 return 0;
1141}
1142
1143static int s3c64xx_spi_resume(struct platform_device *pdev)
1144{
1145 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
1146 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1147 struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info;
1148 unsigned long flags;
1149
1150 sci->cfg_gpio(pdev);
1151
1152 /* Enable the clock */
1153 if (sci->src_clk != sdd->clk)
1154 clk_enable(sci->src_clk);
1155
1156 clk_enable(sdd->clk);
1157
1158 s3c64xx_spi_hwinit(sdd, pdev->id);
1159
1160 spin_lock_irqsave(&sdd->lock, flags);
1161 sdd->state &= ~SUSPND;
1162 spin_unlock_irqrestore(&sdd->lock, flags);
1163
1164 return 0;
1165}
1166#else
1167#define s3c64xx_spi_suspend NULL
1168#define s3c64xx_spi_resume NULL
1169#endif /* CONFIG_PM */
1170
1171static struct platform_driver s3c64xx_spi_driver = {
1172 .driver = {
1173 .name = "s3c64xx-spi",
1174 .owner = THIS_MODULE,
1175 },
1176 .remove = s3c64xx_spi_remove,
1177 .suspend = s3c64xx_spi_suspend,
1178 .resume = s3c64xx_spi_resume,
1179};
1180MODULE_ALIAS("platform:s3c64xx-spi");
1181
1182static int __init s3c64xx_spi_init(void)
1183{
1184 return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe);
1185}
1186module_init(s3c64xx_spi_init);
1187
1188static void __exit s3c64xx_spi_exit(void)
1189{
1190 platform_driver_unregister(&s3c64xx_spi_driver);
1191}
1192module_exit(s3c64xx_spi_exit);
1193
1194MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
1195MODULE_DESCRIPTION("S3C64XX SPI Controller Driver");
1196MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi_sh_sci.c b/drivers/spi/spi_sh_sci.c
index 7d36720eb982..a65c12ffa733 100644
--- a/drivers/spi/spi_sh_sci.c
+++ b/drivers/spi/spi_sh_sci.c
@@ -148,7 +148,7 @@ static int sh_sci_spi_probe(struct platform_device *dev)
148 ret = -ENOENT; 148 ret = -ENOENT;
149 goto err1; 149 goto err1;
150 } 150 }
151 sp->membase = ioremap(r->start, r->end - r->start + 1); 151 sp->membase = ioremap(r->start, resource_size(r));
152 if (!sp->membase) { 152 if (!sp->membase) {
153 ret = -ENXIO; 153 ret = -ENXIO;
154 goto err1; 154 goto err1;
diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c
index 19f75627c3de..dfa024b633e1 100644
--- a/drivers/spi/spi_txx9.c
+++ b/drivers/spi/spi_txx9.c
@@ -375,12 +375,10 @@ static int __init txx9spi_probe(struct platform_device *dev)
375 res = platform_get_resource(dev, IORESOURCE_MEM, 0); 375 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
376 if (!res) 376 if (!res)
377 goto exit_busy; 377 goto exit_busy;
378 if (!devm_request_mem_region(&dev->dev, 378 if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res),
379 res->start, res->end - res->start + 1,
380 "spi_txx9")) 379 "spi_txx9"))
381 goto exit_busy; 380 goto exit_busy;
382 c->membase = devm_ioremap(&dev->dev, 381 c->membase = devm_ioremap(&dev->dev, res->start, resource_size(res));
383 res->start, res->end - res->start + 1);
384 if (!c->membase) 382 if (!c->membase)
385 goto exit_busy; 383 goto exit_busy;
386 384
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 9c446e6003d5..ea1bec3c9a13 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -53,7 +53,7 @@
53#define SPIDEV_MAJOR 153 /* assigned */ 53#define SPIDEV_MAJOR 153 /* assigned */
54#define N_SPI_MINORS 32 /* ... up to 256 */ 54#define N_SPI_MINORS 32 /* ... up to 256 */
55 55
56static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; 56static DECLARE_BITMAP(minors, N_SPI_MINORS);
57 57
58 58
59/* Bit masks for spi_device.mode management. Note that incorrect 59/* Bit masks for spi_device.mode management. Note that incorrect
@@ -558,7 +558,7 @@ static struct class *spidev_class;
558 558
559/*-------------------------------------------------------------------------*/ 559/*-------------------------------------------------------------------------*/
560 560
561static int spidev_probe(struct spi_device *spi) 561static int __devinit spidev_probe(struct spi_device *spi)
562{ 562{
563 struct spidev_data *spidev; 563 struct spidev_data *spidev;
564 int status; 564 int status;
@@ -607,7 +607,7 @@ static int spidev_probe(struct spi_device *spi)
607 return status; 607 return status;
608} 608}
609 609
610static int spidev_remove(struct spi_device *spi) 610static int __devexit spidev_remove(struct spi_device *spi)
611{ 611{
612 struct spidev_data *spidev = spi_get_drvdata(spi); 612 struct spidev_data *spidev = spi_get_drvdata(spi);
613 613
@@ -629,7 +629,7 @@ static int spidev_remove(struct spi_device *spi)
629 return 0; 629 return 0;
630} 630}
631 631
632static struct spi_driver spidev_spi = { 632static struct spi_driver spidev_spi_driver = {
633 .driver = { 633 .driver = {
634 .name = "spidev", 634 .name = "spidev",
635 .owner = THIS_MODULE, 635 .owner = THIS_MODULE,
@@ -661,14 +661,14 @@ static int __init spidev_init(void)
661 661
662 spidev_class = class_create(THIS_MODULE, "spidev"); 662 spidev_class = class_create(THIS_MODULE, "spidev");
663 if (IS_ERR(spidev_class)) { 663 if (IS_ERR(spidev_class)) {
664 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); 664 unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
665 return PTR_ERR(spidev_class); 665 return PTR_ERR(spidev_class);
666 } 666 }
667 667
668 status = spi_register_driver(&spidev_spi); 668 status = spi_register_driver(&spidev_spi_driver);
669 if (status < 0) { 669 if (status < 0) {
670 class_destroy(spidev_class); 670 class_destroy(spidev_class);
671 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); 671 unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
672 } 672 }
673 return status; 673 return status;
674} 674}
@@ -676,9 +676,9 @@ module_init(spidev_init);
676 676
677static void __exit spidev_exit(void) 677static void __exit spidev_exit(void)
678{ 678{
679 spi_unregister_driver(&spidev_spi); 679 spi_unregister_driver(&spidev_spi_driver);
680 class_destroy(spidev_class); 680 class_destroy(spidev_class);
681 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); 681 unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
682} 682}
683module_exit(spidev_exit); 683module_exit(spidev_exit);
684 684
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index f0b86f02cd80..fd677f008365 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -29,7 +29,6 @@
29 * driver requests - some may support multiple options */ 29 * driver requests - some may support multiple options */
30 30
31 31
32#include <linux/autoconf.h>
33#include "iio.h" 32#include "iio.h"
34#include "ring_generic.h" 33#include "ring_generic.h"
35 34
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 4ce399b6d237..f98a52448eae 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -55,7 +55,7 @@
55#include <linux/list.h> 55#include <linux/list.h>
56#include <linux/notifier.h> 56#include <linux/notifier.h>
57#include <linux/reboot.h> 57#include <linux/reboot.h>
58#include <linux/utsrelease.h> 58#include <generated/utsrelease.h>
59 59
60#include <linux/io.h> 60#include <linux/io.h>
61#include <asm/uaccess.h> 61#include <asm/uaccess.h>
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 2051c9dc813b..b7687c55fe16 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -2245,9 +2245,6 @@ static int ext_setcolreg(unsigned int regno, unsigned int red,
2245 if (regno > 255) 2245 if (regno > 255)
2246 return 1; 2246 return 1;
2247 2247
2248 if (regno > 255)
2249 return 1;
2250
2251 switch (external_card_type) { 2248 switch (external_card_type) {
2252 case IS_VGA: 2249 case IS_VGA:
2253 OUTB(0x3c8, regno); 2250 OUTB(0x3c8, regno);
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index 4c10edecfb66..86d95c228adb 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -85,7 +85,7 @@ static int adp5520_bl_get_brightness(struct backlight_device *bl)
85 return error ? data->current_brightness : reg_val; 85 return error ? data->current_brightness : reg_val;
86} 86}
87 87
88static struct backlight_ops adp5520_bl_ops = { 88static const struct backlight_ops adp5520_bl_ops = {
89 .update_status = adp5520_bl_update_status, 89 .update_status = adp5520_bl_update_status,
90 .get_brightness = adp5520_bl_get_brightness, 90 .get_brightness = adp5520_bl_get_brightness,
91}; 91};
diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c
index 2c3bdfc620b7..d769b0bab21a 100644
--- a/drivers/video/backlight/adx_bl.c
+++ b/drivers/video/backlight/adx_bl.c
@@ -61,7 +61,7 @@ static int adx_backlight_check_fb(struct fb_info *fb)
61 return 1; 61 return 1;
62} 62}
63 63
64static struct backlight_ops adx_backlight_ops = { 64static const struct backlight_ops adx_backlight_ops = {
65 .options = 0, 65 .options = 0,
66 .update_status = adx_backlight_update_status, 66 .update_status = adx_backlight_update_status,
67 .get_brightness = adx_backlight_get_brightness, 67 .get_brightness = adx_backlight_get_brightness,
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index 2cf7ba52f67c..f625ffc69ad3 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -113,7 +113,7 @@ static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
113 return pwm_channel_enable(&pwmbl->pwmc); 113 return pwm_channel_enable(&pwmbl->pwmc);
114} 114}
115 115
116static struct backlight_ops atmel_pwm_bl_ops = { 116static const struct backlight_ops atmel_pwm_bl_ops = {
117 .get_brightness = atmel_pwm_bl_get_intensity, 117 .get_brightness = atmel_pwm_bl_get_intensity,
118 .update_status = atmel_pwm_bl_set_intensity, 118 .update_status = atmel_pwm_bl_set_intensity,
119}; 119};
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 6615ac7fa60a..18829cf68b1b 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -269,7 +269,7 @@ EXPORT_SYMBOL(backlight_force_update);
269 * ERR_PTR() or a pointer to the newly allocated device. 269 * ERR_PTR() or a pointer to the newly allocated device.
270 */ 270 */
271struct backlight_device *backlight_device_register(const char *name, 271struct backlight_device *backlight_device_register(const char *name,
272 struct device *parent, void *devdata, struct backlight_ops *ops) 272 struct device *parent, void *devdata, const struct backlight_ops *ops)
273{ 273{
274 struct backlight_device *new_bd; 274 struct backlight_device *new_bd;
275 int rc; 275 int rc;
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index 96774949cd30..b4bcf8043797 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -451,7 +451,7 @@ void corgi_lcd_limit_intensity(int limit)
451} 451}
452EXPORT_SYMBOL(corgi_lcd_limit_intensity); 452EXPORT_SYMBOL(corgi_lcd_limit_intensity);
453 453
454static struct backlight_ops corgi_bl_ops = { 454static const struct backlight_ops corgi_bl_ops = {
455 .get_brightness = corgi_bl_get_intensity, 455 .get_brightness = corgi_bl_get_intensity,
456 .update_status = corgi_bl_update_status, 456 .update_status = corgi_bl_update_status,
457}; 457};
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index b9fe62b475c6..da86db4374a0 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -108,7 +108,7 @@ static int cr_backlight_get_intensity(struct backlight_device *bd)
108 return intensity; 108 return intensity;
109} 109}
110 110
111static struct backlight_ops cr_backlight_ops = { 111static const struct backlight_ops cr_backlight_ops = {
112 .get_brightness = cr_backlight_get_intensity, 112 .get_brightness = cr_backlight_get_intensity,
113 .update_status = cr_backlight_set_intensity, 113 .update_status = cr_backlight_set_intensity,
114}; 114};
@@ -201,7 +201,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
201 if (IS_ERR(ldp)) { 201 if (IS_ERR(ldp)) {
202 backlight_device_unregister(bdp); 202 backlight_device_unregister(bdp);
203 pci_dev_put(lpc_dev); 203 pci_dev_put(lpc_dev);
204 return PTR_ERR(bdp); 204 return PTR_ERR(ldp);
205 } 205 }
206 206
207 pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR, 207 pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR,
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index f2d76dae1eb3..74cdc640173d 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -95,7 +95,7 @@ static int da903x_backlight_get_brightness(struct backlight_device *bl)
95 return data->current_brightness; 95 return data->current_brightness;
96} 96}
97 97
98static struct backlight_ops da903x_backlight_ops = { 98static const struct backlight_ops da903x_backlight_ops = {
99 .update_status = da903x_backlight_update_status, 99 .update_status = da903x_backlight_update_status,
100 .get_brightness = da903x_backlight_get_brightness, 100 .get_brightness = da903x_backlight_get_brightness,
101}; 101};
diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c
index 6d27f62fdcd0..e6d348e63596 100644
--- a/drivers/video/backlight/generic_bl.c
+++ b/drivers/video/backlight/generic_bl.c
@@ -70,7 +70,7 @@ void corgibl_limit_intensity(int limit)
70} 70}
71EXPORT_SYMBOL(corgibl_limit_intensity); 71EXPORT_SYMBOL(corgibl_limit_intensity);
72 72
73static struct backlight_ops genericbl_ops = { 73static const struct backlight_ops genericbl_ops = {
74 .options = BL_CORE_SUSPENDRESUME, 74 .options = BL_CORE_SUSPENDRESUME,
75 .get_brightness = genericbl_get_intensity, 75 .get_brightness = genericbl_get_intensity,
76 .update_status = genericbl_send_intensity, 76 .update_status = genericbl_send_intensity,
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 7fb4eefff80d..f7cc528d5be7 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -98,7 +98,7 @@ static int hp680bl_get_intensity(struct backlight_device *bd)
98 return current_intensity; 98 return current_intensity;
99} 99}
100 100
101static struct backlight_ops hp680bl_ops = { 101static const struct backlight_ops hp680bl_ops = {
102 .get_brightness = hp680bl_get_intensity, 102 .get_brightness = hp680bl_get_intensity,
103 .update_status = hp680bl_set_intensity, 103 .update_status = hp680bl_set_intensity,
104}; 104};
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
index 7aed2565c1bd..db9071fc5665 100644
--- a/drivers/video/backlight/jornada720_bl.c
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -93,7 +93,7 @@ out:
93 return ret; 93 return ret;
94} 94}
95 95
96static struct backlight_ops jornada_bl_ops = { 96static const struct backlight_ops jornada_bl_ops = {
97 .get_brightness = jornada_bl_get_brightness, 97 .get_brightness = jornada_bl_get_brightness,
98 .update_status = jornada_bl_update_status, 98 .update_status = jornada_bl_update_status,
99 .options = BL_CORE_SUSPENDRESUME, 99 .options = BL_CORE_SUSPENDRESUME,
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c
index a38fda1742dd..939e7b830cf3 100644
--- a/drivers/video/backlight/kb3886_bl.c
+++ b/drivers/video/backlight/kb3886_bl.c
@@ -134,7 +134,7 @@ static int kb3886bl_get_intensity(struct backlight_device *bd)
134 return kb3886bl_intensity; 134 return kb3886bl_intensity;
135} 135}
136 136
137static struct backlight_ops kb3886bl_ops = { 137static const struct backlight_ops kb3886bl_ops = {
138 .get_brightness = kb3886bl_get_intensity, 138 .get_brightness = kb3886bl_get_intensity,
139 .update_status = kb3886bl_send_intensity, 139 .update_status = kb3886bl_send_intensity,
140}; 140};
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index 6b488b8a7eee..00a9591b0003 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -141,7 +141,7 @@ static int locomolcd_get_intensity(struct backlight_device *bd)
141 return current_intensity; 141 return current_intensity;
142} 142}
143 143
144static struct backlight_ops locomobl_data = { 144static const struct backlight_ops locomobl_data = {
145 .get_brightness = locomolcd_get_intensity, 145 .get_brightness = locomolcd_get_intensity,
146 .update_status = locomolcd_set_intensity, 146 .update_status = locomolcd_set_intensity,
147}; 147};
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
index 9edb8d7c295f..2e78b0784bdc 100644
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -33,7 +33,7 @@ struct dmi_match_data {
33 unsigned long iostart; 33 unsigned long iostart;
34 unsigned long iolen; 34 unsigned long iolen;
35 /* Backlight operations structure. */ 35 /* Backlight operations structure. */
36 struct backlight_ops backlight_ops; 36 const struct backlight_ops backlight_ops;
37}; 37};
38 38
39/* Module parameters. */ 39/* Module parameters. */
@@ -220,6 +220,24 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
220 }, 220 },
221 { 221 {
222 .callback = mbp_dmi_match, 222 .callback = mbp_dmi_match,
223 .ident = "MacBookPro 5,3",
224 .matches = {
225 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
226 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3"),
227 },
228 .driver_data = (void *)&nvidia_chipset_data,
229 },
230 {
231 .callback = mbp_dmi_match,
232 .ident = "MacBookPro 5,4",
233 .matches = {
234 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
235 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4"),
236 },
237 .driver_data = (void *)&nvidia_chipset_data,
238 },
239 {
240 .callback = mbp_dmi_match,
223 .ident = "MacBookPro 5,5", 241 .ident = "MacBookPro 5,5",
224 .matches = { 242 .matches = {
225 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 243 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index 8693e5fcd2eb..409ca9643528 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -125,7 +125,7 @@ static int omapbl_get_intensity(struct backlight_device *dev)
125 return bl->current_intensity; 125 return bl->current_intensity;
126} 126}
127 127
128static struct backlight_ops omapbl_ops = { 128static const struct backlight_ops omapbl_ops = {
129 .get_brightness = omapbl_get_intensity, 129 .get_brightness = omapbl_get_intensity,
130 .update_status = omapbl_update_status, 130 .update_status = omapbl_update_status,
131}; 131};
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
index 9edaf24fd82d..075786e05034 100644
--- a/drivers/video/backlight/progear_bl.c
+++ b/drivers/video/backlight/progear_bl.c
@@ -54,7 +54,7 @@ static int progearbl_get_intensity(struct backlight_device *bd)
54 return intensity - HW_LEVEL_MIN; 54 return intensity - HW_LEVEL_MIN;
55} 55}
56 56
57static struct backlight_ops progearbl_ops = { 57static const struct backlight_ops progearbl_ops = {
58 .get_brightness = progearbl_get_intensity, 58 .get_brightness = progearbl_get_intensity,
59 .update_status = progearbl_set_intensity, 59 .update_status = progearbl_set_intensity,
60}; 60};
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 887166267443..9d2ec2a1cce8 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -22,8 +22,10 @@
22 22
23struct pwm_bl_data { 23struct pwm_bl_data {
24 struct pwm_device *pwm; 24 struct pwm_device *pwm;
25 struct device *dev;
25 unsigned int period; 26 unsigned int period;
26 int (*notify)(int brightness); 27 int (*notify)(struct device *,
28 int brightness);
27}; 29};
28 30
29static int pwm_backlight_update_status(struct backlight_device *bl) 31static int pwm_backlight_update_status(struct backlight_device *bl)
@@ -39,7 +41,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
39 brightness = 0; 41 brightness = 0;
40 42
41 if (pb->notify) 43 if (pb->notify)
42 brightness = pb->notify(brightness); 44 brightness = pb->notify(pb->dev, brightness);
43 45
44 if (brightness == 0) { 46 if (brightness == 0) {
45 pwm_config(pb->pwm, 0, pb->period); 47 pwm_config(pb->pwm, 0, pb->period);
@@ -56,7 +58,7 @@ static int pwm_backlight_get_brightness(struct backlight_device *bl)
56 return bl->props.brightness; 58 return bl->props.brightness;
57} 59}
58 60
59static struct backlight_ops pwm_backlight_ops = { 61static const struct backlight_ops pwm_backlight_ops = {
60 .update_status = pwm_backlight_update_status, 62 .update_status = pwm_backlight_update_status,
61 .get_brightness = pwm_backlight_get_brightness, 63 .get_brightness = pwm_backlight_get_brightness,
62}; 64};
@@ -88,6 +90,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
88 90
89 pb->period = data->pwm_period_ns; 91 pb->period = data->pwm_period_ns;
90 pb->notify = data->notify; 92 pb->notify = data->notify;
93 pb->dev = &pdev->dev;
91 94
92 pb->pwm = pwm_request(data->pwm_id, "backlight"); 95 pb->pwm = pwm_request(data->pwm_id, "backlight");
93 if (IS_ERR(pb->pwm)) { 96 if (IS_ERR(pb->pwm)) {
@@ -146,7 +149,7 @@ static int pwm_backlight_suspend(struct platform_device *pdev,
146 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); 149 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
147 150
148 if (pb->notify) 151 if (pb->notify)
149 pb->notify(0); 152 pb->notify(pb->dev, 0);
150 pwm_config(pb->pwm, 0, pb->period); 153 pwm_config(pb->pwm, 0, pb->period);
151 pwm_disable(pb->pwm); 154 pwm_disable(pb->pwm);
152 return 0; 155 return 0;
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index 43edbada12d1..e14ce4d469f5 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -72,7 +72,7 @@ static int tosa_bl_get_brightness(struct backlight_device *dev)
72 return props->brightness; 72 return props->brightness;
73} 73}
74 74
75static struct backlight_ops bl_ops = { 75static const struct backlight_ops bl_ops = {
76 .get_brightness = tosa_bl_get_brightness, 76 .get_brightness = tosa_bl_get_brightness,
77 .update_status = tosa_bl_update_status, 77 .update_status = tosa_bl_update_status,
78}; 78};
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
index 467bdb7efb23..e32add37a203 100644
--- a/drivers/video/backlight/wm831x_bl.c
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -112,7 +112,7 @@ static int wm831x_backlight_get_brightness(struct backlight_device *bl)
112 return data->current_brightness; 112 return data->current_brightness;
113} 113}
114 114
115static struct backlight_ops wm831x_backlight_ops = { 115static const struct backlight_ops wm831x_backlight_ops = {
116 .options = BL_CORE_SUSPENDRESUME, 116 .options = BL_CORE_SUSPENDRESUME,
117 .update_status = wm831x_backlight_update_status, 117 .update_status = wm831x_backlight_update_status,
118 .get_brightness = wm831x_backlight_get_brightness, 118 .get_brightness = wm831x_backlight_get_brightness,
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 10d8c4b4baeb..d8df17a7d5fc 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -680,7 +680,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
680 if (!viafb_gamma_table) 680 if (!viafb_gamma_table)
681 return -ENOMEM; 681 return -ENOMEM;
682 if (copy_from_user(viafb_gamma_table, argp, 682 if (copy_from_user(viafb_gamma_table, argp,
683 sizeof(viafb_gamma_table))) { 683 256 * sizeof(u32))) {
684 kfree(viafb_gamma_table); 684 kfree(viafb_gamma_table);
685 return -EFAULT; 685 return -EFAULT;
686 } 686 }
@@ -694,7 +694,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
694 return -ENOMEM; 694 return -ENOMEM;
695 viafb_get_gamma_table(viafb_gamma_table); 695 viafb_get_gamma_table(viafb_gamma_table);
696 if (copy_to_user(argp, viafb_gamma_table, 696 if (copy_to_user(argp, viafb_gamma_table,
697 sizeof(viafb_gamma_table))) { 697 256 * sizeof(u32))) {
698 kfree(viafb_gamma_table); 698 kfree(viafb_gamma_table);
699 return -EFAULT; 699 return -EFAULT;
700 } 700 }