diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/pata_palmld.c | 43 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_colibri.c | 133 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_palmld.c | 42 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_palmtc.c | 75 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_palmtx.c | 57 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_vpac270.c | 110 | ||||
-rw-r--r-- | drivers/usb/gadget/pxa25x_udc.c | 76 | ||||
-rw-r--r-- | drivers/video/pxafb.c | 136 | ||||
-rw-r--r-- | drivers/video/pxafb.h | 3 |
9 files changed, 234 insertions, 441 deletions
diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c index a2a73d953840..b86d7e22595e 100644 --- a/drivers/ata/pata_palmld.c +++ b/drivers/ata/pata_palmld.c | |||
@@ -33,6 +33,11 @@ | |||
33 | 33 | ||
34 | #define DRV_NAME "pata_palmld" | 34 | #define DRV_NAME "pata_palmld" |
35 | 35 | ||
36 | static struct gpio palmld_hdd_gpios[] = { | ||
37 | { GPIO_NR_PALMLD_IDE_PWEN, GPIOF_INIT_HIGH, "HDD Power" }, | ||
38 | { GPIO_NR_PALMLD_IDE_RESET, GPIOF_INIT_LOW, "HDD Reset" }, | ||
39 | }; | ||
40 | |||
36 | static struct scsi_host_template palmld_sht = { | 41 | static struct scsi_host_template palmld_sht = { |
37 | ATA_PIO_SHT(DRV_NAME), | 42 | ATA_PIO_SHT(DRV_NAME), |
38 | }; | 43 | }; |
@@ -52,28 +57,23 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) | |||
52 | 57 | ||
53 | /* allocate host */ | 58 | /* allocate host */ |
54 | host = ata_host_alloc(&pdev->dev, 1); | 59 | host = ata_host_alloc(&pdev->dev, 1); |
55 | if (!host) | 60 | if (!host) { |
56 | return -ENOMEM; | 61 | ret = -ENOMEM; |
62 | goto err1; | ||
63 | } | ||
57 | 64 | ||
58 | /* remap drive's physical memory address */ | 65 | /* remap drive's physical memory address */ |
59 | mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000); | 66 | mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000); |
60 | if (!mem) | 67 | if (!mem) { |
61 | return -ENOMEM; | 68 | ret = -ENOMEM; |
69 | goto err1; | ||
70 | } | ||
62 | 71 | ||
63 | /* request and activate power GPIO, IRQ GPIO */ | 72 | /* request and activate power GPIO, IRQ GPIO */ |
64 | ret = gpio_request(GPIO_NR_PALMLD_IDE_PWEN, "HDD PWR"); | 73 | ret = gpio_request_array(palmld_hdd_gpios, |
74 | ARRAY_SIZE(palmld_hdd_gpios)); | ||
65 | if (ret) | 75 | if (ret) |
66 | goto err1; | 76 | goto err1; |
67 | ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_PWEN, 1); | ||
68 | if (ret) | ||
69 | goto err2; | ||
70 | |||
71 | ret = gpio_request(GPIO_NR_PALMLD_IDE_RESET, "HDD RST"); | ||
72 | if (ret) | ||
73 | goto err2; | ||
74 | ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_RESET, 0); | ||
75 | if (ret) | ||
76 | goto err3; | ||
77 | 77 | ||
78 | /* reset the drive */ | 78 | /* reset the drive */ |
79 | gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0); | 79 | gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0); |
@@ -96,13 +96,15 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) | |||
96 | ata_sff_std_ports(&ap->ioaddr); | 96 | ata_sff_std_ports(&ap->ioaddr); |
97 | 97 | ||
98 | /* activate host */ | 98 | /* activate host */ |
99 | return ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING, | 99 | ret = ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING, |
100 | &palmld_sht); | 100 | &palmld_sht); |
101 | if (ret) | ||
102 | goto err2; | ||
103 | |||
104 | return ret; | ||
101 | 105 | ||
102 | err3: | ||
103 | gpio_free(GPIO_NR_PALMLD_IDE_RESET); | ||
104 | err2: | 106 | err2: |
105 | gpio_free(GPIO_NR_PALMLD_IDE_PWEN); | 107 | gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios)); |
106 | err1: | 108 | err1: |
107 | return ret; | 109 | return ret; |
108 | } | 110 | } |
@@ -116,8 +118,7 @@ static __devexit int palmld_pata_remove(struct platform_device *dev) | |||
116 | /* power down the HDD */ | 118 | /* power down the HDD */ |
117 | gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0); | 119 | gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0); |
118 | 120 | ||
119 | gpio_free(GPIO_NR_PALMLD_IDE_RESET); | 121 | gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios)); |
120 | gpio_free(GPIO_NR_PALMLD_IDE_PWEN); | ||
121 | 122 | ||
122 | return 0; | 123 | return 0; |
123 | } | 124 | } |
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index a52039564e74..443cb7fc872d 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c | |||
@@ -34,14 +34,24 @@ | |||
34 | #define COLIBRI320_DETECT_GPIO 81 | 34 | #define COLIBRI320_DETECT_GPIO 81 |
35 | #define COLIBRI320_READY_GPIO 29 | 35 | #define COLIBRI320_READY_GPIO 29 |
36 | 36 | ||
37 | static struct { | 37 | enum { |
38 | int reset_gpio; | 38 | DETECT = 0, |
39 | int ppen_gpio; | 39 | READY = 1, |
40 | int bvd1_gpio; | 40 | BVD1 = 2, |
41 | int bvd2_gpio; | 41 | BVD2 = 3, |
42 | int detect_gpio; | 42 | PPEN = 4, |
43 | int ready_gpio; | 43 | RESET = 5, |
44 | } colibri_pcmcia_gpio; | 44 | }; |
45 | |||
46 | /* Contents of this array are configured on-the-fly in init function */ | ||
47 | static struct gpio colibri_pcmcia_gpios[] = { | ||
48 | { 0, GPIOF_IN, "PCMCIA Detect" }, | ||
49 | { 0, GPIOF_IN, "PCMCIA Ready" }, | ||
50 | { 0, GPIOF_IN, "PCMCIA BVD1" }, | ||
51 | { 0, GPIOF_IN, "PCMCIA BVD2" }, | ||
52 | { 0, GPIOF_INIT_LOW, "PCMCIA PPEN" }, | ||
53 | { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | ||
54 | }; | ||
45 | 55 | ||
46 | static struct pcmcia_irqs colibri_irqs[] = { | 56 | static struct pcmcia_irqs colibri_irqs[] = { |
47 | { | 57 | { |
@@ -54,88 +64,42 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
54 | { | 64 | { |
55 | int ret; | 65 | int ret; |
56 | 66 | ||
57 | ret = gpio_request(colibri_pcmcia_gpio.detect_gpio, "DETECT"); | 67 | ret = gpio_request_array(colibri_pcmcia_gpios, |
68 | ARRAY_SIZE(colibri_pcmcia_gpios)); | ||
58 | if (ret) | 69 | if (ret) |
59 | goto err1; | 70 | goto err1; |
60 | ret = gpio_direction_input(colibri_pcmcia_gpio.detect_gpio); | ||
61 | if (ret) | ||
62 | goto err2; | ||
63 | |||
64 | ret = gpio_request(colibri_pcmcia_gpio.ready_gpio, "READY"); | ||
65 | if (ret) | ||
66 | goto err2; | ||
67 | ret = gpio_direction_input(colibri_pcmcia_gpio.ready_gpio); | ||
68 | if (ret) | ||
69 | goto err3; | ||
70 | 71 | ||
71 | ret = gpio_request(colibri_pcmcia_gpio.bvd1_gpio, "BVD1"); | 72 | colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio); |
72 | if (ret) | 73 | skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio); |
73 | goto err3; | ||
74 | ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio); | ||
75 | if (ret) | ||
76 | goto err4; | ||
77 | 74 | ||
78 | ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2"); | 75 | ret = soc_pcmcia_request_irqs(skt, colibri_irqs, |
79 | if (ret) | 76 | ARRAY_SIZE(colibri_irqs)); |
80 | goto err4; | ||
81 | ret = gpio_direction_input(colibri_pcmcia_gpio.bvd2_gpio); | ||
82 | if (ret) | ||
83 | goto err5; | ||
84 | |||
85 | ret = gpio_request(colibri_pcmcia_gpio.ppen_gpio, "PPEN"); | ||
86 | if (ret) | ||
87 | goto err5; | ||
88 | ret = gpio_direction_output(colibri_pcmcia_gpio.ppen_gpio, 0); | ||
89 | if (ret) | ||
90 | goto err6; | ||
91 | |||
92 | ret = gpio_request(colibri_pcmcia_gpio.reset_gpio, "RESET"); | ||
93 | if (ret) | ||
94 | goto err6; | ||
95 | ret = gpio_direction_output(colibri_pcmcia_gpio.reset_gpio, 1); | ||
96 | if (ret) | 77 | if (ret) |
97 | goto err7; | 78 | goto err2; |
98 | |||
99 | colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio); | ||
100 | skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio); | ||
101 | 79 | ||
102 | return soc_pcmcia_request_irqs(skt, colibri_irqs, | 80 | return ret; |
103 | ARRAY_SIZE(colibri_irqs)); | ||
104 | 81 | ||
105 | err7: | ||
106 | gpio_free(colibri_pcmcia_gpio.detect_gpio); | ||
107 | err6: | ||
108 | gpio_free(colibri_pcmcia_gpio.ready_gpio); | ||
109 | err5: | ||
110 | gpio_free(colibri_pcmcia_gpio.bvd1_gpio); | ||
111 | err4: | ||
112 | gpio_free(colibri_pcmcia_gpio.bvd2_gpio); | ||
113 | err3: | ||
114 | gpio_free(colibri_pcmcia_gpio.reset_gpio); | ||
115 | err2: | 82 | err2: |
116 | gpio_free(colibri_pcmcia_gpio.ppen_gpio); | 83 | gpio_free_array(colibri_pcmcia_gpios, |
84 | ARRAY_SIZE(colibri_pcmcia_gpios)); | ||
117 | err1: | 85 | err1: |
118 | return ret; | 86 | return ret; |
119 | } | 87 | } |
120 | 88 | ||
121 | static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 89 | static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
122 | { | 90 | { |
123 | gpio_free(colibri_pcmcia_gpio.detect_gpio); | 91 | gpio_free_array(colibri_pcmcia_gpios, |
124 | gpio_free(colibri_pcmcia_gpio.ready_gpio); | 92 | ARRAY_SIZE(colibri_pcmcia_gpios)); |
125 | gpio_free(colibri_pcmcia_gpio.bvd1_gpio); | ||
126 | gpio_free(colibri_pcmcia_gpio.bvd2_gpio); | ||
127 | gpio_free(colibri_pcmcia_gpio.reset_gpio); | ||
128 | gpio_free(colibri_pcmcia_gpio.ppen_gpio); | ||
129 | } | 93 | } |
130 | 94 | ||
131 | static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 95 | static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
132 | struct pcmcia_state *state) | 96 | struct pcmcia_state *state) |
133 | { | 97 | { |
134 | 98 | ||
135 | state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio); | 99 | state->detect = !!gpio_get_value(colibri_pcmcia_gpios[DETECT].gpio); |
136 | state->ready = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio); | 100 | state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio); |
137 | state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio); | 101 | state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio); |
138 | state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio); | 102 | state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio); |
139 | state->wrprot = 0; | 103 | state->wrprot = 0; |
140 | state->vs_3v = 1; | 104 | state->vs_3v = 1; |
141 | state->vs_Xv = 0; | 105 | state->vs_Xv = 0; |
@@ -145,9 +109,10 @@ static int | |||
145 | colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 109 | colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
146 | const socket_state_t *state) | 110 | const socket_state_t *state) |
147 | { | 111 | { |
148 | gpio_set_value(colibri_pcmcia_gpio.ppen_gpio, | 112 | gpio_set_value(colibri_pcmcia_gpios[PPEN].gpio, |
149 | !(state->Vcc == 33 && state->Vpp < 50)); | 113 | !(state->Vcc == 33 && state->Vpp < 50)); |
150 | gpio_set_value(colibri_pcmcia_gpio.reset_gpio, state->flags & SS_RESET); | 114 | gpio_set_value(colibri_pcmcia_gpios[RESET].gpio, |
115 | state->flags & SS_RESET); | ||
151 | return 0; | 116 | return 0; |
152 | } | 117 | } |
153 | 118 | ||
@@ -190,20 +155,20 @@ static int __init colibri_pcmcia_init(void) | |||
190 | 155 | ||
191 | /* Colibri PXA270 */ | 156 | /* Colibri PXA270 */ |
192 | if (machine_is_colibri()) { | 157 | if (machine_is_colibri()) { |
193 | colibri_pcmcia_gpio.reset_gpio = COLIBRI270_RESET_GPIO; | 158 | colibri_pcmcia_gpios[RESET].gpio = COLIBRI270_RESET_GPIO; |
194 | colibri_pcmcia_gpio.ppen_gpio = COLIBRI270_PPEN_GPIO; | 159 | colibri_pcmcia_gpios[PPEN].gpio = COLIBRI270_PPEN_GPIO; |
195 | colibri_pcmcia_gpio.bvd1_gpio = COLIBRI270_BVD1_GPIO; | 160 | colibri_pcmcia_gpios[BVD1].gpio = COLIBRI270_BVD1_GPIO; |
196 | colibri_pcmcia_gpio.bvd2_gpio = COLIBRI270_BVD2_GPIO; | 161 | colibri_pcmcia_gpios[BVD2].gpio = COLIBRI270_BVD2_GPIO; |
197 | colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO; | 162 | colibri_pcmcia_gpios[DETECT].gpio = COLIBRI270_DETECT_GPIO; |
198 | colibri_pcmcia_gpio.ready_gpio = COLIBRI270_READY_GPIO; | 163 | colibri_pcmcia_gpios[READY].gpio = COLIBRI270_READY_GPIO; |
199 | /* Colibri PXA320 */ | 164 | /* Colibri PXA320 */ |
200 | } else if (machine_is_colibri320()) { | 165 | } else if (machine_is_colibri320()) { |
201 | colibri_pcmcia_gpio.reset_gpio = COLIBRI320_RESET_GPIO; | 166 | colibri_pcmcia_gpios[RESET].gpio = COLIBRI320_RESET_GPIO; |
202 | colibri_pcmcia_gpio.ppen_gpio = COLIBRI320_PPEN_GPIO; | 167 | colibri_pcmcia_gpios[PPEN].gpio = COLIBRI320_PPEN_GPIO; |
203 | colibri_pcmcia_gpio.bvd1_gpio = COLIBRI320_BVD1_GPIO; | 168 | colibri_pcmcia_gpios[BVD1].gpio = COLIBRI320_BVD1_GPIO; |
204 | colibri_pcmcia_gpio.bvd2_gpio = COLIBRI320_BVD2_GPIO; | 169 | colibri_pcmcia_gpios[BVD2].gpio = COLIBRI320_BVD2_GPIO; |
205 | colibri_pcmcia_gpio.detect_gpio = COLIBRI320_DETECT_GPIO; | 170 | colibri_pcmcia_gpios[DETECT].gpio = COLIBRI320_DETECT_GPIO; |
206 | colibri_pcmcia_gpio.ready_gpio = COLIBRI320_READY_GPIO; | 171 | colibri_pcmcia_gpios[READY].gpio = COLIBRI320_READY_GPIO; |
207 | } | 172 | } |
208 | 173 | ||
209 | ret = platform_device_add_data(colibri_pcmcia_device, | 174 | ret = platform_device_add_data(colibri_pcmcia_device, |
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c index 6fb6f7f0672e..69f73670949a 100644 --- a/drivers/pcmcia/pxa2xx_palmld.c +++ b/drivers/pcmcia/pxa2xx_palmld.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Driver for Palm LifeDrive PCMCIA | 4 | * Driver for Palm LifeDrive PCMCIA |
5 | * | 5 | * |
6 | * Copyright (C) 2006 Alex Osborne <ato@meshy.org> | 6 | * Copyright (C) 2006 Alex Osborne <ato@meshy.org> |
7 | * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com> | 7 | * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -20,49 +20,27 @@ | |||
20 | #include <mach/palmld.h> | 20 | #include <mach/palmld.h> |
21 | #include "soc_common.h" | 21 | #include "soc_common.h" |
22 | 22 | ||
23 | static struct gpio palmld_pcmcia_gpios[] = { | ||
24 | { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" }, | ||
25 | { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | ||
26 | { GPIO_NR_PALMLD_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, | ||
27 | }; | ||
28 | |||
23 | static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 29 | static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
24 | { | 30 | { |
25 | int ret; | 31 | int ret; |
26 | 32 | ||
27 | ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR"); | 33 | ret = gpio_request_array(palmld_pcmcia_gpios, |
28 | if (ret) | 34 | ARRAY_SIZE(palmld_pcmcia_gpios)); |
29 | goto err1; | ||
30 | ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0); | ||
31 | if (ret) | ||
32 | goto err2; | ||
33 | |||
34 | ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST"); | ||
35 | if (ret) | ||
36 | goto err2; | ||
37 | ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1); | ||
38 | if (ret) | ||
39 | goto err3; | ||
40 | |||
41 | ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY"); | ||
42 | if (ret) | ||
43 | goto err3; | ||
44 | ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY); | ||
45 | if (ret) | ||
46 | goto err4; | ||
47 | 35 | ||
48 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); | 36 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); |
49 | return 0; | ||
50 | 37 | ||
51 | err4: | ||
52 | gpio_free(GPIO_NR_PALMLD_PCMCIA_READY); | ||
53 | err3: | ||
54 | gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET); | ||
55 | err2: | ||
56 | gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER); | ||
57 | err1: | ||
58 | return ret; | 38 | return ret; |
59 | } | 39 | } |
60 | 40 | ||
61 | static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 41 | static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
62 | { | 42 | { |
63 | gpio_free(GPIO_NR_PALMLD_PCMCIA_READY); | 43 | gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios)); |
64 | gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET); | ||
65 | gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER); | ||
66 | } | 44 | } |
67 | 45 | ||
68 | static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 46 | static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c index 459a232d66be..d0ad6a76bbde 100644 --- a/drivers/pcmcia/pxa2xx_palmtc.c +++ b/drivers/pcmcia/pxa2xx_palmtc.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Driver for Palm Tungsten|C PCMCIA | 4 | * Driver for Palm Tungsten|C PCMCIA |
5 | * | 5 | * |
6 | * Copyright (C) 2008 Alex Osborne <ato@meshy.org> | 6 | * Copyright (C) 2008 Alex Osborne <ato@meshy.org> |
7 | * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com> | 7 | * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -21,79 +21,30 @@ | |||
21 | #include <mach/palmtc.h> | 21 | #include <mach/palmtc.h> |
22 | #include "soc_common.h" | 22 | #include "soc_common.h" |
23 | 23 | ||
24 | static struct gpio palmtc_pcmcia_gpios[] = { | ||
25 | { GPIO_NR_PALMTC_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, | ||
26 | { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, | ||
27 | { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" }, | ||
28 | { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | ||
29 | { GPIO_NR_PALMTC_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, | ||
30 | { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" }, | ||
31 | }; | ||
32 | |||
24 | static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 33 | static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
25 | { | 34 | { |
26 | int ret; | 35 | int ret; |
27 | 36 | ||
28 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1"); | 37 | ret = gpio_request_array(palmtc_pcmcia_gpios, |
29 | if (ret) | 38 | ARRAY_SIZE(palmtc_pcmcia_gpios)); |
30 | goto err1; | ||
31 | ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER1, 0); | ||
32 | if (ret) | ||
33 | goto err2; | ||
34 | |||
35 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER2, "PCMCIA PWR2"); | ||
36 | if (ret) | ||
37 | goto err2; | ||
38 | ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER2, 0); | ||
39 | if (ret) | ||
40 | goto err3; | ||
41 | |||
42 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER3, "PCMCIA PWR3"); | ||
43 | if (ret) | ||
44 | goto err3; | ||
45 | ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER3, 0); | ||
46 | if (ret) | ||
47 | goto err4; | ||
48 | |||
49 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_RESET, "PCMCIA RST"); | ||
50 | if (ret) | ||
51 | goto err4; | ||
52 | ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_RESET, 1); | ||
53 | if (ret) | ||
54 | goto err5; | ||
55 | |||
56 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_READY, "PCMCIA RDY"); | ||
57 | if (ret) | ||
58 | goto err5; | ||
59 | ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_READY); | ||
60 | if (ret) | ||
61 | goto err6; | ||
62 | |||
63 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_PWRREADY, "PCMCIA PWRRDY"); | ||
64 | if (ret) | ||
65 | goto err6; | ||
66 | ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_PWRREADY); | ||
67 | if (ret) | ||
68 | goto err7; | ||
69 | 39 | ||
70 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY); | 40 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY); |
71 | return 0; | ||
72 | 41 | ||
73 | err7: | ||
74 | gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY); | ||
75 | err6: | ||
76 | gpio_free(GPIO_NR_PALMTC_PCMCIA_READY); | ||
77 | err5: | ||
78 | gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET); | ||
79 | err4: | ||
80 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3); | ||
81 | err3: | ||
82 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2); | ||
83 | err2: | ||
84 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1); | ||
85 | err1: | ||
86 | return ret; | 42 | return ret; |
87 | } | 43 | } |
88 | 44 | ||
89 | static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 45 | static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
90 | { | 46 | { |
91 | gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY); | 47 | gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios)); |
92 | gpio_free(GPIO_NR_PALMTC_PCMCIA_READY); | ||
93 | gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET); | ||
94 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3); | ||
95 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2); | ||
96 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1); | ||
97 | } | 48 | } |
98 | 49 | ||
99 | static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 50 | static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c index b07b247a399f..1a2580450402 100644 --- a/drivers/pcmcia/pxa2xx_palmtx.c +++ b/drivers/pcmcia/pxa2xx_palmtx.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Driver for Palm T|X PCMCIA | 4 | * Driver for Palm T|X PCMCIA |
5 | * | 5 | * |
6 | * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com> | 6 | * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 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 | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -13,67 +13,34 @@ | |||
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/gpio.h> | ||
16 | 17 | ||
17 | #include <asm/mach-types.h> | 18 | #include <asm/mach-types.h> |
18 | |||
19 | #include <mach/gpio.h> | ||
20 | #include <mach/palmtx.h> | 19 | #include <mach/palmtx.h> |
21 | |||
22 | #include "soc_common.h" | 20 | #include "soc_common.h" |
23 | 21 | ||
22 | static struct gpio palmtx_pcmcia_gpios[] = { | ||
23 | { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, | ||
24 | { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, | ||
25 | { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | ||
26 | { GPIO_NR_PALMTX_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, | ||
27 | }; | ||
28 | |||
24 | static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 29 | static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
25 | { | 30 | { |
26 | int ret; | 31 | int ret; |
27 | 32 | ||
28 | ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1"); | 33 | ret = gpio_request_array(palmtx_pcmcia_gpios, |
29 | if (ret) | 34 | ARRAY_SIZE(palmtx_pcmcia_gpios)); |
30 | goto err1; | ||
31 | ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER1, 0); | ||
32 | if (ret) | ||
33 | goto err2; | ||
34 | |||
35 | ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER2, "PCMCIA PWR2"); | ||
36 | if (ret) | ||
37 | goto err2; | ||
38 | ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER2, 0); | ||
39 | if (ret) | ||
40 | goto err3; | ||
41 | |||
42 | ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_RESET, "PCMCIA RST"); | ||
43 | if (ret) | ||
44 | goto err3; | ||
45 | ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_RESET, 1); | ||
46 | if (ret) | ||
47 | goto err4; | ||
48 | |||
49 | ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_READY, "PCMCIA RDY"); | ||
50 | if (ret) | ||
51 | goto err4; | ||
52 | ret = gpio_direction_input(GPIO_NR_PALMTX_PCMCIA_READY); | ||
53 | if (ret) | ||
54 | goto err5; | ||
55 | 35 | ||
56 | skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); | 36 | skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); |
57 | return 0; | ||
58 | 37 | ||
59 | err5: | ||
60 | gpio_free(GPIO_NR_PALMTX_PCMCIA_READY); | ||
61 | err4: | ||
62 | gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET); | ||
63 | err3: | ||
64 | gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2); | ||
65 | err2: | ||
66 | gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1); | ||
67 | err1: | ||
68 | return ret; | 38 | return ret; |
69 | } | 39 | } |
70 | 40 | ||
71 | static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 41 | static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
72 | { | 42 | { |
73 | gpio_free(GPIO_NR_PALMTX_PCMCIA_READY); | 43 | gpio_free_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios)); |
74 | gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET); | ||
75 | gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2); | ||
76 | gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1); | ||
77 | } | 44 | } |
78 | 45 | ||
79 | static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 46 | static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c index 55627eccee8e..435002dfc3ca 100644 --- a/drivers/pcmcia/pxa2xx_vpac270.c +++ b/drivers/pcmcia/pxa2xx_vpac270.c | |||
@@ -3,8 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Driver for Voipac PXA270 PCMCIA and CF sockets | 4 | * Driver for Voipac PXA270 PCMCIA and CF sockets |
5 | * | 5 | * |
6 | * Copyright (C) 2010 | 6 | * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com> |
7 | * Marek Vasut <marek.vasut@gmail.com> | ||
8 | * | 7 | * |
9 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -22,6 +21,19 @@ | |||
22 | 21 | ||
23 | #include "soc_common.h" | 22 | #include "soc_common.h" |
24 | 23 | ||
24 | static struct gpio vpac270_pcmcia_gpios[] = { | ||
25 | { GPIO84_VPAC270_PCMCIA_CD, GPIOF_IN, "PCMCIA Card Detect" }, | ||
26 | { GPIO35_VPAC270_PCMCIA_RDY, GPIOF_IN, "PCMCIA Ready" }, | ||
27 | { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, | ||
28 | { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, | ||
29 | }; | ||
30 | |||
31 | static struct gpio vpac270_cf_gpios[] = { | ||
32 | { GPIO17_VPAC270_CF_CD, GPIOF_IN, "CF Card Detect" }, | ||
33 | { GPIO12_VPAC270_CF_RDY, GPIOF_IN, "CF Ready" }, | ||
34 | { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, | ||
35 | }; | ||
36 | |||
25 | static struct pcmcia_irqs cd_irqs[] = { | 37 | static struct pcmcia_irqs cd_irqs[] = { |
26 | { | 38 | { |
27 | .sock = 0, | 39 | .sock = 0, |
@@ -40,96 +52,34 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
40 | int ret; | 52 | int ret; |
41 | 53 | ||
42 | if (skt->nr == 0) { | 54 | if (skt->nr == 0) { |
43 | ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD"); | 55 | ret = gpio_request_array(vpac270_pcmcia_gpios, |
44 | if (ret) | 56 | ARRAY_SIZE(vpac270_pcmcia_gpios)); |
45 | goto err1; | ||
46 | ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD); | ||
47 | if (ret) | ||
48 | goto err2; | ||
49 | |||
50 | ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY"); | ||
51 | if (ret) | ||
52 | goto err2; | ||
53 | ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY); | ||
54 | if (ret) | ||
55 | goto err3; | ||
56 | |||
57 | ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN"); | ||
58 | if (ret) | ||
59 | goto err3; | ||
60 | ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0); | ||
61 | if (ret) | ||
62 | goto err4; | ||
63 | |||
64 | ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET"); | ||
65 | if (ret) | ||
66 | goto err4; | ||
67 | ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0); | ||
68 | if (ret) | ||
69 | goto err5; | ||
70 | 57 | ||
71 | skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); | 58 | skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); |
72 | 59 | ||
73 | return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); | 60 | if (!ret) |
74 | 61 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); | |
75 | err5: | ||
76 | gpio_free(GPIO11_VPAC270_PCMCIA_RESET); | ||
77 | err4: | ||
78 | gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); | ||
79 | err3: | ||
80 | gpio_free(GPIO35_VPAC270_PCMCIA_RDY); | ||
81 | err2: | ||
82 | gpio_free(GPIO84_VPAC270_PCMCIA_CD); | ||
83 | err1: | ||
84 | return ret; | ||
85 | |||
86 | } else { | 62 | } else { |
87 | ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD"); | 63 | ret = gpio_request_array(vpac270_cf_gpios, |
88 | if (ret) | 64 | ARRAY_SIZE(vpac270_cf_gpios)); |
89 | goto err6; | ||
90 | ret = gpio_direction_input(GPIO17_VPAC270_CF_CD); | ||
91 | if (ret) | ||
92 | goto err7; | ||
93 | |||
94 | ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY"); | ||
95 | if (ret) | ||
96 | goto err7; | ||
97 | ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY); | ||
98 | if (ret) | ||
99 | goto err8; | ||
100 | |||
101 | ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET"); | ||
102 | if (ret) | ||
103 | goto err8; | ||
104 | ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0); | ||
105 | if (ret) | ||
106 | goto err9; | ||
107 | 65 | ||
108 | skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); | 66 | skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); |
109 | 67 | ||
110 | return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); | 68 | if (!ret) |
111 | 69 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); | |
112 | err9: | ||
113 | gpio_free(GPIO16_VPAC270_CF_RESET); | ||
114 | err8: | ||
115 | gpio_free(GPIO12_VPAC270_CF_RDY); | ||
116 | err7: | ||
117 | gpio_free(GPIO17_VPAC270_CF_CD); | ||
118 | err6: | ||
119 | return ret; | ||
120 | |||
121 | } | 70 | } |
71 | |||
72 | return ret; | ||
122 | } | 73 | } |
123 | 74 | ||
124 | static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 75 | static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
125 | { | 76 | { |
126 | gpio_free(GPIO11_VPAC270_PCMCIA_RESET); | 77 | if (skt->nr == 0) |
127 | gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); | 78 | gpio_request_array(vpac270_pcmcia_gpios, |
128 | gpio_free(GPIO35_VPAC270_PCMCIA_RDY); | 79 | ARRAY_SIZE(vpac270_pcmcia_gpios)); |
129 | gpio_free(GPIO84_VPAC270_PCMCIA_CD); | 80 | else |
130 | gpio_free(GPIO16_VPAC270_CF_RESET); | 81 | gpio_request_array(vpac270_cf_gpios, |
131 | gpio_free(GPIO12_VPAC270_CF_RDY); | 82 | ARRAY_SIZE(vpac270_cf_gpios)); |
132 | gpio_free(GPIO17_VPAC270_CF_CD); | ||
133 | } | 83 | } |
134 | 84 | ||
135 | static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 85 | static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index b37f92cb71bc..444b60aa15e9 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -139,24 +139,6 @@ static const char ep0name [] = "ep0"; | |||
139 | static void pxa25x_ep_fifo_flush (struct usb_ep *ep); | 139 | static void pxa25x_ep_fifo_flush (struct usb_ep *ep); |
140 | static void nuke (struct pxa25x_ep *, int status); | 140 | static void nuke (struct pxa25x_ep *, int status); |
141 | 141 | ||
142 | /* one GPIO should be used to detect VBUS from the host */ | ||
143 | static int is_vbus_present(void) | ||
144 | { | ||
145 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | ||
146 | |||
147 | if (gpio_is_valid(mach->gpio_vbus)) { | ||
148 | int value = gpio_get_value(mach->gpio_vbus); | ||
149 | |||
150 | if (mach->gpio_vbus_inverted) | ||
151 | return !value; | ||
152 | else | ||
153 | return !!value; | ||
154 | } | ||
155 | if (mach->udc_is_connected) | ||
156 | return mach->udc_is_connected(); | ||
157 | return 1; | ||
158 | } | ||
159 | |||
160 | /* one GPIO should control a D+ pullup, so host sees this device (or not) */ | 142 | /* one GPIO should control a D+ pullup, so host sees this device (or not) */ |
161 | static void pullup_off(void) | 143 | static void pullup_off(void) |
162 | { | 144 | { |
@@ -1055,7 +1037,7 @@ udc_seq_show(struct seq_file *m, void *_d) | |||
1055 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", | 1037 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", |
1056 | driver_name, DRIVER_VERSION SIZE_STR "(pio)", | 1038 | driver_name, DRIVER_VERSION SIZE_STR "(pio)", |
1057 | dev->driver ? dev->driver->driver.name : "(none)", | 1039 | dev->driver ? dev->driver->driver.name : "(none)", |
1058 | is_vbus_present() ? "full speed" : "disconnected"); | 1040 | dev->gadget.speed == USB_SPEED_FULL ? "full speed" : "disconnected"); |
1059 | 1041 | ||
1060 | /* registers for device and ep0 */ | 1042 | /* registers for device and ep0 */ |
1061 | seq_printf(m, | 1043 | seq_printf(m, |
@@ -1094,7 +1076,7 @@ udc_seq_show(struct seq_file *m, void *_d) | |||
1094 | (tmp & UDCCFR_ACM) ? " acm" : ""); | 1076 | (tmp & UDCCFR_ACM) ? " acm" : ""); |
1095 | } | 1077 | } |
1096 | 1078 | ||
1097 | if (!is_vbus_present() || !dev->driver) | 1079 | if (dev->gadget.speed != USB_SPEED_FULL || !dev->driver) |
1098 | goto done; | 1080 | goto done; |
1099 | 1081 | ||
1100 | seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", | 1082 | seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", |
@@ -1435,14 +1417,6 @@ lubbock_vbus_irq(int irq, void *_dev) | |||
1435 | 1417 | ||
1436 | #endif | 1418 | #endif |
1437 | 1419 | ||
1438 | static irqreturn_t udc_vbus_irq(int irq, void *_dev) | ||
1439 | { | ||
1440 | struct pxa25x_udc *dev = _dev; | ||
1441 | |||
1442 | pxa25x_udc_vbus_session(&dev->gadget, is_vbus_present()); | ||
1443 | return IRQ_HANDLED; | ||
1444 | } | ||
1445 | |||
1446 | 1420 | ||
1447 | /*-------------------------------------------------------------------------*/ | 1421 | /*-------------------------------------------------------------------------*/ |
1448 | 1422 | ||
@@ -1766,12 +1740,9 @@ pxa25x_udc_irq(int irq, void *_dev) | |||
1766 | if (unlikely(udccr & UDCCR_SUSIR)) { | 1740 | if (unlikely(udccr & UDCCR_SUSIR)) { |
1767 | udc_ack_int_UDCCR(UDCCR_SUSIR); | 1741 | udc_ack_int_UDCCR(UDCCR_SUSIR); |
1768 | handled = 1; | 1742 | handled = 1; |
1769 | DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present() | 1743 | DBG(DBG_VERBOSE, "USB suspend\n"); |
1770 | ? "" : "+disconnect"); | ||
1771 | 1744 | ||
1772 | if (!is_vbus_present()) | 1745 | if (dev->gadget.speed != USB_SPEED_UNKNOWN |
1773 | stop_activity(dev, dev->driver); | ||
1774 | else if (dev->gadget.speed != USB_SPEED_UNKNOWN | ||
1775 | && dev->driver | 1746 | && dev->driver |
1776 | && dev->driver->suspend) | 1747 | && dev->driver->suspend) |
1777 | dev->driver->suspend(&dev->gadget); | 1748 | dev->driver->suspend(&dev->gadget); |
@@ -1786,8 +1757,7 @@ pxa25x_udc_irq(int irq, void *_dev) | |||
1786 | 1757 | ||
1787 | if (dev->gadget.speed != USB_SPEED_UNKNOWN | 1758 | if (dev->gadget.speed != USB_SPEED_UNKNOWN |
1788 | && dev->driver | 1759 | && dev->driver |
1789 | && dev->driver->resume | 1760 | && dev->driver->resume) |
1790 | && is_vbus_present()) | ||
1791 | dev->driver->resume(&dev->gadget); | 1761 | dev->driver->resume(&dev->gadget); |
1792 | } | 1762 | } |
1793 | 1763 | ||
@@ -2137,7 +2107,7 @@ static struct pxa25x_udc memory = { | |||
2137 | static int __init pxa25x_udc_probe(struct platform_device *pdev) | 2107 | static int __init pxa25x_udc_probe(struct platform_device *pdev) |
2138 | { | 2108 | { |
2139 | struct pxa25x_udc *dev = &memory; | 2109 | struct pxa25x_udc *dev = &memory; |
2140 | int retval, vbus_irq, irq; | 2110 | int retval, irq; |
2141 | u32 chiprev; | 2111 | u32 chiprev; |
2142 | 2112 | ||
2143 | /* insist on Intel/ARM/XScale */ | 2113 | /* insist on Intel/ARM/XScale */ |
@@ -2199,19 +2169,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2199 | 2169 | ||
2200 | dev->transceiver = otg_get_transceiver(); | 2170 | dev->transceiver = otg_get_transceiver(); |
2201 | 2171 | ||
2202 | if (gpio_is_valid(dev->mach->gpio_vbus)) { | ||
2203 | if ((retval = gpio_request(dev->mach->gpio_vbus, | ||
2204 | "pxa25x_udc GPIO VBUS"))) { | ||
2205 | dev_dbg(&pdev->dev, | ||
2206 | "can't get vbus gpio %d, err: %d\n", | ||
2207 | dev->mach->gpio_vbus, retval); | ||
2208 | goto err_gpio_vbus; | ||
2209 | } | ||
2210 | gpio_direction_input(dev->mach->gpio_vbus); | ||
2211 | vbus_irq = gpio_to_irq(dev->mach->gpio_vbus); | ||
2212 | } else | ||
2213 | vbus_irq = 0; | ||
2214 | |||
2215 | if (gpio_is_valid(dev->mach->gpio_pullup)) { | 2172 | if (gpio_is_valid(dev->mach->gpio_pullup)) { |
2216 | if ((retval = gpio_request(dev->mach->gpio_pullup, | 2173 | if ((retval = gpio_request(dev->mach->gpio_pullup, |
2217 | "pca25x_udc GPIO PULLUP"))) { | 2174 | "pca25x_udc GPIO PULLUP"))) { |
@@ -2237,7 +2194,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2237 | udc_disable(dev); | 2194 | udc_disable(dev); |
2238 | udc_reinit(dev); | 2195 | udc_reinit(dev); |
2239 | 2196 | ||
2240 | dev->vbus = !!is_vbus_present(); | 2197 | dev->vbus = 0; |
2241 | 2198 | ||
2242 | /* irq setup after old hardware state is cleaned up */ | 2199 | /* irq setup after old hardware state is cleaned up */ |
2243 | retval = request_irq(irq, pxa25x_udc_irq, | 2200 | retval = request_irq(irq, pxa25x_udc_irq, |
@@ -2273,22 +2230,10 @@ lubbock_fail0: | |||
2273 | } | 2230 | } |
2274 | } else | 2231 | } else |
2275 | #endif | 2232 | #endif |
2276 | if (vbus_irq) { | ||
2277 | retval = request_irq(vbus_irq, udc_vbus_irq, | ||
2278 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM | | ||
2279 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
2280 | driver_name, dev); | ||
2281 | if (retval != 0) { | ||
2282 | pr_err("%s: can't get irq %i, err %d\n", | ||
2283 | driver_name, vbus_irq, retval); | ||
2284 | goto err_vbus_irq; | ||
2285 | } | ||
2286 | } | ||
2287 | create_debug_files(dev); | 2233 | create_debug_files(dev); |
2288 | 2234 | ||
2289 | return 0; | 2235 | return 0; |
2290 | 2236 | ||
2291 | err_vbus_irq: | ||
2292 | #ifdef CONFIG_ARCH_LUBBOCK | 2237 | #ifdef CONFIG_ARCH_LUBBOCK |
2293 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); | 2238 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); |
2294 | err_irq_lub: | 2239 | err_irq_lub: |
@@ -2298,9 +2243,6 @@ lubbock_fail0: | |||
2298 | if (gpio_is_valid(dev->mach->gpio_pullup)) | 2243 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
2299 | gpio_free(dev->mach->gpio_pullup); | 2244 | gpio_free(dev->mach->gpio_pullup); |
2300 | err_gpio_pullup: | 2245 | err_gpio_pullup: |
2301 | if (gpio_is_valid(dev->mach->gpio_vbus)) | ||
2302 | gpio_free(dev->mach->gpio_vbus); | ||
2303 | err_gpio_vbus: | ||
2304 | if (dev->transceiver) { | 2246 | if (dev->transceiver) { |
2305 | otg_put_transceiver(dev->transceiver); | 2247 | otg_put_transceiver(dev->transceiver); |
2306 | dev->transceiver = NULL; | 2248 | dev->transceiver = NULL; |
@@ -2337,10 +2279,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) | |||
2337 | free_irq(LUBBOCK_USB_IRQ, dev); | 2279 | free_irq(LUBBOCK_USB_IRQ, dev); |
2338 | } | 2280 | } |
2339 | #endif | 2281 | #endif |
2340 | if (gpio_is_valid(dev->mach->gpio_vbus)) { | ||
2341 | free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); | ||
2342 | gpio_free(dev->mach->gpio_vbus); | ||
2343 | } | ||
2344 | if (gpio_is_valid(dev->mach->gpio_pullup)) | 2282 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
2345 | gpio_free(dev->mach->gpio_pullup); | 2283 | gpio_free(dev->mach->gpio_pullup); |
2346 | 2284 | ||
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 825b665245bb..a2e5b5100ab4 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -627,7 +627,12 @@ static void overlay1fb_enable(struct pxafb_layer *ofb) | |||
627 | 627 | ||
628 | static void overlay1fb_disable(struct pxafb_layer *ofb) | 628 | static void overlay1fb_disable(struct pxafb_layer *ofb) |
629 | { | 629 | { |
630 | uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5); | 630 | uint32_t lccr5; |
631 | |||
632 | if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN)) | ||
633 | return; | ||
634 | |||
635 | lccr5 = lcd_readl(ofb->fbi, LCCR5); | ||
631 | 636 | ||
632 | lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN); | 637 | lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN); |
633 | 638 | ||
@@ -685,7 +690,12 @@ static void overlay2fb_enable(struct pxafb_layer *ofb) | |||
685 | 690 | ||
686 | static void overlay2fb_disable(struct pxafb_layer *ofb) | 691 | static void overlay2fb_disable(struct pxafb_layer *ofb) |
687 | { | 692 | { |
688 | uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5); | 693 | uint32_t lccr5; |
694 | |||
695 | if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN)) | ||
696 | return; | ||
697 | |||
698 | lccr5 = lcd_readl(ofb->fbi, LCCR5); | ||
689 | 699 | ||
690 | lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN); | 700 | lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN); |
691 | 701 | ||
@@ -720,12 +730,10 @@ static int overlayfb_open(struct fb_info *info, int user) | |||
720 | if (user == 0) | 730 | if (user == 0) |
721 | return -ENODEV; | 731 | return -ENODEV; |
722 | 732 | ||
723 | /* allow only one user at a time */ | 733 | if (ofb->usage++ == 0) |
724 | if (atomic_inc_and_test(&ofb->usage)) | 734 | /* unblank the base framebuffer */ |
725 | return -EBUSY; | 735 | fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK); |
726 | 736 | ||
727 | /* unblank the base framebuffer */ | ||
728 | fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK); | ||
729 | return 0; | 737 | return 0; |
730 | } | 738 | } |
731 | 739 | ||
@@ -733,12 +741,15 @@ static int overlayfb_release(struct fb_info *info, int user) | |||
733 | { | 741 | { |
734 | struct pxafb_layer *ofb = (struct pxafb_layer*) info; | 742 | struct pxafb_layer *ofb = (struct pxafb_layer*) info; |
735 | 743 | ||
736 | atomic_dec(&ofb->usage); | 744 | if (ofb->usage == 1) { |
737 | ofb->ops->disable(ofb); | 745 | ofb->ops->disable(ofb); |
746 | ofb->fb.var.height = -1; | ||
747 | ofb->fb.var.width = -1; | ||
748 | ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0; | ||
749 | ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0; | ||
738 | 750 | ||
739 | free_pages_exact(ofb->video_mem, ofb->video_mem_size); | 751 | ofb->usage--; |
740 | ofb->video_mem = NULL; | 752 | } |
741 | ofb->video_mem_size = 0; | ||
742 | return 0; | 753 | return 0; |
743 | } | 754 | } |
744 | 755 | ||
@@ -750,7 +761,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var, | |||
750 | int xpos, ypos, pfor, bpp; | 761 | int xpos, ypos, pfor, bpp; |
751 | 762 | ||
752 | xpos = NONSTD_TO_XPOS(var->nonstd); | 763 | xpos = NONSTD_TO_XPOS(var->nonstd); |
753 | ypos = NONSTD_TO_XPOS(var->nonstd); | 764 | ypos = NONSTD_TO_YPOS(var->nonstd); |
754 | pfor = NONSTD_TO_PFOR(var->nonstd); | 765 | pfor = NONSTD_TO_PFOR(var->nonstd); |
755 | 766 | ||
756 | bpp = pxafb_var_to_bpp(var); | 767 | bpp = pxafb_var_to_bpp(var); |
@@ -794,7 +805,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var, | |||
794 | return 0; | 805 | return 0; |
795 | } | 806 | } |
796 | 807 | ||
797 | static int overlayfb_map_video_memory(struct pxafb_layer *ofb) | 808 | static int overlayfb_check_video_memory(struct pxafb_layer *ofb) |
798 | { | 809 | { |
799 | struct fb_var_screeninfo *var = &ofb->fb.var; | 810 | struct fb_var_screeninfo *var = &ofb->fb.var; |
800 | int pfor = NONSTD_TO_PFOR(var->nonstd); | 811 | int pfor = NONSTD_TO_PFOR(var->nonstd); |
@@ -812,27 +823,11 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb) | |||
812 | 823 | ||
813 | size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual); | 824 | size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual); |
814 | 825 | ||
815 | /* don't re-allocate if the original video memory is enough */ | ||
816 | if (ofb->video_mem) { | 826 | if (ofb->video_mem) { |
817 | if (ofb->video_mem_size >= size) | 827 | if (ofb->video_mem_size >= size) |
818 | return 0; | 828 | return 0; |
819 | |||
820 | free_pages_exact(ofb->video_mem, ofb->video_mem_size); | ||
821 | } | 829 | } |
822 | 830 | return -EINVAL; | |
823 | ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); | ||
824 | if (ofb->video_mem == NULL) | ||
825 | return -ENOMEM; | ||
826 | |||
827 | ofb->video_mem_phys = virt_to_phys(ofb->video_mem); | ||
828 | ofb->video_mem_size = size; | ||
829 | |||
830 | mutex_lock(&ofb->fb.mm_lock); | ||
831 | ofb->fb.fix.smem_start = ofb->video_mem_phys; | ||
832 | ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual; | ||
833 | mutex_unlock(&ofb->fb.mm_lock); | ||
834 | ofb->fb.screen_base = ofb->video_mem; | ||
835 | return 0; | ||
836 | } | 831 | } |
837 | 832 | ||
838 | static int overlayfb_set_par(struct fb_info *info) | 833 | static int overlayfb_set_par(struct fb_info *info) |
@@ -841,13 +836,13 @@ static int overlayfb_set_par(struct fb_info *info) | |||
841 | struct fb_var_screeninfo *var = &info->var; | 836 | struct fb_var_screeninfo *var = &info->var; |
842 | int xpos, ypos, pfor, bpp, ret; | 837 | int xpos, ypos, pfor, bpp, ret; |
843 | 838 | ||
844 | ret = overlayfb_map_video_memory(ofb); | 839 | ret = overlayfb_check_video_memory(ofb); |
845 | if (ret) | 840 | if (ret) |
846 | return ret; | 841 | return ret; |
847 | 842 | ||
848 | bpp = pxafb_var_to_bpp(var); | 843 | bpp = pxafb_var_to_bpp(var); |
849 | xpos = NONSTD_TO_XPOS(var->nonstd); | 844 | xpos = NONSTD_TO_XPOS(var->nonstd); |
850 | ypos = NONSTD_TO_XPOS(var->nonstd); | 845 | ypos = NONSTD_TO_YPOS(var->nonstd); |
851 | pfor = NONSTD_TO_PFOR(var->nonstd); | 846 | pfor = NONSTD_TO_PFOR(var->nonstd); |
852 | 847 | ||
853 | ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) | | 848 | ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) | |
@@ -891,7 +886,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi, | |||
891 | 886 | ||
892 | ofb->id = id; | 887 | ofb->id = id; |
893 | ofb->ops = &ofb_ops[id]; | 888 | ofb->ops = &ofb_ops[id]; |
894 | atomic_set(&ofb->usage, 0); | 889 | ofb->usage = 0; |
895 | ofb->fbi = fbi; | 890 | ofb->fbi = fbi; |
896 | init_completion(&ofb->branch_done); | 891 | init_completion(&ofb->branch_done); |
897 | } | 892 | } |
@@ -904,29 +899,60 @@ static inline int pxafb_overlay_supported(void) | |||
904 | return 0; | 899 | return 0; |
905 | } | 900 | } |
906 | 901 | ||
907 | static int __devinit pxafb_overlay_init(struct pxafb_info *fbi) | 902 | static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb, |
903 | struct pxafb_layer *ofb) | ||
904 | { | ||
905 | /* We assume that user will use at most video_mem_size for overlay fb, | ||
906 | * anyway, it's useless to use 16bpp main plane and 24bpp overlay | ||
907 | */ | ||
908 | ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size), | ||
909 | GFP_KERNEL | __GFP_ZERO); | ||
910 | if (ofb->video_mem == NULL) | ||
911 | return -ENOMEM; | ||
912 | |||
913 | ofb->video_mem_phys = virt_to_phys(ofb->video_mem); | ||
914 | ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size); | ||
915 | |||
916 | mutex_lock(&ofb->fb.mm_lock); | ||
917 | ofb->fb.fix.smem_start = ofb->video_mem_phys; | ||
918 | ofb->fb.fix.smem_len = pxafb->video_mem_size; | ||
919 | mutex_unlock(&ofb->fb.mm_lock); | ||
920 | |||
921 | ofb->fb.screen_base = ofb->video_mem; | ||
922 | |||
923 | return 0; | ||
924 | } | ||
925 | |||
926 | static void __devinit pxafb_overlay_init(struct pxafb_info *fbi) | ||
908 | { | 927 | { |
909 | int i, ret; | 928 | int i, ret; |
910 | 929 | ||
911 | if (!pxafb_overlay_supported()) | 930 | if (!pxafb_overlay_supported()) |
912 | return 0; | 931 | return; |
913 | 932 | ||
914 | for (i = 0; i < 2; i++) { | 933 | for (i = 0; i < 2; i++) { |
915 | init_pxafb_overlay(fbi, &fbi->overlay[i], i); | 934 | struct pxafb_layer *ofb = &fbi->overlay[i]; |
916 | ret = register_framebuffer(&fbi->overlay[i].fb); | 935 | init_pxafb_overlay(fbi, ofb, i); |
936 | ret = register_framebuffer(&ofb->fb); | ||
917 | if (ret) { | 937 | if (ret) { |
918 | dev_err(fbi->dev, "failed to register overlay %d\n", i); | 938 | dev_err(fbi->dev, "failed to register overlay %d\n", i); |
919 | return ret; | 939 | continue; |
920 | } | 940 | } |
941 | ret = pxafb_overlay_map_video_memory(fbi, ofb); | ||
942 | if (ret) { | ||
943 | dev_err(fbi->dev, | ||
944 | "failed to map video memory for overlay %d\n", | ||
945 | i); | ||
946 | unregister_framebuffer(&ofb->fb); | ||
947 | continue; | ||
948 | } | ||
949 | ofb->registered = 1; | ||
921 | } | 950 | } |
922 | 951 | ||
923 | /* mask all IU/BS/EOF/SOF interrupts */ | 952 | /* mask all IU/BS/EOF/SOF interrupts */ |
924 | lcd_writel(fbi, LCCR5, ~0); | 953 | lcd_writel(fbi, LCCR5, ~0); |
925 | 954 | ||
926 | /* place overlay(s) on top of base */ | ||
927 | fbi->lccr0 |= LCCR0_OUC; | ||
928 | pr_info("PXA Overlay driver loaded successfully!\n"); | 955 | pr_info("PXA Overlay driver loaded successfully!\n"); |
929 | return 0; | ||
930 | } | 956 | } |
931 | 957 | ||
932 | static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) | 958 | static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) |
@@ -936,8 +962,15 @@ static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) | |||
936 | if (!pxafb_overlay_supported()) | 962 | if (!pxafb_overlay_supported()) |
937 | return; | 963 | return; |
938 | 964 | ||
939 | for (i = 0; i < 2; i++) | 965 | for (i = 0; i < 2; i++) { |
940 | unregister_framebuffer(&fbi->overlay[i].fb); | 966 | struct pxafb_layer *ofb = &fbi->overlay[i]; |
967 | if (ofb->registered) { | ||
968 | if (ofb->video_mem) | ||
969 | free_pages_exact(ofb->video_mem, | ||
970 | ofb->video_mem_size); | ||
971 | unregister_framebuffer(&ofb->fb); | ||
972 | } | ||
973 | } | ||
941 | } | 974 | } |
942 | #else | 975 | #else |
943 | static inline void pxafb_overlay_init(struct pxafb_info *fbi) {} | 976 | static inline void pxafb_overlay_init(struct pxafb_info *fbi) {} |
@@ -1368,7 +1401,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, | |||
1368 | (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) || | 1401 | (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) || |
1369 | (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) || | 1402 | (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) || |
1370 | (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) || | 1403 | (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) || |
1371 | (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])) | 1404 | ((fbi->lccr0 & LCCR0_SDS) && |
1405 | (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))) | ||
1372 | pxafb_schedule_work(fbi, C_REENABLE); | 1406 | pxafb_schedule_work(fbi, C_REENABLE); |
1373 | 1407 | ||
1374 | return 0; | 1408 | return 0; |
@@ -1420,7 +1454,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi) | |||
1420 | lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); | 1454 | lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); |
1421 | 1455 | ||
1422 | lcd_writel(fbi, FDADR0, fbi->fdadr[0]); | 1456 | lcd_writel(fbi, FDADR0, fbi->fdadr[0]); |
1423 | lcd_writel(fbi, FDADR1, fbi->fdadr[1]); | 1457 | if (fbi->lccr0 & LCCR0_SDS) |
1458 | lcd_writel(fbi, FDADR1, fbi->fdadr[1]); | ||
1424 | lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); | 1459 | lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); |
1425 | } | 1460 | } |
1426 | 1461 | ||
@@ -1613,7 +1648,8 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) | |||
1613 | 1648 | ||
1614 | switch (val) { | 1649 | switch (val) { |
1615 | case CPUFREQ_PRECHANGE: | 1650 | case CPUFREQ_PRECHANGE: |
1616 | set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); | 1651 | if (!fbi->overlay[0].usage && !fbi->overlay[1].usage) |
1652 | set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); | ||
1617 | break; | 1653 | break; |
1618 | 1654 | ||
1619 | case CPUFREQ_POSTCHANGE: | 1655 | case CPUFREQ_POSTCHANGE: |
@@ -1806,6 +1842,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev) | |||
1806 | 1842 | ||
1807 | pxafb_decode_mach_info(fbi, inf); | 1843 | pxafb_decode_mach_info(fbi, inf); |
1808 | 1844 | ||
1845 | #ifdef CONFIG_FB_PXA_OVERLAY | ||
1846 | /* place overlay(s) on top of base */ | ||
1847 | if (pxafb_overlay_supported()) | ||
1848 | fbi->lccr0 |= LCCR0_OUC; | ||
1849 | #endif | ||
1850 | |||
1809 | init_waitqueue_head(&fbi->ctrlr_wait); | 1851 | init_waitqueue_head(&fbi->ctrlr_wait); |
1810 | INIT_WORK(&fbi->task, pxafb_task); | 1852 | INIT_WORK(&fbi->task, pxafb_task); |
1811 | mutex_init(&fbi->ctrlr_lock); | 1853 | mutex_init(&fbi->ctrlr_lock); |
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h index 2353521c5c8c..26ba9fa3f737 100644 --- a/drivers/video/pxafb.h +++ b/drivers/video/pxafb.h | |||
@@ -92,7 +92,8 @@ struct pxafb_layer_ops { | |||
92 | struct pxafb_layer { | 92 | struct pxafb_layer { |
93 | struct fb_info fb; | 93 | struct fb_info fb; |
94 | int id; | 94 | int id; |
95 | atomic_t usage; | 95 | int registered; |
96 | uint32_t usage; | ||
96 | uint32_t control[2]; | 97 | uint32_t control[2]; |
97 | 98 | ||
98 | struct pxafb_layer_ops *ops; | 99 | struct pxafb_layer_ops *ops; |