diff options
51 files changed, 514 insertions, 582 deletions
diff --git a/arch/arm/include/asm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h index 833306ee9e7..ea297ac70bc 100644 --- a/arch/arm/include/asm/mach/udc_pxa2xx.h +++ b/arch/arm/include/asm/mach/udc_pxa2xx.h @@ -20,8 +20,6 @@ struct pxa2xx_udc_mach_info { * VBUS IRQ and omit the methods above. Store the GPIO number * here. Note that sometimes the signals go through inverters... */ - bool gpio_vbus_inverted; - int gpio_vbus; /* high == vbus present */ bool gpio_pullup_inverted; int gpio_pullup; /* high == pullup activated */ }; diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c index 3499fada73a..4cb069fd9af 100644 --- a/arch/arm/mach-pxa/am200epd.c +++ b/arch/arm/mach-pxa/am200epd.c @@ -128,8 +128,8 @@ static int am200_init_gpio_regs(struct metronomefb_par *par) return 0; err_req_gpio: - while (i > 0) - gpio_free(gpios[i--]); + while (--i >= 0) + gpio_free(gpios[i]); return err; } @@ -194,7 +194,7 @@ static struct notifier_block am200_fb_notif = { }; /* this gets called as part of our init. these steps must be done now so - * that we can use set_pxa_fb_info */ + * that we can use pxa_set_fb_info */ static void __init am200_presetup_fb(void) { int fw; @@ -249,7 +249,7 @@ static void __init am200_presetup_fb(void) /* we divide since we told the LCD controller we're 16bpp */ am200_fb_info.modes->xres /= 2; - set_pxa_fb_info(&am200_fb_info); + pxa_set_fb_info(NULL, &am200_fb_info); } diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c index 993d75e6639..fa8bad235d9 100644 --- a/arch/arm/mach-pxa/am300epd.c +++ b/arch/arm/mach-pxa/am300epd.c @@ -125,10 +125,7 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par) if (err) { dev_err(&am300_device->dev, "failed requesting " "gpio %d, err=%d\n", i, err); - while (i >= DB0_GPIO_PIN) - gpio_free(i--); - i = ARRAY_SIZE(gpios) - 1; - goto err_req_gpio; + goto err_req_gpio2; } } @@ -159,9 +156,13 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par) return 0; +err_req_gpio2: + while (--i >= DB0_GPIO_PIN) + gpio_free(i); + i = ARRAY_SIZE(gpios); err_req_gpio: - while (i > 0) - gpio_free(gpios[i--]); + while (--i >= 0) + gpio_free(gpios[i]); return err; } diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index d2af73321da..c6661b1d30b 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -263,7 +263,7 @@ static void __init balloon3_lcd_init(void) } balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power; - set_pxa_fb_info(&balloon3_lcd_screen); + pxa_set_fb_info(NULL, &balloon3_lcd_screen); return; err2: diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index b734d846816..8225e2e58c6 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -379,7 +379,7 @@ __setup("monitor=", cmx2xx_set_display); static void __init cmx2xx_init_display(void) { - set_pxa_fb_info(cmx2xx_display); + pxa_set_fb_info(NULL, cmx2xx_display); } #else static inline void cmx2xx_init_display(void) {} diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index bfca7ed2fea..7a8edba0dcd 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -296,7 +296,7 @@ static struct pxafb_mach_info cm_x300_lcd = { static void __init cm_x300_init_lcd(void) { - set_pxa_fb_info(&cm_x300_lcd); + pxa_set_fb_info(NULL, &cm_x300_lcd); } #else static inline void cm_x300_init_lcd(void) {} diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c index ee797397dc5..44c1b77ece6 100644 --- a/arch/arm/mach-pxa/colibri-pxa270-income.c +++ b/arch/arm/mach-pxa/colibri-pxa270-income.c @@ -175,7 +175,7 @@ static struct pxafb_mach_info income_lcd_screen = { static void __init income_lcd_init(void) { - set_pxa_fb_info(&income_lcd_screen); + pxa_set_fb_info(NULL, &income_lcd_screen); } #else static inline void income_lcd_init(void) {} diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c index 96b2d9fbfef..3f9be419959 100644 --- a/arch/arm/mach-pxa/colibri-pxa3xx.c +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c @@ -105,7 +105,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin) lcd_bl_pin = bl_pin; gpio_request(bl_pin, "lcd backlight"); gpio_direction_output(bl_pin, 0); - set_pxa_fb_info(&sharp_lq43_info); + pxa_set_fb_info(NULL, &sharp_lq43_info); } #endif diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index d4e705caefe..3a5507e3191 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -462,7 +462,6 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = { * USB Device Controller */ static struct pxa2xx_udc_mach_info udc_info __initdata = { - .gpio_vbus = -1, /* no connect GPIO; corgi can't tell connection status */ .gpio_pullup = CORGI_GPIO_USB_PULLUP, }; diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index c4bf08b3eb6..2e0425404de 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -90,7 +90,6 @@ void __init pxa_set_mci_info(struct pxamci_platform_data *info) static struct pxa2xx_udc_mach_info pxa_udc_info = { .gpio_pullup = -1, - .gpio_vbus = -1, }; void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info) @@ -188,16 +187,12 @@ struct platform_device pxa_device_fb = { .resource = pxafb_resources, }; -void __init set_pxa_fb_info(struct pxafb_mach_info *info) +void __init pxa_set_fb_info(struct device *parent, struct pxafb_mach_info *info) { + pxa_device_fb.dev.parent = parent; pxa_register_device(&pxa_device_fb, info); } -void __init set_pxa_fb_parent(struct device *parent_dev) -{ - pxa_device_fb.dev.parent = parent_dev; -} - static struct resource pxa_resource_ffuart[] = { { .start = 0x40100000, diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index b411d7cbf5a..f8a6e9d79a3 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -689,7 +689,7 @@ static struct pxafb_mach_info em_x270_lcd = { static void __init em_x270_init_lcd(void) { - set_pxa_fb_info(&em_x270_lcd); + pxa_set_fb_info(NULL, &em_x270_lcd); } #else static inline void em_x270_init_lcd(void) {} diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index edca0a04329..2e3970fdde0 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -20,6 +20,7 @@ #include <linux/mfd/t7l66xb.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> +#include <linux/usb/gpio_vbus.h> #include <video/w100fb.h> @@ -51,12 +52,20 @@ void __init eseries_fixup(struct machine_desc *desc, mi->bank[0].size = (64*1024*1024); } -struct pxa2xx_udc_mach_info e7xx_udc_mach_info = { +struct gpio_vbus_mach_info e7xx_udc_info = { .gpio_vbus = GPIO_E7XX_USB_DISC, .gpio_pullup = GPIO_E7XX_USB_PULLUP, .gpio_pullup_inverted = 1 }; +static struct platform_device e7xx_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &e7xx_udc_info, + }, +}; + struct pxaficp_platform_data e7xx_ficp_platform_data = { .gpio_pwdown = GPIO_E7XX_IR_OFF, .transceiver_cap = IR_SIRMODE | IR_OFF, @@ -165,6 +174,7 @@ static struct platform_device e330_tc6387xb_device = { static struct platform_device *e330_devices[] __initdata = { &e330_tc6387xb_device, + &e7xx_gpio_vbus, }; static void __init e330_init(void) @@ -175,7 +185,6 @@ static void __init e330_init(void) eseries_register_clks(); eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e330_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); } MACHINE_START(E330, "Toshiba e330") @@ -214,6 +223,7 @@ static struct platform_device e350_t7l66xb_device = { static struct platform_device *e350_devices[] __initdata = { &e350_t7l66xb_device, + &e7xx_gpio_vbus, }; static void __init e350_init(void) @@ -224,7 +234,6 @@ static void __init e350_init(void) eseries_register_clks(); eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e350_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); } MACHINE_START(E350, "Toshiba e350") @@ -333,6 +342,7 @@ static struct platform_device e400_t7l66xb_device = { static struct platform_device *e400_devices[] __initdata = { &e400_t7l66xb_device, + &e7xx_gpio_vbus, }; static void __init e400_init(void) @@ -344,9 +354,8 @@ static void __init e400_init(void) /* Fixme - e400 may have a switched clock */ eseries_register_clks(); eseries_get_tmio_gpios(); - set_pxa_fb_info(&e400_pxafb_mach_info); + pxa_set_fb_info(NULL, &e400_pxafb_mach_info); platform_add_devices(ARRAY_AND_SIZE(e400_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); } MACHINE_START(E400, "Toshiba e400") @@ -519,6 +528,7 @@ static struct platform_device e740_t7l66xb_device = { static struct platform_device *e740_devices[] __initdata = { &e740_fb_device, &e740_t7l66xb_device, + &e7xx_gpio_vbus, }; static void __init e740_init(void) @@ -532,7 +542,6 @@ static void __init e740_init(void) "UDCCLK", &pxa25x_device_udc.dev), eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e740_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); pxa_set_ac97_info(NULL); pxa_set_ficp_info(&e7xx_ficp_platform_data); } @@ -711,6 +720,7 @@ static struct platform_device e750_tc6393xb_device = { static struct platform_device *e750_devices[] __initdata = { &e750_fb_device, &e750_tc6393xb_device, + &e7xx_gpio_vbus, }; static void __init e750_init(void) @@ -723,7 +733,6 @@ static void __init e750_init(void) "GPIO11_CLK", NULL), eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e750_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); pxa_set_ac97_info(NULL); pxa_set_ficp_info(&e7xx_ficp_platform_data); } @@ -873,12 +882,21 @@ static struct platform_device e800_fb_device = { /* --------------------------- UDC definitions --------------------------- */ -static struct pxa2xx_udc_mach_info e800_udc_mach_info = { +static struct gpio_vbus_mach_info e800_udc_info = { .gpio_vbus = GPIO_E800_USB_DISC, .gpio_pullup = GPIO_E800_USB_PULLUP, .gpio_pullup_inverted = 1 }; +static struct platform_device e800_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &e800_udc_info, + }, +}; + + /* ----------------- e800 tc6393xb parameters ------------------ */ static struct tc6393xb_platform_data e800_tc6393xb_info = { @@ -907,6 +925,7 @@ static struct platform_device e800_tc6393xb_device = { static struct platform_device *e800_devices[] __initdata = { &e800_fb_device, &e800_tc6393xb_device, + &e800_gpio_vbus, }; static void __init e800_init(void) @@ -919,7 +938,6 @@ static void __init e800_init(void) "GPIO11_CLK", NULL), eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e800_devices)); - pxa_set_udc_info(&e800_udc_mach_info); pxa_set_ac97_info(NULL); } diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index 93f05e02431..d88aed8fbe1 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -783,7 +783,7 @@ static void __init a780_init(void) pxa_set_i2c_info(NULL); - set_pxa_fb_info(&ezx_fb_info_1); + pxa_set_fb_info(NULL, &ezx_fb_info_1); pxa_set_keypad_info(&a780_keypad_platform_data); @@ -853,7 +853,7 @@ static void __init e680_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_1); + pxa_set_fb_info(NULL, &ezx_fb_info_1); pxa_set_keypad_info(&e680_keypad_platform_data); @@ -918,7 +918,7 @@ static void __init a1200_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_2); + pxa_set_fb_info(NULL, &ezx_fb_info_2); pxa_set_keypad_info(&a1200_keypad_platform_data); @@ -1103,7 +1103,7 @@ static void __init a910_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_2); + pxa_set_fb_info(NULL, &ezx_fb_info_2); pxa_set_keypad_info(&a910_keypad_platform_data); @@ -1173,7 +1173,7 @@ static void __init e6_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_2); + pxa_set_fb_info(NULL, &ezx_fb_info_2); pxa_set_keypad_info(&e6_keypad_platform_data); @@ -1212,7 +1212,7 @@ static void __init e2_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_2); + pxa_set_fb_info(NULL, &ezx_fb_info_2); pxa_set_keypad_info(&e2_keypad_platform_data); diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index 6fd319ea528..d65e4bde9b9 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -26,6 +26,7 @@ #include <linux/gpio.h> #include <linux/err.h> #include <linux/clk.h> +#include <linux/usb/gpio_vbus.h> #include <asm/setup.h> #include <asm/memory.h> @@ -106,14 +107,22 @@ static void __init gumstix_mmc_init(void) #endif #ifdef CONFIG_USB_GADGET_PXA25X -static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = { +static struct gpio_vbus_mach_info gumstix_udc_info = { .gpio_vbus = GPIO_GUMSTIX_USB_GPIOn, .gpio_pullup = GPIO_GUMSTIX_USB_GPIOx, }; +static struct platform_device gumstix_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &gumstix_udc_info, + }, +}; + static void __init gumstix_udc_init(void) { - pxa_set_udc_info(&gumstix_udc_info); + platform_device_register(&gumstix_gpio_vbus); } #else static void gumstix_udc_init(void) diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index dd40e4a9291..f7fb64f11a7 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -167,7 +167,7 @@ static void __init idp_init(void) platform_device_register(&smc91x_device); //platform_device_register(&mst_audio_device); - set_pxa_fb_info(&sharp_lm8v31); + pxa_set_fb_info(NULL, &sharp_lm8v31); pxa_set_mci_info(&idp_mci_platform_data); } diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h index 2bbcf70dd93..0d4700a7961 100644 --- a/arch/arm/mach-pxa/include/mach/palmz72.h +++ b/arch/arm/mach-pxa/include/mach/palmz72.h @@ -44,6 +44,11 @@ #define GPIO_NR_PALMZ72_BT_POWER 17 #define GPIO_NR_PALMZ72_BT_RESET 83 +/* Camera */ +#define GPIO_NR_PALMZ72_CAM_PWDN 56 +#define GPIO_NR_PALMZ72_CAM_RESET 57 +#define GPIO_NR_PALMZ72_CAM_POWER 91 + /** Initial values **/ /* Battery */ diff --git a/arch/arm/mach-pxa/include/mach/pxafb.h b/arch/arm/mach-pxa/include/mach/pxafb.h index 160ec83f51a..01a45ac4811 100644 --- a/arch/arm/mach-pxa/include/mach/pxafb.h +++ b/arch/arm/mach-pxa/include/mach/pxafb.h @@ -154,8 +154,8 @@ struct pxafb_mach_info { void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *); void (*smart_update)(struct fb_info *); }; -void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info); -void set_pxa_fb_parent(struct device *parent_dev); + +void pxa_set_fb_info(struct device *, struct pxafb_mach_info *); unsigned long pxafb_get_hsync_time(struct device *dev); extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int); diff --git a/arch/arm/mach-pxa/include/mach/z2.h b/arch/arm/mach-pxa/include/mach/z2.h index 8835c16bc82..7b0f71ef316 100644 --- a/arch/arm/mach-pxa/include/mach/z2.h +++ b/arch/arm/mach-pxa/include/mach/z2.h @@ -25,8 +25,7 @@ #define GPIO98_ZIPITZ2_LID_BUTTON 98 /* Libertas GSPI8686 WiFi */ -#define GPIO14_ZIPITZ2_WIFI_RESET 14 -#define GPIO15_ZIPITZ2_WIFI_POWER 15 +#define GPIO14_ZIPITZ2_WIFI_POWER 14 #define GPIO24_ZIPITZ2_WIFI_CS 24 #define GPIO36_ZIPITZ2_WIFI_IRQ 36 diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 87c1ed9ccd2..e5e326d2cdc 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -185,7 +185,7 @@ static struct pxafb_mach_info littleton_lcd_info = { static void littleton_init_lcd(void) { - set_pxa_fb_info(&littleton_lcd_info); + pxa_set_fb_info(NULL, &littleton_lcd_info); } #else static inline void littleton_init_lcd(void) {}; diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index c9a3e775c2d..8aebc58c9f1 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -480,7 +480,7 @@ static void __init lpd270_init(void) pxa_set_ac97_info(NULL); if (lpd270_lcd_to_use != NULL) - set_pxa_fb_info(lpd270_lcd_to_use); + pxa_set_fb_info(NULL, lpd270_lcd_to_use); pxa_set_ohci_info(&lpd270_ohci_platform_data); } diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index dca20de306b..12a2a56b215 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -521,7 +521,7 @@ static void __init lubbock_init(void) clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL); pxa_set_udc_info(&udc_info); - set_pxa_fb_info(&sharp_lm8v31); + pxa_set_fb_info(NULL, &sharp_lm8v31); pxa_set_mci_info(&lubbock_mci_platform_data); pxa_set_ficp_info(&lubbock_ficp_platform_data); pxa_set_ac97_info(NULL); diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 5535991c4a3..a72993dde2b 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -757,7 +757,7 @@ static void __init magician_init(void) gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0); gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0); gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0); - set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info); + pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info); } else pr_err("LCD detection: CPLD mapping failed\n"); } diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index f9542220595..8306b227e61 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -592,7 +592,7 @@ static void __init mainstone_init(void) else mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode; - set_pxa_fb_info(&mainstone_pxafb_info); + pxa_set_fb_info(NULL, &mainstone_pxafb_info); mainstone_backlight_register(); pxa_set_mci_info(&mainstone_mci_platform_data); diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 78d98a8607e..dd13bb63259 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -795,7 +795,7 @@ static void __init mioa701_machine_init(void) pxa_set_stuart_info(NULL); mio_gpio_request(ARRAY_AND_SIZE(global_gpios)); bootstrap_init(); - set_pxa_fb_info(&mioa701_pxafb_info); + pxa_set_fb_info(NULL, &mioa701_pxafb_info); pxa_set_mci_info(&mioa701_mci_info); pxa_set_keypad_info(&mioa701_keypad_info); pxa_set_udc_info(&mioa701_udc_info); diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index 72adb3ae2b4..325c245c0a0 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c @@ -1,8 +1,7 @@ /* * Common code for Palm LD, T5, TX, Z72 * - * Copyright (C) 2010 - * Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -158,7 +157,7 @@ void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode) palm27x_lcd_screen.pxafb_lcd_power = palm27x_lcd_ctl; } - set_pxa_fb_info(&palm27x_lcd_screen); + pxa_set_fb_info(NULL, &palm27x_lcd_screen); } #endif diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index a09a2374697..fb06bd04727 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -507,7 +507,7 @@ static struct pxafb_mach_info palmtc_lcd_screen = { static void __init palmtc_lcd_init(void) { - set_pxa_fb_info(&palmtc_lcd_screen); + pxa_set_fb_info(NULL, &palmtc_lcd_screen); } #else static inline void palmtc_lcd_init(void) {} diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 3f25014a136..726f5b98dcd 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -136,30 +136,14 @@ static struct platform_device palmte2_pxa_keys = { /****************************************************************************** * Backlight ******************************************************************************/ +static struct gpio palmte_bl_gpios[] = { + { GPIO_NR_PALMTE2_BL_POWER, GPIOF_INIT_LOW, "Backlight power" }, + { GPIO_NR_PALMTE2_LCD_POWER, GPIOF_INIT_LOW, "LCD power" }, +}; + static int palmte2_backlight_init(struct device *dev) { - int ret; - - ret = gpio_request(GPIO_NR_PALMTE2_BL_POWER, "BL POWER"); - if (ret) - goto err; - ret = gpio_direction_output(GPIO_NR_PALMTE2_BL_POWER, 0); - if (ret) - goto err2; - ret = gpio_request(GPIO_NR_PALMTE2_LCD_POWER, "LCD POWER"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMTE2_LCD_POWER, 0); - if (ret) - goto err3; - - return 0; -err3: - gpio_free(GPIO_NR_PALMTE2_LCD_POWER); -err2: - gpio_free(GPIO_NR_PALMTE2_BL_POWER); -err: - return ret; + return gpio_request_array(ARRAY_AND_SIZE(palmte_bl_gpios)); } static int palmte2_backlight_notify(struct device *dev, int brightness) @@ -171,8 +155,7 @@ static int palmte2_backlight_notify(struct device *dev, int brightness) static void palmte2_backlight_exit(struct device *dev) { - gpio_free(GPIO_NR_PALMTE2_BL_POWER); - gpio_free(GPIO_NR_PALMTE2_LCD_POWER); + gpio_free_array(ARRAY_AND_SIZE(palmte_bl_gpios)); } static struct platform_pwm_backlight_data palmte2_backlight_data = { @@ -363,7 +346,7 @@ static void __init palmte2_init(void) pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); - set_pxa_fb_info(&palmte2_lcd_screen); + pxa_set_fb_info(NULL, &palmte2_lcd_screen); pxa_set_mci_info(&palmte2_mci_platform_data); palmte2_udc_init(); pxa_set_ac97_info(&palmte2_ac97_pdata); diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index 3010193b081..3b8a4f37dbb 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -30,6 +30,7 @@ #include <linux/wm97xx.h> #include <linux/power_supply.h> #include <linux/usb/gpio_vbus.h> +#include <linux/i2c-gpio.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -47,6 +48,9 @@ #include <mach/palm27x.h> #include <mach/pm.h> +#include <mach/camera.h> + +#include <media/soc_camera.h> #include "generic.h" #include "devices.h" @@ -103,6 +107,28 @@ static unsigned long palmz72_pin_config[] __initdata = { GPIO22_GPIO, /* LCD border color */ GPIO96_GPIO, /* lcd power */ + /* PXA Camera */ + GPIO81_CIF_DD_0, + GPIO48_CIF_DD_5, + GPIO50_CIF_DD_3, + GPIO51_CIF_DD_2, + GPIO52_CIF_DD_4, + GPIO53_CIF_MCLK, + GPIO54_CIF_PCLK, + GPIO55_CIF_DD_1, + GPIO84_CIF_FV, + GPIO85_CIF_LV, + GPIO93_CIF_DD_6, + GPIO108_CIF_DD_7, + + GPIO56_GPIO, /* OV9640 Powerdown */ + GPIO57_GPIO, /* OV9640 Reset */ + GPIO91_GPIO, /* OV9640 Power */ + + /* I2C */ + GPIO117_GPIO, /* I2C_SCL */ + GPIO118_GPIO, /* I2C_SDA */ + /* Misc. */ GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* power detect */ GPIO88_GPIO, /* green led */ @@ -254,6 +280,106 @@ device_initcall(palmz72_pm_init); #endif /****************************************************************************** + * SoC Camera + ******************************************************************************/ +#if defined(CONFIG_SOC_CAMERA_OV9640) || \ + defined(CONFIG_SOC_CAMERA_OV9640_MODULE) +static struct pxacamera_platform_data palmz72_pxacamera_platform_data = { + .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | + PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, + .mclk_10khz = 2600, +}; + +/* Board I2C devices. */ +static struct i2c_board_info palmz72_i2c_device[] = { + { + I2C_BOARD_INFO("ov9640", 0x30), + } +}; + +static int palmz72_camera_power(struct device *dev, int power) +{ + gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power); + mdelay(50); + return 0; +} + +static int palmz72_camera_reset(struct device *dev) +{ + gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1); + mdelay(50); + gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0); + mdelay(50); + return 0; +} + +static struct soc_camera_link palmz72_iclink = { + .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */ + .board_info = &palmz72_i2c_device[0], + .i2c_adapter_id = 0, + .module_name = "ov96xx", + .power = &palmz72_camera_power, + .reset = &palmz72_camera_reset, + .flags = SOCAM_DATAWIDTH_8, +}; + +static struct i2c_gpio_platform_data palmz72_i2c_bus_data = { + .sda_pin = 118, + .scl_pin = 117, + .udelay = 10, + .timeout = 100, +}; + +static struct platform_device palmz72_i2c_bus_device = { + .name = "i2c-gpio", + .id = 0, /* we use this as a replacement for i2c-pxa */ + .dev = { + .platform_data = &palmz72_i2c_bus_data, + } +}; + +static struct platform_device palmz72_camera = { + .name = "soc-camera-pdrv", + .id = -1, + .dev = { + .platform_data = &palmz72_iclink, + }, +}; + +/* Here we request the camera GPIOs and configure them. We power up the camera + * module, deassert the reset pin, but put it into powerdown (low to no power + * consumption) mode. This allows us to later bring the module up fast. */ +static struct gpio palmz72_camera_gpios[] = { + { GPIO_NR_PALMZ72_CAM_POWER, GPIOF_INIT_HIGH,"Camera DVDD" }, + { GPIO_NR_PALMZ72_CAM_RESET, GPIOF_INIT_LOW, "Camera RESET" }, + { GPIO_NR_PALMZ72_CAM_PWDN, GPIOF_INIT_LOW, "Camera PWDN" }, +}; + +static inline void __init palmz72_cam_gpio_init(void) +{ + int ret; + + ret = gpio_request_array(ARRAY_AND_SIZE(palmz72_camera_gpios)); + if (!ret) + gpio_free_array(ARRAY_AND_SIZE(palmz72_camera_gpios)); + else + printk(KERN_ERR "Camera GPIO init failed!\n"); + + return; +} + +static void __init palmz72_camera_init(void) +{ + palmz72_cam_gpio_init(); + pxa_set_camera_info(&palmz72_pxacamera_platform_data); + platform_device_register(&palmz72_i2c_bus_device); + platform_device_register(&palmz72_camera); +} +#else +static inline void palmz72_camera_init(void) {} +#endif + +/****************************************************************************** * Machine init ******************************************************************************/ static void __init palmz72_init(void) @@ -276,6 +402,7 @@ static void __init palmz72_init(void) palm27x_pmic_init(); palmz72_kpc_init(); palmz72_leds_init(); + palmz72_camera_init(); } MACHINE_START(PALMZ72, "Palm Zire72") diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 9dbf3ccd415..a70fb848dcd 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -515,7 +515,7 @@ void __init pcm990_baseboard_init(void) pcm990_init_irq(); #ifndef CONFIG_PCM990_DISPLAY_NONE - set_pxa_fb_info(&pcm990_fbinfo); + pxa_set_fb_info(NULL, &pcm990_fbinfo); #endif platform_device_register(&pcm990_backlight_device); diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 35353af345d..16d14fd79b4 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -445,8 +445,7 @@ static void __init poodle_init(void) if (ret) pr_warning("poodle: Unable to register LoCoMo device\n"); - set_pxa_fb_parent(&poodle_locomo_device.dev); - set_pxa_fb_info(&poodle_fb_info); + pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info); pxa_set_udc_info(&udc_info); pxa_set_mci_info(&poodle_mci_platform_data); pxa_set_ficp_info(&poodle_ficp_platform_data); diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 47094188e02..cd1861351f7 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -597,7 +597,7 @@ static void __init raumfeld_lcd_init(void) { int ret; - set_pxa_fb_info(&raumfeld_sharp_lcd_info); + pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info); /* Earlier devices had the backlight regulator controlled * via PWM, later versions use another controller for that */ diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index eb83c89428e..fee97a93512 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -473,7 +473,7 @@ static struct pxafb_mach_info saar_lcd_info = { static void __init saar_init_lcd(void) { - set_pxa_fb_info(&saar_lcd_info); + pxa_set_fb_info(NULL, &saar_lcd_info); } #else static inline void saar_init_lcd(void) {} diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 38e2c0912b9..01c576963e9 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -724,7 +724,7 @@ static struct pxafb_mach_info spitz_pxafb_info = { static void __init spitz_lcd_init(void) { - set_pxa_fb_info(&spitz_pxafb_info); + pxa_set_fb_info(NULL, &spitz_pxafb_info); } #else static inline void spitz_lcd_init(void) {} diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 9cecf8366db..53d4a472b69 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -466,7 +466,7 @@ static void __init tavorevb_init_lcd(void) { platform_device_register(&tavorevb_backlight_devices[0]); platform_device_register(&tavorevb_backlight_devices[1]); - set_pxa_fb_info(&tavorevb_lcd_info); + pxa_set_fb_info(NULL, &tavorevb_lcd_info); } #else static inline void tavorevb_init_lcd(void) {} diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index e7f64d9b4f2..428da3ff33a 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -100,7 +100,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) static struct clock_event_device ckevt_pxa_osmr0 = { .name = "osmr0", .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, .rating = 200, .set_next_event = pxa_osmr0_set_next_event, .set_mode = pxa_osmr0_set_mode, @@ -135,8 +134,8 @@ static void __init pxa_timer_init(void) init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate); - ckevt_pxa_osmr0.mult = - div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); + clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4); + clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4); ckevt_pxa_osmr0.max_delta_ns = clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); ckevt_pxa_osmr0.min_delta_ns = diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 5ad3807af33..5fa145778e7 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -35,6 +35,7 @@ #include <linux/spi/pxa2xx_spi.h> #include <linux/input/matrix_keypad.h> #include <linux/i2c/pxa-i2c.h> +#include <linux/usb/gpio_vbus.h> #include <asm/setup.h> #include <asm/mach-types.h> @@ -240,12 +241,20 @@ static struct scoop_pcmcia_config tosa_pcmcia_config = { /* * USB Device Controller */ -static struct pxa2xx_udc_mach_info udc_info __initdata = { +static struct gpio_vbus_mach_info tosa_udc_info = { .gpio_pullup = TOSA_GPIO_USB_PULLUP, .gpio_vbus = TOSA_GPIO_USB_IN, .gpio_vbus_inverted = 1, }; +static struct platform_device tosa_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &tosa_udc_info, + }, +}; + /* * MMC/SD Device */ @@ -891,6 +900,7 @@ static struct platform_device *devices[] __initdata = { &tosa_bt_device, &sharpsl_rom_device, &wm9712_device, + &tosa_gpio_vbus, }; static void tosa_poweroff(void) @@ -937,7 +947,6 @@ static void __init tosa_init(void) dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16); pxa_set_mci_info(&tosa_mci_platform_data); - pxa_set_udc_info(&udc_info); pxa_set_ficp_info(&tosa_ficp_platform_data); pxa_set_i2c_info(NULL); pxa_set_ac97_info(NULL); diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 857bb2e6348..b9cfbebdfe9 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -516,9 +516,9 @@ static void __init trizeps4_init(void) pxa_set_stuart_info(NULL); if (0) /* dont know how to determine LCD */ - set_pxa_fb_info(&sharp_lcd); + pxa_set_fb_info(NULL, &sharp_lcd); else - set_pxa_fb_info(&toshiba_lcd); + pxa_set_fb_info(NULL, &toshiba_lcd); pxa_set_mci_info(&trizeps4_mci_platform_data); #ifndef STATUS_LEDS_ON_STUART_PINS diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 12279214c87..0fbe78df846 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -932,7 +932,7 @@ static void __init viper_init(void) /* Wake-up serial console */ viper_init_serial_gpio(); - set_pxa_fb_info(&fb_info); + pxa_set_fb_info(NULL, &fb_info); /* v1 hardware cannot use the datacs line */ version = viper_hw_version(); diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index e709fd45926..f71d377c864 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -572,7 +572,7 @@ static void __init vpac270_lcd_init(void) } vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power; - set_pxa_fb_info(&vpac270_lcd_screen); + pxa_set_fb_info(NULL, &vpac270_lcd_screen); return; err2: diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index aaf883754ef..fbe9e02e2f9 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -91,13 +91,13 @@ static unsigned long z2_pin_config[] = { GPIO47_STUART_TXD, /* Keypad */ - GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, - GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, - GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, - GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, - GPIO38_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, - GPIO16_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH, - GPIO17_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH, + GPIO100_KP_MKIN_0, + GPIO101_KP_MKIN_1, + GPIO102_KP_MKIN_2, + GPIO34_KP_MKIN_3, + GPIO38_KP_MKIN_4, + GPIO16_KP_MKIN_5, + GPIO17_KP_MKIN_6, GPIO103_KP_MKOUT_0, GPIO104_KP_MKOUT_1, GPIO105_KP_MKOUT_2, @@ -138,8 +138,7 @@ static unsigned long z2_pin_config[] = { GPIO1_GPIO, /* Power button */ GPIO37_GPIO, /* Headphone detect */ GPIO98_GPIO, /* Lid switch */ - GPIO14_GPIO, /* WiFi Reset */ - GPIO15_GPIO, /* WiFi Power */ + GPIO14_GPIO, /* WiFi Power */ GPIO24_GPIO, /* WiFi CS */ GPIO36_GPIO, /* WiFi IRQ */ GPIO88_GPIO, /* LCD CS */ @@ -204,7 +203,7 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = { /* Keypad Backlight */ .pwm_id = 1, .max_brightness = 1023, - .dft_brightness = 512, + .dft_brightness = 0, .pwm_period_ns = 1260320, }, [1] = { @@ -271,7 +270,7 @@ static struct pxafb_mach_info z2_lcd_screen = { static void __init z2_lcd_init(void) { - set_pxa_fb_info(&z2_lcd_screen); + pxa_set_fb_info(NULL, &z2_lcd_screen); } #else static inline void z2_lcd_init(void) {} @@ -309,12 +308,12 @@ struct gpio_led z2_gpio_leds[] = { .active_low = 1, }, { .name = "z2:green:charged", - .default_trigger = "none", + .default_trigger = "mmc0", .gpio = GPIO85_ZIPITZ2_LED_CHARGED, .active_low = 1, }, { .name = "z2:amber:charging", - .default_trigger = "none", + .default_trigger = "Z2-charging-or-full", .gpio = GPIO83_ZIPITZ2_LED_CHARGING, .active_low = 1, }, @@ -427,8 +426,22 @@ static inline void z2_mkp_init(void) {} ******************************************************************************/ #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) static struct gpio_keys_button z2_pxa_buttons[] = { - {KEY_POWER, GPIO1_ZIPITZ2_POWER_BUTTON, 0, "Power Button" }, - {KEY_CLOSE, GPIO98_ZIPITZ2_LID_BUTTON, 0, "Lid Button" }, + { + .code = KEY_POWER, + .gpio = GPIO1_ZIPITZ2_POWER_BUTTON, + .active_low = 0, + .desc = "Power Button", + .wakeup = 1, + .type = EV_KEY, + }, + { + .code = SW_LID, + .gpio = GPIO98_ZIPITZ2_LID_BUTTON, + .active_low = 1, + .desc = "Lid Switch", + .wakeup = 0, + .type = EV_SW, + }, }; static struct gpio_keys_platform_data z2_pxa_keys_data = { @@ -461,9 +474,9 @@ static struct z2_battery_info batt_chip_info = { .batt_I2C_addr = 0x55, .batt_I2C_reg = 2, .charge_gpio = GPIO0_ZIPITZ2_AC_DETECT, - .min_voltage = 2400000, - .max_voltage = 3700000, - .batt_div = 69, + .min_voltage = 3475000, + .max_voltage = 4190000, + .batt_div = 59, .batt_mult = 1000000, .batt_tech = POWER_SUPPLY_TECHNOLOGY_LION, .batt_name = "Z2", @@ -497,26 +510,16 @@ static int z2_lbs_spi_setup(struct spi_device *spi) { int ret = 0; - ret = gpio_request(GPIO15_ZIPITZ2_WIFI_POWER, "WiFi Power"); + ret = gpio_request(GPIO14_ZIPITZ2_WIFI_POWER, "WiFi Power"); if (ret) goto err; - ret = gpio_direction_output(GPIO15_ZIPITZ2_WIFI_POWER, 1); + ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_POWER, 1); if (ret) goto err2; - ret = gpio_request(GPIO14_ZIPITZ2_WIFI_RESET, "WiFi Reset"); - if (ret) - goto err2; - - ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_RESET, 0); - if (ret) - goto err3; - - /* Reset the card */ + /* Wait until card is powered on */ mdelay(180); - gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 1); - mdelay(20); spi->bits_per_word = 16; spi->mode = SPI_MODE_2, @@ -525,22 +528,18 @@ static int z2_lbs_spi_setup(struct spi_device *spi) return 0; -err3: - gpio_free(GPIO14_ZIPITZ2_WIFI_RESET); err2: - gpio_free(GPIO15_ZIPITZ2_WIFI_POWER); + gpio_free(GPIO14_ZIPITZ2_WIFI_POWER); err: return ret; }; static int z2_lbs_spi_teardown(struct spi_device *spi) { - gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 0); - gpio_set_value(GPIO15_ZIPITZ2_WIFI_POWER, 0); - gpio_free(GPIO14_ZIPITZ2_WIFI_RESET); - gpio_free(GPIO15_ZIPITZ2_WIFI_POWER); - return 0; + gpio_set_value(GPIO14_ZIPITZ2_WIFI_POWER, 0); + gpio_free(GPIO14_ZIPITZ2_WIFI_POWER); + return 0; }; static struct pxa2xx_spi_chip z2_lbs_chip_info = { diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 730f51e57c1..5891590126f 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -846,7 +846,7 @@ static void __init zeus_init(void) if (zeus_setup_fb_gpios()) pr_err("Failed to setup fb gpios\n"); else - set_pxa_fb_info(&zeus_fb_info); + pxa_set_fb_info(NULL, &zeus_fb_info); pxa_set_mci_info(&zeus_mci_platform_data); pxa_set_udc_info(&zeus_udc_info); diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index a4c784aab76..5821185f77a 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -208,7 +208,7 @@ static void __init zylonite_init_lcd(void) platform_device_register(&zylonite_backlight_device); if (lcd_id & 0x20) { - set_pxa_fb_info(&zylonite_sharp_lcd_info); + pxa_set_fb_info(NULL, &zylonite_sharp_lcd_info); return; } @@ -220,7 +220,7 @@ static void __init zylonite_init_lcd(void) else zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode; - set_pxa_fb_info(&zylonite_toshiba_lcd_info); + pxa_set_fb_info(NULL, &zylonite_toshiba_lcd_info); } #else static inline void zylonite_init_lcd(void) {} diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c index a2a73d95384..b86d7e22595 100644 --- a/drivers/ata/pata_palmld.c +++ b/drivers/ata/pata_palmld.c @@ -33,6 +33,11 @@ #define DRV_NAME "pata_palmld" +static struct gpio palmld_hdd_gpios[] = { + { GPIO_NR_PALMLD_IDE_PWEN, GPIOF_INIT_HIGH, "HDD Power" }, + { GPIO_NR_PALMLD_IDE_RESET, GPIOF_INIT_LOW, "HDD Reset" }, +}; + static struct scsi_host_template palmld_sht = { ATA_PIO_SHT(DRV_NAME), }; @@ -52,28 +57,23 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) /* allocate host */ host = ata_host_alloc(&pdev->dev, 1); - if (!host) - return -ENOMEM; + if (!host) { + ret = -ENOMEM; + goto err1; + } /* remap drive's physical memory address */ mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000); - if (!mem) - return -ENOMEM; + if (!mem) { + ret = -ENOMEM; + goto err1; + } /* request and activate power GPIO, IRQ GPIO */ - ret = gpio_request(GPIO_NR_PALMLD_IDE_PWEN, "HDD PWR"); + ret = gpio_request_array(palmld_hdd_gpios, + ARRAY_SIZE(palmld_hdd_gpios)); if (ret) goto err1; - ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_PWEN, 1); - if (ret) - goto err2; - - ret = gpio_request(GPIO_NR_PALMLD_IDE_RESET, "HDD RST"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_RESET, 0); - if (ret) - goto err3; /* reset the drive */ gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0); @@ -96,13 +96,15 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) ata_sff_std_ports(&ap->ioaddr); /* activate host */ - return ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING, + ret = ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING, &palmld_sht); + if (ret) + goto err2; + + return ret; -err3: - gpio_free(GPIO_NR_PALMLD_IDE_RESET); err2: - gpio_free(GPIO_NR_PALMLD_IDE_PWEN); + gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios)); err1: return ret; } @@ -116,8 +118,7 @@ static __devexit int palmld_pata_remove(struct platform_device *dev) /* power down the HDD */ gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0); - gpio_free(GPIO_NR_PALMLD_IDE_RESET); - gpio_free(GPIO_NR_PALMLD_IDE_PWEN); + gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios)); return 0; } diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index a52039564e7..443cb7fc872 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -34,14 +34,24 @@ #define COLIBRI320_DETECT_GPIO 81 #define COLIBRI320_READY_GPIO 29 -static struct { - int reset_gpio; - int ppen_gpio; - int bvd1_gpio; - int bvd2_gpio; - int detect_gpio; - int ready_gpio; -} colibri_pcmcia_gpio; +enum { + DETECT = 0, + READY = 1, + BVD1 = 2, + BVD2 = 3, + PPEN = 4, + RESET = 5, +}; + +/* Contents of this array are configured on-the-fly in init function */ +static struct gpio colibri_pcmcia_gpios[] = { + { 0, GPIOF_IN, "PCMCIA Detect" }, + { 0, GPIOF_IN, "PCMCIA Ready" }, + { 0, GPIOF_IN, "PCMCIA BVD1" }, + { 0, GPIOF_IN, "PCMCIA BVD2" }, + { 0, GPIOF_INIT_LOW, "PCMCIA PPEN" }, + { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" }, +}; static struct pcmcia_irqs colibri_irqs[] = { { @@ -54,88 +64,42 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - ret = gpio_request(colibri_pcmcia_gpio.detect_gpio, "DETECT"); + ret = gpio_request_array(colibri_pcmcia_gpios, + ARRAY_SIZE(colibri_pcmcia_gpios)); if (ret) goto err1; - ret = gpio_direction_input(colibri_pcmcia_gpio.detect_gpio); - if (ret) - goto err2; - - ret = gpio_request(colibri_pcmcia_gpio.ready_gpio, "READY"); - if (ret) - goto err2; - ret = gpio_direction_input(colibri_pcmcia_gpio.ready_gpio); - if (ret) - goto err3; - ret = gpio_request(colibri_pcmcia_gpio.bvd1_gpio, "BVD1"); - if (ret) - goto err3; - ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio); - if (ret) - goto err4; + colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio); + skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio); - ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2"); - if (ret) - goto err4; - ret = gpio_direction_input(colibri_pcmcia_gpio.bvd2_gpio); - if (ret) - goto err5; - - ret = gpio_request(colibri_pcmcia_gpio.ppen_gpio, "PPEN"); - if (ret) - goto err5; - ret = gpio_direction_output(colibri_pcmcia_gpio.ppen_gpio, 0); - if (ret) - goto err6; - - ret = gpio_request(colibri_pcmcia_gpio.reset_gpio, "RESET"); - if (ret) - goto err6; - ret = gpio_direction_output(colibri_pcmcia_gpio.reset_gpio, 1); + ret = soc_pcmcia_request_irqs(skt, colibri_irqs, + ARRAY_SIZE(colibri_irqs)); if (ret) - goto err7; - - colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio); - skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio); + goto err2; - return soc_pcmcia_request_irqs(skt, colibri_irqs, - ARRAY_SIZE(colibri_irqs)); + return ret; -err7: - gpio_free(colibri_pcmcia_gpio.detect_gpio); -err6: - gpio_free(colibri_pcmcia_gpio.ready_gpio); -err5: - gpio_free(colibri_pcmcia_gpio.bvd1_gpio); -err4: - gpio_free(colibri_pcmcia_gpio.bvd2_gpio); -err3: - gpio_free(colibri_pcmcia_gpio.reset_gpio); err2: - gpio_free(colibri_pcmcia_gpio.ppen_gpio); + gpio_free_array(colibri_pcmcia_gpios, + ARRAY_SIZE(colibri_pcmcia_gpios)); err1: return ret; } static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(colibri_pcmcia_gpio.detect_gpio); - gpio_free(colibri_pcmcia_gpio.ready_gpio); - gpio_free(colibri_pcmcia_gpio.bvd1_gpio); - gpio_free(colibri_pcmcia_gpio.bvd2_gpio); - gpio_free(colibri_pcmcia_gpio.reset_gpio); - gpio_free(colibri_pcmcia_gpio.ppen_gpio); + gpio_free_array(colibri_pcmcia_gpios, + ARRAY_SIZE(colibri_pcmcia_gpios)); } static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio); - state->ready = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio); - state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio); - state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio); + state->detect = !!gpio_get_value(colibri_pcmcia_gpios[DETECT].gpio); + state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio); + state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio); + state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio); state->wrprot = 0; state->vs_3v = 1; state->vs_Xv = 0; @@ -145,9 +109,10 @@ static int colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) { - gpio_set_value(colibri_pcmcia_gpio.ppen_gpio, + gpio_set_value(colibri_pcmcia_gpios[PPEN].gpio, !(state->Vcc == 33 && state->Vpp < 50)); - gpio_set_value(colibri_pcmcia_gpio.reset_gpio, state->flags & SS_RESET); + gpio_set_value(colibri_pcmcia_gpios[RESET].gpio, + state->flags & SS_RESET); return 0; } @@ -190,20 +155,20 @@ static int __init colibri_pcmcia_init(void) /* Colibri PXA270 */ if (machine_is_colibri()) { - colibri_pcmcia_gpio.reset_gpio = COLIBRI270_RESET_GPIO; - colibri_pcmcia_gpio.ppen_gpio = COLIBRI270_PPEN_GPIO; - colibri_pcmcia_gpio.bvd1_gpio = COLIBRI270_BVD1_GPIO; - colibri_pcmcia_gpio.bvd2_gpio = COLIBRI270_BVD2_GPIO; - colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO; - colibri_pcmcia_gpio.ready_gpio = COLIBRI270_READY_GPIO; + colibri_pcmcia_gpios[RESET].gpio = COLIBRI270_RESET_GPIO; + colibri_pcmcia_gpios[PPEN].gpio = COLIBRI270_PPEN_GPIO; + colibri_pcmcia_gpios[BVD1].gpio = COLIBRI270_BVD1_GPIO; + colibri_pcmcia_gpios[BVD2].gpio = COLIBRI270_BVD2_GPIO; + colibri_pcmcia_gpios[DETECT].gpio = COLIBRI270_DETECT_GPIO; + colibri_pcmcia_gpios[READY].gpio = COLIBRI270_READY_GPIO; /* Colibri PXA320 */ } else if (machine_is_colibri320()) { - colibri_pcmcia_gpio.reset_gpio = COLIBRI320_RESET_GPIO; - colibri_pcmcia_gpio.ppen_gpio = COLIBRI320_PPEN_GPIO; - colibri_pcmcia_gpio.bvd1_gpio = COLIBRI320_BVD1_GPIO; - colibri_pcmcia_gpio.bvd2_gpio = COLIBRI320_BVD2_GPIO; - colibri_pcmcia_gpio.detect_gpio = COLIBRI320_DETECT_GPIO; - colibri_pcmcia_gpio.ready_gpio = COLIBRI320_READY_GPIO; + colibri_pcmcia_gpios[RESET].gpio = COLIBRI320_RESET_GPIO; + colibri_pcmcia_gpios[PPEN].gpio = COLIBRI320_PPEN_GPIO; + colibri_pcmcia_gpios[BVD1].gpio = COLIBRI320_BVD1_GPIO; + colibri_pcmcia_gpios[BVD2].gpio = COLIBRI320_BVD2_GPIO; + colibri_pcmcia_gpios[DETECT].gpio = COLIBRI320_DETECT_GPIO; + colibri_pcmcia_gpios[READY].gpio = COLIBRI320_READY_GPIO; } ret = platform_device_add_data(colibri_pcmcia_device, diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c index 6fb6f7f0672..69f73670949 100644 --- a/drivers/pcmcia/pxa2xx_palmld.c +++ b/drivers/pcmcia/pxa2xx_palmld.c @@ -4,7 +4,7 @@ * Driver for Palm LifeDrive PCMCIA * * Copyright (C) 2006 Alex Osborne <ato@meshy.org> - * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -20,49 +20,27 @@ #include <mach/palmld.h> #include "soc_common.h" +static struct gpio palmld_pcmcia_gpios[] = { + { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" }, + { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, + { GPIO_NR_PALMLD_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, +}; + static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR"); - if (ret) - goto err1; - ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0); - if (ret) - goto err2; - - ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1); - if (ret) - goto err3; - - ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY"); - if (ret) - goto err3; - ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY); - if (ret) - goto err4; + ret = gpio_request_array(palmld_pcmcia_gpios, + ARRAY_SIZE(palmld_pcmcia_gpios)); skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); - return 0; -err4: - gpio_free(GPIO_NR_PALMLD_PCMCIA_READY); -err3: - gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET); -err2: - gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER); -err1: return ret; } static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(GPIO_NR_PALMLD_PCMCIA_READY); - gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET); - gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER); + gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios)); } 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 459a232d66b..d0ad6a76bbd 100644 --- a/drivers/pcmcia/pxa2xx_palmtc.c +++ b/drivers/pcmcia/pxa2xx_palmtc.c @@ -4,7 +4,7 @@ * Driver for Palm Tungsten|C PCMCIA * * Copyright (C) 2008 Alex Osborne <ato@meshy.org> - * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -21,79 +21,30 @@ #include <mach/palmtc.h> #include "soc_common.h" +static struct gpio palmtc_pcmcia_gpios[] = { + { GPIO_NR_PALMTC_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, + { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, + { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" }, + { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, + { GPIO_NR_PALMTC_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, + { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" }, +}; + static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1"); - if (ret) - goto err1; - ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER1, 0); - if (ret) - goto err2; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER2, "PCMCIA PWR2"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER2, 0); - if (ret) - goto err3; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER3, "PCMCIA PWR3"); - if (ret) - goto err3; - ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER3, 0); - if (ret) - goto err4; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_RESET, "PCMCIA RST"); - if (ret) - goto err4; - ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_RESET, 1); - if (ret) - goto err5; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_READY, "PCMCIA RDY"); - if (ret) - goto err5; - ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_READY); - if (ret) - goto err6; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_PWRREADY, "PCMCIA PWRRDY"); - if (ret) - goto err6; - ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_PWRREADY); - if (ret) - goto err7; + ret = gpio_request_array(palmtc_pcmcia_gpios, + ARRAY_SIZE(palmtc_pcmcia_gpios)); skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY); - return 0; -err7: - gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY); -err6: - gpio_free(GPIO_NR_PALMTC_PCMCIA_READY); -err5: - gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET); -err4: - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3); -err3: - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2); -err2: - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1); -err1: return ret; } static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY); - gpio_free(GPIO_NR_PALMTC_PCMCIA_READY); - gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET); - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3); - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2); - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1); + gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios)); } 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 b07b247a399..1a258045040 100644 --- a/drivers/pcmcia/pxa2xx_palmtx.c +++ b/drivers/pcmcia/pxa2xx_palmtx.c @@ -3,7 +3,7 @@ * * Driver for Palm T|X PCMCIA * - * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -13,67 +13,34 @@ #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/gpio.h> #include <asm/mach-types.h> - -#include <mach/gpio.h> #include <mach/palmtx.h> - #include "soc_common.h" +static struct gpio palmtx_pcmcia_gpios[] = { + { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, + { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, + { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, + { GPIO_NR_PALMTX_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, +}; + static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1"); - if (ret) - goto err1; - ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER1, 0); - if (ret) - goto err2; - - ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER2, "PCMCIA PWR2"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER2, 0); - if (ret) - goto err3; - - ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_RESET, "PCMCIA RST"); - if (ret) - goto err3; - ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_RESET, 1); - if (ret) - goto err4; - - ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_READY, "PCMCIA RDY"); - if (ret) - goto err4; - ret = gpio_direction_input(GPIO_NR_PALMTX_PCMCIA_READY); - if (ret) - goto err5; + ret = gpio_request_array(palmtx_pcmcia_gpios, + ARRAY_SIZE(palmtx_pcmcia_gpios)); skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); - return 0; -err5: - gpio_free(GPIO_NR_PALMTX_PCMCIA_READY); -err4: - gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET); -err3: - gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2); -err2: - gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1); -err1: return ret; } static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(GPIO_NR_PALMTX_PCMCIA_READY); - gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET); - gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2); - gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1); + gpio_free_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios)); } 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 55627eccee8..435002dfc3c 100644 --- a/drivers/pcmcia/pxa2xx_vpac270.c +++ b/drivers/pcmcia/pxa2xx_vpac270.c @@ -3,8 +3,7 @@ * * Driver for Voipac PXA270 PCMCIA and CF sockets * - * Copyright (C) 2010 - * Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,6 +21,19 @@ #include "soc_common.h" +static struct gpio vpac270_pcmcia_gpios[] = { + { GPIO84_VPAC270_PCMCIA_CD, GPIOF_IN, "PCMCIA Card Detect" }, + { GPIO35_VPAC270_PCMCIA_RDY, GPIOF_IN, "PCMCIA Ready" }, + { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, + { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, +}; + +static struct gpio vpac270_cf_gpios[] = { + { GPIO17_VPAC270_CF_CD, GPIOF_IN, "CF Card Detect" }, + { GPIO12_VPAC270_CF_RDY, GPIOF_IN, "CF Ready" }, + { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, +}; + static struct pcmcia_irqs cd_irqs[] = { { .sock = 0, @@ -40,96 +52,34 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) int ret; if (skt->nr == 0) { - ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD"); - if (ret) - goto err1; - ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD); - if (ret) - goto err2; - - ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY"); - if (ret) - goto err2; - ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY); - if (ret) - goto err3; - - ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN"); - if (ret) - goto err3; - ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0); - if (ret) - goto err4; - - ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET"); - if (ret) - goto err4; - ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0); - if (ret) - goto err5; + ret = gpio_request_array(vpac270_pcmcia_gpios, + ARRAY_SIZE(vpac270_pcmcia_gpios)); skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); - return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); - -err5: - gpio_free(GPIO11_VPAC270_PCMCIA_RESET); -err4: - gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); -err3: - gpio_free(GPIO35_VPAC270_PCMCIA_RDY); -err2: - gpio_free(GPIO84_VPAC270_PCMCIA_CD); -err1: - return ret; - + if (!ret) + ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); } else { - ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD"); - if (ret) - goto err6; - ret = gpio_direction_input(GPIO17_VPAC270_CF_CD); - if (ret) - goto err7; - - ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY"); - if (ret) - goto err7; - ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY); - if (ret) - goto err8; - - ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET"); - if (ret) - goto err8; - ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0); - if (ret) - goto err9; + ret = gpio_request_array(vpac270_cf_gpios, + ARRAY_SIZE(vpac270_cf_gpios)); skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); - return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); - -err9: - gpio_free(GPIO16_VPAC270_CF_RESET); -err8: - gpio_free(GPIO12_VPAC270_CF_RDY); -err7: - gpio_free(GPIO17_VPAC270_CF_CD); -err6: - return ret; - + if (!ret) + ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); } + + return ret; } static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(GPIO11_VPAC270_PCMCIA_RESET); - gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); - gpio_free(GPIO35_VPAC270_PCMCIA_RDY); - gpio_free(GPIO84_VPAC270_PCMCIA_CD); - gpio_free(GPIO16_VPAC270_CF_RESET); - gpio_free(GPIO12_VPAC270_CF_RDY); - gpio_free(GPIO17_VPAC270_CF_CD); + if (skt->nr == 0) + gpio_request_array(vpac270_pcmcia_gpios, + ARRAY_SIZE(vpac270_pcmcia_gpios)); + else + gpio_request_array(vpac270_cf_gpios, + ARRAY_SIZE(vpac270_cf_gpios)); } 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 b37f92cb71b..444b60aa15e 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -139,24 +139,6 @@ static const char ep0name [] = "ep0"; static void pxa25x_ep_fifo_flush (struct usb_ep *ep); static void nuke (struct pxa25x_ep *, int status); -/* one GPIO should be used to detect VBUS from the host */ -static int is_vbus_present(void) -{ - struct pxa2xx_udc_mach_info *mach = the_controller->mach; - - if (gpio_is_valid(mach->gpio_vbus)) { - int value = gpio_get_value(mach->gpio_vbus); - - if (mach->gpio_vbus_inverted) - return !value; - else - return !!value; - } - if (mach->udc_is_connected) - return mach->udc_is_connected(); - return 1; -} - /* one GPIO should control a D+ pullup, so host sees this device (or not) */ static void pullup_off(void) { @@ -1055,7 +1037,7 @@ udc_seq_show(struct seq_file *m, void *_d) "%s version: %s\nGadget driver: %s\nHost %s\n\n", driver_name, DRIVER_VERSION SIZE_STR "(pio)", dev->driver ? dev->driver->driver.name : "(none)", - is_vbus_present() ? "full speed" : "disconnected"); + dev->gadget.speed == USB_SPEED_FULL ? "full speed" : "disconnected"); /* registers for device and ep0 */ seq_printf(m, @@ -1094,7 +1076,7 @@ udc_seq_show(struct seq_file *m, void *_d) (tmp & UDCCFR_ACM) ? " acm" : ""); } - if (!is_vbus_present() || !dev->driver) + if (dev->gadget.speed != USB_SPEED_FULL || !dev->driver) goto done; 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) #endif -static irqreturn_t udc_vbus_irq(int irq, void *_dev) -{ - struct pxa25x_udc *dev = _dev; - - pxa25x_udc_vbus_session(&dev->gadget, is_vbus_present()); - return IRQ_HANDLED; -} - /*-------------------------------------------------------------------------*/ @@ -1766,12 +1740,9 @@ pxa25x_udc_irq(int irq, void *_dev) if (unlikely(udccr & UDCCR_SUSIR)) { udc_ack_int_UDCCR(UDCCR_SUSIR); handled = 1; - DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present() - ? "" : "+disconnect"); + DBG(DBG_VERBOSE, "USB suspend\n"); - if (!is_vbus_present()) - stop_activity(dev, dev->driver); - else if (dev->gadget.speed != USB_SPEED_UNKNOWN + if (dev->gadget.speed != USB_SPEED_UNKNOWN && dev->driver && dev->driver->suspend) dev->driver->suspend(&dev->gadget); @@ -1786,8 +1757,7 @@ pxa25x_udc_irq(int irq, void *_dev) if (dev->gadget.speed != USB_SPEED_UNKNOWN && dev->driver - && dev->driver->resume - && is_vbus_present()) + && dev->driver->resume) dev->driver->resume(&dev->gadget); } @@ -2137,7 +2107,7 @@ static struct pxa25x_udc memory = { static int __init pxa25x_udc_probe(struct platform_device *pdev) { struct pxa25x_udc *dev = &memory; - int retval, vbus_irq, irq; + int retval, irq; u32 chiprev; /* insist on Intel/ARM/XScale */ @@ -2199,19 +2169,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->transceiver = otg_get_transceiver(); - if (gpio_is_valid(dev->mach->gpio_vbus)) { - if ((retval = gpio_request(dev->mach->gpio_vbus, - "pxa25x_udc GPIO VBUS"))) { - dev_dbg(&pdev->dev, - "can't get vbus gpio %d, err: %d\n", - dev->mach->gpio_vbus, retval); - goto err_gpio_vbus; - } - gpio_direction_input(dev->mach->gpio_vbus); - vbus_irq = gpio_to_irq(dev->mach->gpio_vbus); - } else - vbus_irq = 0; - if (gpio_is_valid(dev->mach->gpio_pullup)) { if ((retval = gpio_request(dev->mach->gpio_pullup, "pca25x_udc GPIO PULLUP"))) { @@ -2237,7 +2194,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) udc_disable(dev); udc_reinit(dev); - dev->vbus = !!is_vbus_present(); + dev->vbus = 0; /* irq setup after old hardware state is cleaned up */ retval = request_irq(irq, pxa25x_udc_irq, @@ -2273,22 +2230,10 @@ lubbock_fail0: } } else #endif - if (vbus_irq) { - retval = request_irq(vbus_irq, udc_vbus_irq, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM | - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - driver_name, dev); - if (retval != 0) { - pr_err("%s: can't get irq %i, err %d\n", - driver_name, vbus_irq, retval); - goto err_vbus_irq; - } - } create_debug_files(dev); return 0; - err_vbus_irq: #ifdef CONFIG_ARCH_LUBBOCK free_irq(LUBBOCK_USB_DISC_IRQ, dev); err_irq_lub: @@ -2298,9 +2243,6 @@ lubbock_fail0: if (gpio_is_valid(dev->mach->gpio_pullup)) gpio_free(dev->mach->gpio_pullup); err_gpio_pullup: - if (gpio_is_valid(dev->mach->gpio_vbus)) - gpio_free(dev->mach->gpio_vbus); - err_gpio_vbus: if (dev->transceiver) { otg_put_transceiver(dev->transceiver); dev->transceiver = NULL; @@ -2337,10 +2279,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) free_irq(LUBBOCK_USB_IRQ, dev); } #endif - if (gpio_is_valid(dev->mach->gpio_vbus)) { - free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); - gpio_free(dev->mach->gpio_vbus); - } if (gpio_is_valid(dev->mach->gpio_pullup)) gpio_free(dev->mach->gpio_pullup); diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 825b665245b..a2e5b5100ab 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -627,7 +627,12 @@ static void overlay1fb_enable(struct pxafb_layer *ofb) static void overlay1fb_disable(struct pxafb_layer *ofb) { - uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5); + uint32_t lccr5; + + if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN)) + return; + + lccr5 = lcd_readl(ofb->fbi, LCCR5); lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN); @@ -685,7 +690,12 @@ static void overlay2fb_enable(struct pxafb_layer *ofb) static void overlay2fb_disable(struct pxafb_layer *ofb) { - uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5); + uint32_t lccr5; + + if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN)) + return; + + lccr5 = lcd_readl(ofb->fbi, LCCR5); lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN); @@ -720,12 +730,10 @@ static int overlayfb_open(struct fb_info *info, int user) if (user == 0) return -ENODEV; - /* allow only one user at a time */ - if (atomic_inc_and_test(&ofb->usage)) - return -EBUSY; + if (ofb->usage++ == 0) + /* unblank the base framebuffer */ + fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK); - /* unblank the base framebuffer */ - fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK); return 0; } @@ -733,12 +741,15 @@ static int overlayfb_release(struct fb_info *info, int user) { struct pxafb_layer *ofb = (struct pxafb_layer*) info; - atomic_dec(&ofb->usage); - ofb->ops->disable(ofb); + if (ofb->usage == 1) { + ofb->ops->disable(ofb); + ofb->fb.var.height = -1; + ofb->fb.var.width = -1; + ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0; + ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0; - free_pages_exact(ofb->video_mem, ofb->video_mem_size); - ofb->video_mem = NULL; - ofb->video_mem_size = 0; + ofb->usage--; + } return 0; } @@ -750,7 +761,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var, int xpos, ypos, pfor, bpp; xpos = NONSTD_TO_XPOS(var->nonstd); - ypos = NONSTD_TO_XPOS(var->nonstd); + ypos = NONSTD_TO_YPOS(var->nonstd); pfor = NONSTD_TO_PFOR(var->nonstd); bpp = pxafb_var_to_bpp(var); @@ -794,7 +805,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var, return 0; } -static int overlayfb_map_video_memory(struct pxafb_layer *ofb) +static int overlayfb_check_video_memory(struct pxafb_layer *ofb) { struct fb_var_screeninfo *var = &ofb->fb.var; int pfor = NONSTD_TO_PFOR(var->nonstd); @@ -812,27 +823,11 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb) size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual); - /* don't re-allocate if the original video memory is enough */ if (ofb->video_mem) { if (ofb->video_mem_size >= size) return 0; - - free_pages_exact(ofb->video_mem, ofb->video_mem_size); } - - ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); - if (ofb->video_mem == NULL) - return -ENOMEM; - - ofb->video_mem_phys = virt_to_phys(ofb->video_mem); - ofb->video_mem_size = size; - - mutex_lock(&ofb->fb.mm_lock); - ofb->fb.fix.smem_start = ofb->video_mem_phys; - ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual; - mutex_unlock(&ofb->fb.mm_lock); - ofb->fb.screen_base = ofb->video_mem; - return 0; + return -EINVAL; } static int overlayfb_set_par(struct fb_info *info) @@ -841,13 +836,13 @@ static int overlayfb_set_par(struct fb_info *info) struct fb_var_screeninfo *var = &info->var; int xpos, ypos, pfor, bpp, ret; - ret = overlayfb_map_video_memory(ofb); + ret = overlayfb_check_video_memory(ofb); if (ret) return ret; bpp = pxafb_var_to_bpp(var); xpos = NONSTD_TO_XPOS(var->nonstd); - ypos = NONSTD_TO_XPOS(var->nonstd); + ypos = NONSTD_TO_YPOS(var->nonstd); pfor = NONSTD_TO_PFOR(var->nonstd); 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, ofb->id = id; ofb->ops = &ofb_ops[id]; - atomic_set(&ofb->usage, 0); + ofb->usage = 0; ofb->fbi = fbi; init_completion(&ofb->branch_done); } @@ -904,29 +899,60 @@ static inline int pxafb_overlay_supported(void) return 0; } -static int __devinit pxafb_overlay_init(struct pxafb_info *fbi) +static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb, + struct pxafb_layer *ofb) +{ + /* We assume that user will use at most video_mem_size for overlay fb, + * anyway, it's useless to use 16bpp main plane and 24bpp overlay + */ + ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size), + GFP_KERNEL | __GFP_ZERO); + if (ofb->video_mem == NULL) + return -ENOMEM; + + ofb->video_mem_phys = virt_to_phys(ofb->video_mem); + ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size); + + mutex_lock(&ofb->fb.mm_lock); + ofb->fb.fix.smem_start = ofb->video_mem_phys; + ofb->fb.fix.smem_len = pxafb->video_mem_size; + mutex_unlock(&ofb->fb.mm_lock); + + ofb->fb.screen_base = ofb->video_mem; + + return 0; +} + +static void __devinit pxafb_overlay_init(struct pxafb_info *fbi) { int i, ret; if (!pxafb_overlay_supported()) - return 0; + return; for (i = 0; i < 2; i++) { - init_pxafb_overlay(fbi, &fbi->overlay[i], i); - ret = register_framebuffer(&fbi->overlay[i].fb); + struct pxafb_layer *ofb = &fbi->overlay[i]; + init_pxafb_overlay(fbi, ofb, i); + ret = register_framebuffer(&ofb->fb); if (ret) { dev_err(fbi->dev, "failed to register overlay %d\n", i); - return ret; + continue; } + ret = pxafb_overlay_map_video_memory(fbi, ofb); + if (ret) { + dev_err(fbi->dev, + "failed to map video memory for overlay %d\n", + i); + unregister_framebuffer(&ofb->fb); + continue; + } + ofb->registered = 1; } /* mask all IU/BS/EOF/SOF interrupts */ lcd_writel(fbi, LCCR5, ~0); - /* place overlay(s) on top of base */ - fbi->lccr0 |= LCCR0_OUC; pr_info("PXA Overlay driver loaded successfully!\n"); - return 0; } static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) @@ -936,8 +962,15 @@ static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) if (!pxafb_overlay_supported()) return; - for (i = 0; i < 2; i++) - unregister_framebuffer(&fbi->overlay[i].fb); + for (i = 0; i < 2; i++) { + struct pxafb_layer *ofb = &fbi->overlay[i]; + if (ofb->registered) { + if (ofb->video_mem) + free_pages_exact(ofb->video_mem, + ofb->video_mem_size); + unregister_framebuffer(&ofb->fb); + } + } } #else static inline void pxafb_overlay_init(struct pxafb_info *fbi) {} @@ -1368,7 +1401,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) || (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) || (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) || - (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])) + ((fbi->lccr0 & LCCR0_SDS) && + (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))) pxafb_schedule_work(fbi, C_REENABLE); return 0; @@ -1420,7 +1454,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi) lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); lcd_writel(fbi, FDADR0, fbi->fdadr[0]); - lcd_writel(fbi, FDADR1, fbi->fdadr[1]); + if (fbi->lccr0 & LCCR0_SDS) + lcd_writel(fbi, FDADR1, fbi->fdadr[1]); lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); } @@ -1613,7 +1648,8 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) switch (val) { case CPUFREQ_PRECHANGE: - set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); + if (!fbi->overlay[0].usage && !fbi->overlay[1].usage) + set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); break; case CPUFREQ_POSTCHANGE: @@ -1806,6 +1842,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev) pxafb_decode_mach_info(fbi, inf); +#ifdef CONFIG_FB_PXA_OVERLAY + /* place overlay(s) on top of base */ + if (pxafb_overlay_supported()) + fbi->lccr0 |= LCCR0_OUC; +#endif + init_waitqueue_head(&fbi->ctrlr_wait); INIT_WORK(&fbi->task, pxafb_task); mutex_init(&fbi->ctrlr_lock); diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h index 2353521c5c8..26ba9fa3f73 100644 --- a/drivers/video/pxafb.h +++ b/drivers/video/pxafb.h @@ -92,7 +92,8 @@ struct pxafb_layer_ops { struct pxafb_layer { struct fb_info fb; int id; - atomic_t usage; + int registered; + uint32_t usage; uint32_t control[2]; struct pxafb_layer_ops *ops; |