Commit 938c0ace authored by Russell King's avatar Russell King

Merge branch 'devel' of...

Merge branch 'devel' of git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6 into devel-stable

Conflicts:
	arch/arm/mach-pxa/tosa.c
parents 16c29daf 5898eb79
...@@ -20,8 +20,6 @@ struct pxa2xx_udc_mach_info { ...@@ -20,8 +20,6 @@ struct pxa2xx_udc_mach_info {
* VBUS IRQ and omit the methods above. Store the GPIO number * VBUS IRQ and omit the methods above. Store the GPIO number
* here. Note that sometimes the signals go through inverters... * here. Note that sometimes the signals go through inverters...
*/ */
bool gpio_vbus_inverted;
int gpio_vbus; /* high == vbus present */
bool gpio_pullup_inverted; bool gpio_pullup_inverted;
int gpio_pullup; /* high == pullup activated */ int gpio_pullup; /* high == pullup activated */
}; };
......
...@@ -128,8 +128,8 @@ static int am200_init_gpio_regs(struct metronomefb_par *par) ...@@ -128,8 +128,8 @@ static int am200_init_gpio_regs(struct metronomefb_par *par)
return 0; return 0;
err_req_gpio: err_req_gpio:
while (i > 0) while (--i >= 0)
gpio_free(gpios[i--]); gpio_free(gpios[i]);
return err; return err;
} }
...@@ -194,7 +194,7 @@ static struct notifier_block am200_fb_notif = { ...@@ -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 /* 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) static void __init am200_presetup_fb(void)
{ {
int fw; int fw;
...@@ -249,7 +249,7 @@ static void __init am200_presetup_fb(void) ...@@ -249,7 +249,7 @@ static void __init am200_presetup_fb(void)
/* we divide since we told the LCD controller we're 16bpp */ /* we divide since we told the LCD controller we're 16bpp */
am200_fb_info.modes->xres /= 2; am200_fb_info.modes->xres /= 2;
set_pxa_fb_info(&am200_fb_info); pxa_set_fb_info(NULL, &am200_fb_info);
} }
......
...@@ -125,10 +125,7 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par) ...@@ -125,10 +125,7 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par)
if (err) { if (err) {
dev_err(&am300_device->dev, "failed requesting " dev_err(&am300_device->dev, "failed requesting "
"gpio %d, err=%d\n", i, err); "gpio %d, err=%d\n", i, err);
while (i >= DB0_GPIO_PIN) goto err_req_gpio2;
gpio_free(i--);
i = ARRAY_SIZE(gpios) - 1;
goto err_req_gpio;
} }
} }
...@@ -159,9 +156,13 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par) ...@@ -159,9 +156,13 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par)
return 0; return 0;
err_req_gpio2:
while (--i >= DB0_GPIO_PIN)
gpio_free(i);
i = ARRAY_SIZE(gpios);
err_req_gpio: err_req_gpio:
while (i > 0) while (--i >= 0)
gpio_free(gpios[i--]); gpio_free(gpios[i]);
return err; return err;
} }
......
...@@ -263,7 +263,7 @@ static void __init balloon3_lcd_init(void) ...@@ -263,7 +263,7 @@ static void __init balloon3_lcd_init(void)
} }
balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power; 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; return;
err2: err2:
......
...@@ -379,7 +379,7 @@ __setup("monitor=", cmx2xx_set_display); ...@@ -379,7 +379,7 @@ __setup("monitor=", cmx2xx_set_display);
static void __init cmx2xx_init_display(void) static void __init cmx2xx_init_display(void)
{ {
set_pxa_fb_info(cmx2xx_display); pxa_set_fb_info(NULL, cmx2xx_display);
} }
#else #else
static inline void cmx2xx_init_display(void) {} static inline void cmx2xx_init_display(void) {}
......
...@@ -296,7 +296,7 @@ static struct pxafb_mach_info cm_x300_lcd = { ...@@ -296,7 +296,7 @@ static struct pxafb_mach_info cm_x300_lcd = {
static void __init cm_x300_init_lcd(void) static void __init cm_x300_init_lcd(void)
{ {
set_pxa_fb_info(&cm_x300_lcd); pxa_set_fb_info(NULL, &cm_x300_lcd);
} }
#else #else
static inline void cm_x300_init_lcd(void) {} static inline void cm_x300_init_lcd(void) {}
......
...@@ -175,7 +175,7 @@ static struct pxafb_mach_info income_lcd_screen = { ...@@ -175,7 +175,7 @@ static struct pxafb_mach_info income_lcd_screen = {
static void __init income_lcd_init(void) static void __init income_lcd_init(void)
{ {
set_pxa_fb_info(&income_lcd_screen); pxa_set_fb_info(NULL, &income_lcd_screen);
} }
#else #else
static inline void income_lcd_init(void) {} static inline void income_lcd_init(void) {}
......
...@@ -105,7 +105,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin) ...@@ -105,7 +105,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin)
lcd_bl_pin = bl_pin; lcd_bl_pin = bl_pin;
gpio_request(bl_pin, "lcd backlight"); gpio_request(bl_pin, "lcd backlight");
gpio_direction_output(bl_pin, 0); gpio_direction_output(bl_pin, 0);
set_pxa_fb_info(&sharp_lq43_info); pxa_set_fb_info(NULL, &sharp_lq43_info);
} }
#endif #endif
......
...@@ -462,7 +462,6 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = { ...@@ -462,7 +462,6 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = {
* USB Device Controller * USB Device Controller
*/ */
static struct pxa2xx_udc_mach_info udc_info __initdata = { static struct pxa2xx_udc_mach_info udc_info __initdata = {
.gpio_vbus = -1,
/* no connect GPIO; corgi can't tell connection status */ /* no connect GPIO; corgi can't tell connection status */
.gpio_pullup = CORGI_GPIO_USB_PULLUP, .gpio_pullup = CORGI_GPIO_USB_PULLUP,
}; };
......
...@@ -90,7 +90,6 @@ void __init pxa_set_mci_info(struct pxamci_platform_data *info) ...@@ -90,7 +90,6 @@ void __init pxa_set_mci_info(struct pxamci_platform_data *info)
static struct pxa2xx_udc_mach_info pxa_udc_info = { static struct pxa2xx_udc_mach_info pxa_udc_info = {
.gpio_pullup = -1, .gpio_pullup = -1,
.gpio_vbus = -1,
}; };
void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info) void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
...@@ -188,16 +187,12 @@ struct platform_device pxa_device_fb = { ...@@ -188,16 +187,12 @@ struct platform_device pxa_device_fb = {
.resource = pxafb_resources, .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); 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[] = { static struct resource pxa_resource_ffuart[] = {
{ {
.start = 0x40100000, .start = 0x40100000,
......
...@@ -689,7 +689,7 @@ static struct pxafb_mach_info em_x270_lcd = { ...@@ -689,7 +689,7 @@ static struct pxafb_mach_info em_x270_lcd = {
static void __init em_x270_init_lcd(void) static void __init em_x270_init_lcd(void)
{ {
set_pxa_fb_info(&em_x270_lcd); pxa_set_fb_info(NULL, &em_x270_lcd);
} }
#else #else
static inline void em_x270_init_lcd(void) {} static inline void em_x270_init_lcd(void) {}
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/mfd/t7l66xb.h> #include <linux/mfd/t7l66xb.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/usb/gpio_vbus.h>
#include <video/w100fb.h> #include <video/w100fb.h>
...@@ -51,12 +52,20 @@ void __init eseries_fixup(struct machine_desc *desc, ...@@ -51,12 +52,20 @@ void __init eseries_fixup(struct machine_desc *desc,
mi->bank[0].size = (64*1024*1024); 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_vbus = GPIO_E7XX_USB_DISC,
.gpio_pullup = GPIO_E7XX_USB_PULLUP, .gpio_pullup = GPIO_E7XX_USB_PULLUP,
.gpio_pullup_inverted = 1 .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 = { struct pxaficp_platform_data e7xx_ficp_platform_data = {
.gpio_pwdown = GPIO_E7XX_IR_OFF, .gpio_pwdown = GPIO_E7XX_IR_OFF,
.transceiver_cap = IR_SIRMODE | IR_OFF, .transceiver_cap = IR_SIRMODE | IR_OFF,
...@@ -165,6 +174,7 @@ static struct platform_device e330_tc6387xb_device = { ...@@ -165,6 +174,7 @@ static struct platform_device e330_tc6387xb_device = {
static struct platform_device *e330_devices[] __initdata = { static struct platform_device *e330_devices[] __initdata = {
&e330_tc6387xb_device, &e330_tc6387xb_device,
&e7xx_gpio_vbus,
}; };
static void __init e330_init(void) static void __init e330_init(void)
...@@ -175,7 +185,6 @@ static void __init e330_init(void) ...@@ -175,7 +185,6 @@ static void __init e330_init(void)
eseries_register_clks(); eseries_register_clks();
eseries_get_tmio_gpios(); eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e330_devices)); platform_add_devices(ARRAY_AND_SIZE(e330_devices));
pxa_set_udc_info(&e7xx_udc_mach_info);
} }
MACHINE_START(E330, "Toshiba e330") MACHINE_START(E330, "Toshiba e330")
...@@ -214,6 +223,7 @@ static struct platform_device e350_t7l66xb_device = { ...@@ -214,6 +223,7 @@ static struct platform_device e350_t7l66xb_device = {
static struct platform_device *e350_devices[] __initdata = { static struct platform_device *e350_devices[] __initdata = {
&e350_t7l66xb_device, &e350_t7l66xb_device,
&e7xx_gpio_vbus,
}; };
static void __init e350_init(void) static void __init e350_init(void)
...@@ -224,7 +234,6 @@ static void __init e350_init(void) ...@@ -224,7 +234,6 @@ static void __init e350_init(void)
eseries_register_clks(); eseries_register_clks();
eseries_get_tmio_gpios(); eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e350_devices)); platform_add_devices(ARRAY_AND_SIZE(e350_devices));
pxa_set_udc_info(&e7xx_udc_mach_info);
} }
MACHINE_START(E350, "Toshiba e350") MACHINE_START(E350, "Toshiba e350")
...@@ -333,6 +342,7 @@ static struct platform_device e400_t7l66xb_device = { ...@@ -333,6 +342,7 @@ static struct platform_device e400_t7l66xb_device = {
static struct platform_device *e400_devices[] __initdata = { static struct platform_device *e400_devices[] __initdata = {
&e400_t7l66xb_device, &e400_t7l66xb_device,
&e7xx_gpio_vbus,
}; };
static void __init e400_init(void) static void __init e400_init(void)
...@@ -344,9 +354,8 @@ static void __init e400_init(void) ...@@ -344,9 +354,8 @@ static void __init e400_init(void)
/* Fixme - e400 may have a switched clock */ /* Fixme - e400 may have a switched clock */
eseries_register_clks(); eseries_register_clks();
eseries_get_tmio_gpios(); 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)); platform_add_devices(ARRAY_AND_SIZE(e400_devices));
pxa_set_udc_info(&e7xx_udc_mach_info);
} }
MACHINE_START(E400, "Toshiba e400") MACHINE_START(E400, "Toshiba e400")
...@@ -519,6 +528,7 @@ static struct platform_device e740_t7l66xb_device = { ...@@ -519,6 +528,7 @@ static struct platform_device e740_t7l66xb_device = {
static struct platform_device *e740_devices[] __initdata = { static struct platform_device *e740_devices[] __initdata = {
&e740_fb_device, &e740_fb_device,
&e740_t7l66xb_device, &e740_t7l66xb_device,
&e7xx_gpio_vbus,
}; };
static void __init e740_init(void) static void __init e740_init(void)
...@@ -532,7 +542,6 @@ static void __init e740_init(void) ...@@ -532,7 +542,6 @@ static void __init e740_init(void)
"UDCCLK", &pxa25x_device_udc.dev), "UDCCLK", &pxa25x_device_udc.dev),
eseries_get_tmio_gpios(); eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e740_devices)); platform_add_devices(ARRAY_AND_SIZE(e740_devices));
pxa_set_udc_info(&e7xx_udc_mach_info);
pxa_set_ac97_info(NULL); pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&e7xx_ficp_platform_data); pxa_set_ficp_info(&e7xx_ficp_platform_data);
} }
...@@ -711,6 +720,7 @@ static struct platform_device e750_tc6393xb_device = { ...@@ -711,6 +720,7 @@ static struct platform_device e750_tc6393xb_device = {
static struct platform_device *e750_devices[] __initdata = { static struct platform_device *e750_devices[] __initdata = {
&e750_fb_device, &e750_fb_device,
&e750_tc6393xb_device, &e750_tc6393xb_device,
&e7xx_gpio_vbus,
}; };
static void __init e750_init(void) static void __init e750_init(void)
...@@ -723,7 +733,6 @@ static void __init e750_init(void) ...@@ -723,7 +733,6 @@ static void __init e750_init(void)
"GPIO11_CLK", NULL), "GPIO11_CLK", NULL),
eseries_get_tmio_gpios(); eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e750_devices)); platform_add_devices(ARRAY_AND_SIZE(e750_devices));
pxa_set_udc_info(&e7xx_udc_mach_info);
pxa_set_ac97_info(NULL); pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&e7xx_ficp_platform_data); pxa_set_ficp_info(&e7xx_ficp_platform_data);
} }
...@@ -873,12 +882,21 @@ static struct platform_device e800_fb_device = { ...@@ -873,12 +882,21 @@ static struct platform_device e800_fb_device = {
/* --------------------------- UDC definitions --------------------------- */ /* --------------------------- 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_vbus = GPIO_E800_USB_DISC,
.gpio_pullup = GPIO_E800_USB_PULLUP, .gpio_pullup = GPIO_E800_USB_PULLUP,
.gpio_pullup_inverted = 1 .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 ------------------ */ /* ----------------- e800 tc6393xb parameters ------------------ */
static struct tc6393xb_platform_data e800_tc6393xb_info = { static struct tc6393xb_platform_data e800_tc6393xb_info = {
...@@ -907,6 +925,7 @@ static struct platform_device e800_tc6393xb_device = { ...@@ -907,6 +925,7 @@ static struct platform_device e800_tc6393xb_device = {
static struct platform_device *e800_devices[] __initdata = { static struct platform_device *e800_devices[] __initdata = {
&e800_fb_device, &e800_fb_device,
&e800_tc6393xb_device, &e800_tc6393xb_device,
&e800_gpio_vbus,
}; };
static void __init e800_init(void) static void __init e800_init(void)
...@@ -919,7 +938,6 @@ static void __init e800_init(void) ...@@ -919,7 +938,6 @@ static void __init e800_init(void)
"GPIO11_CLK", NULL), "GPIO11_CLK", NULL),
eseries_get_tmio_gpios(); eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e800_devices)); platform_add_devices(ARRAY_AND_SIZE(e800_devices));
pxa_set_udc_info(&e800_udc_mach_info);
pxa_set_ac97_info(NULL); pxa_set_ac97_info(NULL);
} }
......
...@@ -783,7 +783,7 @@ static void __init a780_init(void) ...@@ -783,7 +783,7 @@ static void __init a780_init(void)
pxa_set_i2c_info(NULL); 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); pxa_set_keypad_info(&a780_keypad_platform_data);
...@@ -853,7 +853,7 @@ static void __init e680_init(void) ...@@ -853,7 +853,7 @@ static void __init e680_init(void)
pxa_set_i2c_info(NULL); pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info)); 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); pxa_set_keypad_info(&e680_keypad_platform_data);
...@@ -918,7 +918,7 @@ static void __init a1200_init(void) ...@@ -918,7 +918,7 @@ static void __init a1200_init(void)
pxa_set_i2c_info(NULL); pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info)); 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); pxa_set_keypad_info(&a1200_keypad_platform_data);
...@@ -1103,7 +1103,7 @@ static void __init a910_init(void) ...@@ -1103,7 +1103,7 @@ static void __init a910_init(void)
pxa_set_i2c_info(NULL); pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info)); 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); pxa_set_keypad_info(&a910_keypad_platform_data);
...@@ -1173,7 +1173,7 @@ static void __init e6_init(void) ...@@ -1173,7 +1173,7 @@ static void __init e6_init(void)
pxa_set_i2c_info(NULL); pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info)); 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); pxa_set_keypad_info(&e6_keypad_platform_data);
...@@ -1212,7 +1212,7 @@ static void __init e2_init(void) ...@@ -1212,7 +1212,7 @@ static void __init e2_init(void)
pxa_set_i2c_info(NULL); pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info)); 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); pxa_set_keypad_info(&e2_keypad_platform_data);
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/usb/gpio_vbus.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/memory.h> #include <asm/memory.h>
...@@ -106,14 +107,22 @@ static void __init gumstix_mmc_init(void) ...@@ -106,14 +107,22 @@ static void __init gumstix_mmc_init(void)
#endif #endif
#ifdef CONFIG_USB_GADGET_PXA25X #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_vbus = GPIO_GUMSTIX_USB_GPIOn,
.gpio_pullup = GPIO_GUMSTIX_USB_GPIOx, .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) static void __init gumstix_udc_init(void)
{ {
pxa_set_udc_info(&gumstix_udc_info); platform_device_register(&gumstix_gpio_vbus);
} }
#else #else
static void gumstix_udc_init(void) static void gumstix_udc_init(void)
......
...@@ -167,7 +167,7 @@ static void __init idp_init(void) ...@@ -167,7 +167,7 @@ static void __init idp_init(void)
platform_device_register(&smc91x_device); platform_device_register(&smc91x_device);
//platform_device_register(&mst_audio_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); pxa_set_mci_info(&idp_mci_platform_data);
} }
......
...@@ -44,6 +44,11 @@ ...@@ -44,6 +44,11 @@
#define GPIO_NR_PALMZ72_BT_POWER 17 #define GPIO_NR_PALMZ72_BT_POWER 17
#define GPIO_NR_PALMZ72_BT_RESET 83 #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 **/ /** Initial values **/
/* Battery */ /* Battery */
......
...@@ -154,8 +154,8 @@ struct pxafb_mach_info { ...@@ -154,8 +154,8 @@ struct pxafb_mach_info {
void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *); void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
void (*smart_update)(struct fb_info *); 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); unsigned long pxafb_get_hsync_time(struct device *dev);
extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int); extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int);
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#define GPIO98_ZIPITZ2_LID_BUTTON 98 #define GPIO98_ZIPITZ2_LID_BUTTON 98
/* Libertas GSPI8686 WiFi */ /* Libertas GSPI8686 WiFi */
#define GPIO14_ZIPITZ2_WIFI_RESET 14 #define GPIO14_ZIPITZ2_WIFI_POWER 14
#define GPIO15_ZIPITZ2_WIFI_POWER 15
#define GPIO24_ZIPITZ2_WIFI_CS 24 #define GPIO24_ZIPITZ2_WIFI_CS 24
#define GPIO36_ZIPITZ2_WIFI_IRQ 36 #define GPIO36_ZIPITZ2_WIFI_IRQ 36
......
...@@ -185,7 +185,7 @@ static struct pxafb_mach_info littleton_lcd_info = { ...@@ -185,7 +185,7 @@ static struct pxafb_mach_info littleton_lcd_info = {
static void littleton_init_lcd(void) static void littleton_init_lcd(void)
{ {
set_pxa_fb_info(&littleton_lcd_info); pxa_set_fb_info(NULL, &littleton_lcd_info);
} }
#else #else
static inline void littleton_init_lcd(void) {}; static inline void littleton_init_lcd(void) {};
......
...@@ -480,7 +480,7 @@ static void __init lpd270_init(void) ...@@ -480,7 +480,7 @@ static void __init lpd270_init(void)
pxa_set_ac97_info(NULL); pxa_set_ac97_info(NULL);
if (lpd270_lcd_to_use != 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); pxa_set_ohci_info(&lpd270_ohci_platform_data);
} }
......
...@@ -521,7 +521,7 @@ static void __init lubbock_init(void) ...@@ -521,7 +521,7 @@ static void __init lubbock_init(void)
clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL); clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
pxa_set_udc_info(&udc_info); 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_mci_info(&lubbock_mci_platform_data);
pxa_set_ficp_info(&lubbock_ficp_platform_data); pxa_set_ficp_info(&lubbock_ficp_platform_data);
pxa_set_ac97_info(NULL); pxa_set_ac97_info(NULL);
......
...@@ -757,7 +757,7 @@ static void __init magician_init(void) ...@@ -757,7 +757,7 @@ static void __init magician_init(void)
gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0); gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0);
gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0); gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0);
gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 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 } else
pr_err("LCD detection: CPLD mapping failed\n"); pr_err("LCD detection: CPLD mapping failed\n");
} }
......
...@@ -592,7 +592,7 @@ static void __init mainstone_init(void) ...@@ -592,7 +592,7 @@ static void __init mainstone_init(void)
else else
mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode; 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(); mainstone_backlight_register();
pxa_set_mci_info(&mainstone_mci_platform_data); pxa_set_mci_info(&mainstone_mci_platform_data);
......
...@@ -795,7 +795,7 @@ static void __init mioa701_machine_init(void) ...@@ -795,7 +795,7 @@ static void __init mioa701_machine_init(void)
pxa_set_stuart_info(NULL); pxa_set_stuart_info(NULL);
mio_gpio_request(ARRAY_AND_SIZE(global_gpios)); mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
bootstrap_init(); 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_mci_info(&mioa701_mci_info);
pxa_set_keypad_info(&mioa701_keypad_info); pxa_set_keypad_info(&mioa701_keypad_info);
pxa_set_udc_info(&mioa701_udc_info); pxa_set_udc_info(&mioa701_udc_info);
......
/* /*
* Common code for Palm LD, T5, TX, Z72 * Common code for Palm LD, T5, TX, Z72
* *
* Copyright (C) 2010 * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
* Marek Vasut <marek.vasut@gmail.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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) ...@@ -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; 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 #endif
......
...@@ -507,7 +507,7 @@ static struct pxafb_mach_info palmtc_lcd_screen = { ...@@ -507,7 +507,7 @@ static struct pxafb_mach_info palmtc_lcd_screen = {
static void __init palmtc_lcd_init(void) static void __init palmtc_lcd_init(void)
{ {
set_pxa_fb_info(&palmtc_lcd_screen); pxa_set_fb_info(NULL, &palmtc_lcd_screen);
} }
#else #else
static inline void palmtc_lcd_init(void) {} static inline void palmtc_lcd_init(void) {}
......
...@@ -136,30 +136,14 @@ static struct platform_device palmte2_pxa_keys = { ...@@ -136,30 +136,14 @@ static struct platform_device palmte2_pxa_keys = {
/****************************************************************************** /******************************************************************************
* Backlight * 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) static int palmte2_backlight_init(struct device *dev)
{ {
int ret; return gpio_request_array(ARRAY_AND_SIZE(palmte_bl_gpios));
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;
} }
static int palmte2_backlight_notify(struct device *dev, int brightness) static int palmte2_backlight_notify(struct device *dev, int brightness)
...@@ -171,8 +155,7 @@ 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) static void palmte2_backlight_exit(struct device *dev)
{ {
gpio_free(GPIO_NR_PALMTE2_BL_POWER); gpio_free_array(ARRAY_AND_SIZE(palmte_bl_gpios));
gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
} }
static struct platform_pwm_backlight_data palmte2_backlight_data = { static struct platform_pwm_backlight_data palmte2_backlight_data = {
...@@ -363,7 +346,7 @@ static void __init palmte2_init(void) ...@@ -363,7 +346,7 @@ static void __init palmte2_init(void)
pxa_set_btuart_info(NULL); pxa_set_btuart_info(NULL);
pxa_set_stuart_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); pxa_set_mci_info(&palmte2_mci_platform_data);
palmte2_udc_init(); palmte2_udc_init();
pxa_set_ac97_info(&palmte2_ac97_pdata); pxa_set_ac97_info(&palmte2_ac97_pdata);
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/wm97xx.h> #include <linux/wm97xx.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h> #include <linux/usb/gpio_vbus.h>
#include <linux/i2c-gpio.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
...@@ -47,6 +48,9 @@ ...@@ -47,6 +48,9 @@
#include <mach/palm27x.h> #include <mach/palm27x.h>
#include <mach/pm.h> #include <mach/pm.h>
#include <mach/camera.h>
#include <media/soc_camera.h>
#include "generic.h" #include "generic.h"
#include "devices.h" #include "devices.h"
...@@ -103,6 +107,28 @@ static unsigned long palmz72_pin_config[] __initdata = { ...@@ -103,6 +107,28 @@ static unsigned long palmz72_pin_config[] __initdata = {
GPIO22_GPIO, /* LCD border color */ GPIO22_GPIO, /* LCD border color */
GPIO96_GPIO, /* lcd power */ 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. */ /* Misc. */
GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* power detect */ GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* power detect */
GPIO88_GPIO, /* green led */ GPIO88_GPIO, /* green led */
...@@ -253,6 +279,106 @@ static int __init palmz72_pm_init(void) ...@@ -253,6 +279,106 @@ static int __init palmz72_pm_init(void)
device_initcall(palmz72_pm_init); device_initcall(palmz72_pm_init);
#endif #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 * Machine init
******************************************************************************/ ******************************************************************************/
...@@ -276,6 +402,7 @@ static void __init palmz72_init(void) ...@@ -276,6 +402,7 @@ static void __init palmz72_init(void)
palm27x_pmic_init(); palm27x_pmic_init();
palmz72_kpc_init(); palmz72_kpc_init();
palmz72_leds_init(); palmz72_leds_init();
palmz72_camera_init();
} }
MACHINE_START(PALMZ72, "Palm Zire72") MACHINE_START(PALMZ72, "Palm Zire72")
......
...@@ -515,7 +515,7 @@ void __init pcm990_baseboard_init(void) ...@@ -515,7 +515,7 @@ void __init pcm990_baseboard_init(void)
pcm990_init_irq(); pcm990_init_irq();
#ifndef CONFIG_PCM990_DISPLAY_NONE #ifndef CONFIG_PCM990_DISPLAY_NONE
set_pxa_fb_info(&pcm990_fbinfo); pxa_set_fb_info(NULL, &pcm990_fbinfo);
#endif #endif
platform_device_register(&pcm990_backlight_device); platform_device_register(&pcm990_backlight_device);
......
...@@ -445,8 +445,7 @@ static void __init poodle_init(void) ...@@ -445,8 +445,7 @@ static void __init poodle_init(void)
if (ret) if (ret)
pr_warning("poodle: Unable to register LoCoMo device\n"); pr_warning("poodle: Unable to register LoCoMo device\n");
set_pxa_fb_parent(&poodle_locomo_device.dev); pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info);
set_pxa_fb_info(&poodle_fb_info);
pxa_set_udc_info(&udc_info); pxa_set_udc_info(&udc_info);
pxa_set_mci_info(&poodle_mci_platform_data); pxa_set_mci_info(&poodle_mci_platform_data);
pxa_set_ficp_info(&poodle_ficp_platform_data); pxa_set_ficp_info(&poodle_ficp_platform_data);
......
...@@ -597,7 +597,7 @@ static void __init raumfeld_lcd_init(void) ...@@ -597,7 +597,7 @@ static void __init raumfeld_lcd_init(void)
{ {
int ret; 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 /* Earlier devices had the backlight regulator controlled
* via PWM, later versions use another controller for that */ * via PWM, later versions use another controller for that */
......
...@@ -473,7 +473,7 @@ static struct pxafb_mach_info saar_lcd_info = { ...@@ -473,7 +473,7 @@ static struct pxafb_mach_info saar_lcd_info = {
static void __init saar_init_lcd(void) static void __init saar_init_lcd(void)
{ {
set_pxa_fb_info(&saar_lcd_info); pxa_set_fb_info(NULL, &saar_lcd_info);
} }
#else #else
static inline void saar_init_lcd(void) {} static inline void saar_init_lcd(void) {}
......
...@@ -724,7 +724,7 @@ static struct pxafb_mach_info spitz_pxafb_info = { ...@@ -724,7 +724,7 @@ static struct pxafb_mach_info spitz_pxafb_info = {
static void __init spitz_lcd_init(void) static void __init spitz_lcd_init(void)
{ {
set_pxa_fb_info(&spitz_pxafb_info); pxa_set_fb_info(NULL, &spitz_pxafb_info);
} }
#else #else
static inline void spitz_lcd_init(void) {} static inline void spitz_lcd_init(void) {}
......
...@@ -466,7 +466,7 @@ static void __init tavorevb_init_lcd(void) ...@@ -466,7 +466,7 @@ static void __init tavorevb_init_lcd(void)
{ {
platform_device_register(&tavorevb_backlight_devices[0]); platform_device_register(&tavorevb_backlight_devices[0]);
platform_device_register(&tavorevb_backlight_devices[1]); platform_device_register(&tavorevb_backlight_devices[1]);
set_pxa_fb_info(&tavorevb_lcd_info); pxa_set_fb_info(NULL, &tavorevb_lcd_info);
} }
#else #else
static inline void tavorevb_init_lcd(void) {} static inline void tavorevb_init_lcd(void) {}
......
...@@ -100,7 +100,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) ...@@ -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 = { static struct clock_event_device ckevt_pxa_osmr0 = {
.name = "osmr0", .name = "osmr0",
.features = CLOCK_EVT_FEAT_ONESHOT, .features = CLOCK_EVT_FEAT_ONESHOT,
.shift = 32,
.rating = 200, .rating = 200,
.set_next_event = pxa_osmr0_set_next_event, .set_next_event = pxa_osmr0_set_next_event,
.set_mode = pxa_osmr0_set_mode, .set_mode = pxa_osmr0_set_mode,
...@@ -135,8 +134,8 @@ static void __init pxa_timer_init(void) ...@@ -135,8 +134,8 @@ static void __init pxa_timer_init(void)
init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate); init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
ckevt_pxa_osmr0.mult = clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4);
div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);
ckevt_pxa_osmr0.max_delta_ns = ckevt_pxa_osmr0.max_delta_ns =
clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
ckevt_pxa_osmr0.min_delta_ns = ckevt_pxa_osmr0.min_delta_ns =
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/spi/pxa2xx_spi.h> #include <linux/spi/pxa2xx_spi.h>
#include <linux/input/matrix_keypad.h> #include <linux/input/matrix_keypad.h>
#include <linux/i2c/pxa-i2c.h> #include <linux/i2c/pxa-i2c.h>
#include <linux/usb/gpio_vbus.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -240,12 +241,20 @@ static struct scoop_pcmcia_config tosa_pcmcia_config = { ...@@ -240,12 +241,20 @@ static struct scoop_pcmcia_config tosa_pcmcia_config = {
/* /*
* USB Device Controller * 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_pullup = TOSA_GPIO_USB_PULLUP,
.gpio_vbus = TOSA_GPIO_USB_IN, .gpio_vbus = TOSA_GPIO_USB_IN,
.gpio_vbus_inverted = 1, .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 * MMC/SD Device
*/ */
...@@ -891,6 +900,7 @@ static struct platform_device *devices[] __initdata = { ...@@ -891,6 +900,7 @@ static struct platform_device *devices[] __initdata = {
&tosa_bt_device, &tosa_bt_device,
&sharpsl_rom_device, &sharpsl_rom_device,
&wm9712_device, &wm9712_device,
&tosa_gpio_vbus,
}; };
static void tosa_poweroff(void) static void tosa_poweroff(void)
...@@ -937,7 +947,6 @@ static void __init tosa_init(void) ...@@ -937,7 +947,6 @@ static void __init tosa_init(void)
dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16); dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
pxa_set_mci_info(&tosa_mci_platform_data); pxa_set_mci_info(&tosa_mci_platform_data);
pxa_set_udc_info(&udc_info);
pxa_set_ficp_info(&tosa_ficp_platform_data); pxa_set_ficp_info(&tosa_ficp_platform_data);
pxa_set_i2c_info(NULL); pxa_set_i2c_info(NULL);
pxa_set_ac97_info(NULL); pxa_set_ac97_info(NULL);
......
...@@ -516,9 +516,9 @@ static void __init trizeps4_init(void) ...@@ -516,9 +516,9 @@ static void __init trizeps4_init(void)
pxa_set_stuart_info(NULL); pxa_set_stuart_info(NULL);
if (0) /* dont know how to determine LCD */ if (0) /* dont know how to determine LCD */
set_pxa_fb_info(&sharp_lcd); pxa_set_fb_info(NULL, &sharp_lcd);
else else
set_pxa_fb_info(&toshiba_lcd); pxa_set_fb_info(NULL, &toshiba_lcd);
pxa_set_mci_info(&trizeps4_mci_platform_data); pxa_set_mci_info(&trizeps4_mci_platform_data);
#ifndef STATUS_LEDS_ON_STUART_PINS #ifndef STATUS_LEDS_ON_STUART_PINS
......
...@@ -932,7 +932,7 @@ static void __init viper_init(void) ...@@ -932,7 +932,7 @@ static void __init viper_init(void)
/* Wake-up serial console */ /* Wake-up serial console */
viper_init_serial_gpio(); viper_init_serial_gpio();
set_pxa_fb_info(&fb_info); pxa_set_fb_info(NULL, &fb_info);
/* v1 hardware cannot use the datacs line */ /* v1 hardware cannot use the datacs line */
version = viper_hw_version(); version = viper_hw_version();
......
...@@ -572,7 +572,7 @@ static void __init vpac270_lcd_init(void) ...@@ -572,7 +572,7 @@ static void __init vpac270_lcd_init(void)
} }
vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power; 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; return;
err2: err2:
......
...@@ -91,13 +91,13 @@ static unsigned long z2_pin_config[] = { ...@@ -91,13 +91,13 @@ static unsigned long z2_pin_config[] = {
GPIO47_STUART_TXD, GPIO47_STUART_TXD,
/* Keypad */ /* Keypad */
GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, GPIO100_KP_MKIN_0,
GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, GPIO101_KP_MKIN_1,
GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, GPIO102_KP_MKIN_2,
GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, GPIO34_KP_MKIN_3,
GPIO38_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, GPIO38_KP_MKIN_4,
GPIO16_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH, GPIO16_KP_MKIN_5,
GPIO17_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH, GPIO17_KP_MKIN_6,
GPIO103_KP_MKOUT_0, GPIO103_KP_MKOUT_0,
GPIO104_KP_MKOUT_1, GPIO104_KP_MKOUT_1,
GPIO105_KP_MKOUT_2, GPIO105_KP_MKOUT_2,
...@@ -138,8 +138,7 @@ static unsigned long z2_pin_config[] = { ...@@ -138,8 +138,7 @@ static unsigned long z2_pin_config[] = {
GPIO1_GPIO, /* Power button */ GPIO1_GPIO, /* Power button */
GPIO37_GPIO, /* Headphone detect */ GPIO37_GPIO, /* Headphone detect */
GPIO98_GPIO, /* Lid switch */ GPIO98_GPIO, /* Lid switch */
GPIO14_GPIO, /* WiFi Reset */ GPIO14_GPIO, /* WiFi Power */
GPIO15_GPIO, /* WiFi Power */
GPIO24_GPIO, /* WiFi CS */ GPIO24_GPIO, /* WiFi CS */
GPIO36_GPIO, /* WiFi IRQ */ GPIO36_GPIO, /* WiFi IRQ */
GPIO88_GPIO, /* LCD CS */ GPIO88_GPIO, /* LCD CS */
...@@ -204,7 +203,7 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = { ...@@ -204,7 +203,7 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = {
/* Keypad Backlight */ /* Keypad Backlight */
.pwm_id = 1, .pwm_id = 1,
.max_brightness = 1023, .max_brightness = 1023,
.dft_brightness = 512, .dft_brightness = 0,
.pwm_period_ns = 1260320, .pwm_period_ns = 1260320,
}, },
[1] = { [1] = {
...@@ -271,7 +270,7 @@ static struct pxafb_mach_info z2_lcd_screen = { ...@@ -271,7 +270,7 @@ static struct pxafb_mach_info z2_lcd_screen = {
static void __init z2_lcd_init(void) static void __init z2_lcd_init(void)
{ {
set_pxa_fb_info(&z2_lcd_screen); pxa_set_fb_info(NULL, &z2_lcd_screen);
} }
#else #else
static inline void z2_lcd_init(void) {} static inline void z2_lcd_init(void) {}
...@@ -309,12 +308,12 @@ struct gpio_led z2_gpio_leds[] = { ...@@ -309,12 +308,12 @@ struct gpio_led z2_gpio_leds[] = {
.active_low = 1, .active_low = 1,
}, { }, {
.name = "z2:green:charged", .name = "z2:green:charged",
.default_trigger = "none", .default_trigger = "mmc0",
.gpio = GPIO85_ZIPITZ2_LED_CHARGED, .gpio = GPIO85_ZIPITZ2_LED_CHARGED,
.active_low = 1, .active_low = 1,
}, { }, {
.name = "z2:amber:charging", .name = "z2:amber:charging",
.default_trigger = "none", .default_trigger = "Z2-charging-or-full",
.gpio = GPIO83_ZIPITZ2_LED_CHARGING, .gpio = GPIO83_ZIPITZ2_LED_CHARGING,
.active_low = 1, .active_low = 1,
}, },
...@@ -427,8 +426,22 @@ static inline void z2_mkp_init(void) {} ...@@ -427,8 +426,22 @@ static inline void z2_mkp_init(void) {}
******************************************************************************/ ******************************************************************************/
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
static struct gpio_keys_button z2_pxa_buttons[] = { 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 = { static struct gpio_keys_platform_data z2_pxa_keys_data = {
...@@ -461,9 +474,9 @@ static struct z2_battery_info batt_chip_info = { ...@@ -461,9 +474,9 @@ static struct z2_battery_info batt_chip_info = {
.batt_I2C_addr = 0x55, .batt_I2C_addr = 0x55,
.batt_I2C_reg = 2, .batt_I2C_reg = 2,
.charge_gpio = GPIO0_ZIPITZ2_AC_DETECT, .charge_gpio = GPIO0_ZIPITZ2_AC_DETECT,
.min_voltage = 2400000, .min_voltage = 3475000,
.max_voltage = 3700000, .max_voltage = 4190000,
.batt_div = 69, .batt_div = 59,
.batt_mult = 1000000, .batt_mult = 1000000,
.batt_tech = POWER_SUPPLY_TECHNOLOGY_LION, .batt_tech = POWER_SUPPLY_TECHNOLOGY_LION,
.batt_name = "Z2", .batt_name = "Z2",
...@@ -497,26 +510,16 @@ static int z2_lbs_spi_setup(struct spi_device *spi) ...@@ -497,26 +510,16 @@ static int z2_lbs_spi_setup(struct spi_device *spi)
{ {
int ret = 0; int ret = 0;
ret = gpio_request(GPIO15_ZIPITZ2_WIFI_POWER, "WiFi Power"); ret = gpio_request(GPIO14_ZIPITZ2_WIFI_POWER, "WiFi Power");
if (ret) if (ret)
goto err; goto err;
ret = gpio_direction_output(GPIO15_ZIPITZ2_WIFI_POWER, 1); ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_POWER, 1);
if (ret) if (ret)
goto err2; goto err2;
ret = gpio_request(GPIO14_ZIPITZ2_WIFI_RESET, "WiFi Reset"); /* Wait until card is powered on */
if (ret)
goto err2;
ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_RESET, 0);
if (ret)
goto err3;
/* Reset the card */
mdelay(180); mdelay(180);
gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 1);
mdelay(20);
spi->bits_per_word = 16; spi->bits_per_word = 16;
spi->mode = SPI_MODE_2, spi->mode = SPI_MODE_2,
...@@ -525,22 +528,18 @@ static int z2_lbs_spi_setup(struct spi_device *spi) ...@@ -525,22 +528,18 @@ static int z2_lbs_spi_setup(struct spi_device *spi)
return 0; return 0;
err3:
gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
err2: err2:
gpio_free(GPIO15_ZIPITZ2_WIFI_POWER); gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
err: err:
return ret; return ret;
}; };
static int z2_lbs_spi_teardown(struct spi_device *spi) static int z2_lbs_spi_teardown(struct spi_device *spi)
{ {
gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 0); gpio_set_value(GPIO14_ZIPITZ2_WIFI_POWER, 0);
gpio_set_value(GPIO15_ZIPITZ2_WIFI_POWER, 0); gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
return 0;
return 0;
}; };
static struct pxa2xx_spi_chip z2_lbs_chip_info = { static struct pxa2xx_spi_chip z2_lbs_chip_info = {
......
...@@ -846,7 +846,7 @@ static void __init zeus_init(void) ...@@ -846,7 +846,7 @@ static void __init zeus_init(void)
if (zeus_setup_fb_gpios()) if (zeus_setup_fb_gpios())
pr_err("Failed to setup fb gpios\n"); pr_err("Failed to setup fb gpios\n");
else 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_mci_info(&zeus_mci_platform_data);
pxa_set_udc_info(&zeus_udc_info); pxa_set_udc_info(&zeus_udc_info);
......
...@@ -208,7 +208,7 @@ static void __init zylonite_init_lcd(void) ...@@ -208,7 +208,7 @@ static void __init zylonite_init_lcd(void)
platform_device_register(&zylonite_backlight_device); platform_device_register(&zylonite_backlight_device);
if (lcd_id & 0x20) { if (lcd_id & 0x20) {
set_pxa_fb_info(&zylonite_sharp_lcd_info); pxa_set_fb_info(NULL, &zylonite_sharp_lcd_info);
return; return;
} }
...@@ -220,7 +220,7 @@ static void __init zylonite_init_lcd(void) ...@@ -220,7 +220,7 @@ static void __init zylonite_init_lcd(void)
else else
zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode; 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 #else
static inline void zylonite_init_lcd(void) {} static inline void zylonite_init_lcd(void) {}
......
...@@ -33,6 +33,11 @@ ...@@ -33,6 +33,11 @@
#define DRV_NAME "pata_palmld" #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 = { static struct scsi_host_template palmld_sht = {
ATA_PIO_SHT(DRV_NAME), ATA_PIO_SHT(DRV_NAME),
}; };
...@@ -52,28 +57,23 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) ...@@ -52,28 +57,23 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev)
/* allocate host */ /* allocate host */
host = ata_host_alloc(&pdev->dev, 1); host = ata_host_alloc(&pdev->dev, 1);
if (!host) if (!host) {
return -ENOMEM; ret = -ENOMEM;
goto err1;
}
/* remap drive's physical memory address */ /* remap drive's physical memory address */
mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000); mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000);
if (!mem) if (!mem) {
return -ENOMEM; ret = -ENOMEM;
goto err1;
}
/* request and activate power GPIO, IRQ GPIO */ /* 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) if (ret)
goto err1; 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 */ /* reset the drive */
gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0); gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0);
...@@ -96,13 +96,15 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) ...@@ -96,13 +96,15 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev)
ata_sff_std_ports(&ap->ioaddr); ata_sff_std_ports(&ap->ioaddr);
/* activate host */ /* activate host */
return ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING, ret = ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING,
&palmld_sht); &palmld_sht);
if (ret)
goto err2;
return ret;
err3:
gpio_free(GPIO_NR_PALMLD_IDE_RESET);
err2: err2:
gpio_free(GPIO_NR_PALMLD_IDE_PWEN); gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
err1: err1:
return ret; return ret;
} }
...@@ -116,8 +118,7 @@ static __devexit int palmld_pata_remove(struct platform_device *dev) ...@@ -116,8 +118,7 @@ static __devexit int palmld_pata_remove(struct platform_device *dev)
/* power down the HDD */ /* power down the HDD */
gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0); gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0);
gpio_free(GPIO_NR_PALMLD_IDE_RESET); gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
gpio_free(GPIO_NR_PALMLD_IDE_PWEN);
return 0; return 0;
} }
......
...@@ -34,14 +34,24 @@ ...@@ -34,14 +34,24 @@
#define COLIBRI320_DETECT_GPIO 81 #define COLIBRI320_DETECT_GPIO 81
#define COLIBRI320_READY_GPIO 29 #define COLIBRI320_READY_GPIO 29
static struct { enum {
int reset_gpio; DETECT = 0,
int ppen_gpio; READY = 1,
int bvd1_gpio; BVD1 = 2,
int bvd2_gpio; BVD2 = 3,
int detect_gpio; PPEN = 4,
int ready_gpio; RESET = 5,
} colibri_pcmcia_gpio; };
/* 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[] = { static struct pcmcia_irqs colibri_irqs[] = {
{ {
...@@ -54,88 +64,42 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -54,88 +64,42 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret; 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) if (ret)
goto err1; 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"); colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
if (ret) skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio);
goto err3;
ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio);
if (ret)
goto err4;
ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2"); ret = soc_pcmcia_request_irqs(skt, colibri_irqs,
if (ret) ARRAY_SIZE(colibri_irqs));
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);
if (ret) if (ret)
goto err7; goto err2;
colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio);
skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio);
return soc_pcmcia_request_irqs(skt, colibri_irqs, return ret;
ARRAY_SIZE(colibri_irqs));
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: err2:
gpio_free(colibri_pcmcia_gpio.ppen_gpio); gpio_free_array(colibri_pcmcia_gpios,
ARRAY_SIZE(colibri_pcmcia_gpios));
err1: err1:
return ret; return ret;
} }
static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
gpio_free(colibri_pcmcia_gpio.detect_gpio); gpio_free_array(colibri_pcmcia_gpios,
gpio_free(colibri_pcmcia_gpio.ready_gpio); ARRAY_SIZE(colibri_pcmcia_gpios));
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);
} }
static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state) struct pcmcia_state *state)
{ {
state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio); state->detect = !!gpio_get_value(colibri_pcmcia_gpios[DETECT].gpio);
state->ready = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio); state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio);
state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio); state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);
state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio); state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio);
state->wrprot = 0; state->wrprot = 0;
state->vs_3v = 1; state->vs_3v = 1;
state->vs_Xv = 0; state->vs_Xv = 0;
...@@ -145,9 +109,10 @@ static int ...@@ -145,9 +109,10 @@ static int
colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state) 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)); !(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; return 0;
} }
...@@ -190,20 +155,20 @@ static int __init colibri_pcmcia_init(void) ...@@ -190,20 +155,20 @@ static int __init colibri_pcmcia_init(void)
/* Colibri PXA270 */ /* Colibri PXA270 */
if (machine_is_colibri()) { if (machine_is_colibri()) {
colibri_pcmcia_gpio.reset_gpio = COLIBRI270_RESET_GPIO; colibri_pcmcia_gpios[RESET].gpio = COLIBRI270_RESET_GPIO;
colibri_pcmcia_gpio.ppen_gpio = COLIBRI270_PPEN_GPIO; colibri_pcmcia_gpios[PPEN].gpio = COLIBRI270_PPEN_GPIO;
colibri_pcmcia_gpio.bvd1_gpio = COLIBRI270_BVD1_GPIO; colibri_pcmcia_gpios[BVD1].gpio = COLIBRI270_BVD1_GPIO;
colibri_pcmcia_gpio.bvd2_gpio = COLIBRI270_BVD2_GPIO; colibri_pcmcia_gpios[BVD2].gpio = COLIBRI270_BVD2_GPIO;
colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO; colibri_pcmcia_gpios[DETECT].gpio = COLIBRI270_DETECT_GPIO;
colibri_pcmcia_gpio.ready_gpio = COLIBRI270_READY_GPIO; colibri_pcmcia_gpios[READY].gpio = COLIBRI270_READY_GPIO;
/* Colibri PXA320 */ /* Colibri PXA320 */
} else if (machine_is_colibri320()) { } else if (machine_is_colibri320()) {
colibri_pcmcia_gpio.reset_gpio = COLIBRI320_RESET_GPIO; colibri_pcmcia_gpios[RESET].gpio = COLIBRI320_RESET_GPIO;
colibri_pcmcia_gpio.ppen_gpio = COLIBRI320_PPEN_GPIO; colibri_pcmcia_gpios[PPEN].gpio = COLIBRI320_PPEN_GPIO;
colibri_pcmcia_gpio.bvd1_gpio = COLIBRI320_BVD1_GPIO; colibri_pcmcia_gpios[BVD1].gpio = COLIBRI320_BVD1_GPIO;
colibri_pcmcia_gpio.bvd2_gpio = COLIBRI320_BVD2_GPIO; colibri_pcmcia_gpios[BVD2].gpio = COLIBRI320_BVD2_GPIO;
colibri_pcmcia_gpio.detect_gpio = COLIBRI320_DETECT_GPIO; colibri_pcmcia_gpios[DETECT].gpio = COLIBRI320_DETECT_GPIO;
colibri_pcmcia_gpio.ready_gpio = COLIBRI320_READY_GPIO; colibri_pcmcia_gpios[READY].gpio = COLIBRI320_READY_GPIO;
} }
ret = platform_device_add_data(colibri_pcmcia_device, ret = platform_device_add_data(colibri_pcmcia_device,
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Driver for Palm LifeDrive PCMCIA * Driver for Palm LifeDrive PCMCIA
* *
* Copyright (C) 2006 Alex Osborne <ato@meshy.org> * 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 * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -20,49 +20,27 @@ ...@@ -20,49 +20,27 @@
#include <mach/palmld.h> #include <mach/palmld.h>
#include "soc_common.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) static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret; int ret;
ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR"); ret = gpio_request_array(palmld_pcmcia_gpios,
if (ret) ARRAY_SIZE(palmld_pcmcia_gpios));
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;
skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); 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; return ret;
} }
static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
gpio_free(GPIO_NR_PALMLD_PCMCIA_READY); gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios));
gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
} }
static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Driver for Palm Tungsten|C PCMCIA * Driver for Palm Tungsten|C PCMCIA
* *
* Copyright (C) 2008 Alex Osborne <ato@meshy.org> * 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 * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -21,79 +21,30 @@ ...@@ -21,79 +21,30 @@
#include <mach/palmtc.h> #include <mach/palmtc.h>
#include "soc_common.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) static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret; int ret;
ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1"); ret = gpio_request_array(palmtc_pcmcia_gpios,
if (ret) ARRAY_SIZE(palmtc_pcmcia_gpios));
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;
skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY); 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; return ret;
} }
static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY); gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios));
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);
} }
static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Driver for Palm T|X PCMCIA * 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 * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -13,67 +13,34 @@ ...@@ -13,67 +13,34 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/gpio.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/gpio.h>
#include <mach/palmtx.h> #include <mach/palmtx.h>
#include "soc_common.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) static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{ {
int ret; int ret;
ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1"); ret = gpio_request_array(palmtx_pcmcia_gpios,
if (ret) ARRAY_SIZE(palmtx_pcmcia_gpios));
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;
skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); 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; return ret;
} }
static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
gpio_free(GPIO_NR_PALMTX_PCMCIA_READY); gpio_free_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios));
gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
} }
static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
......
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
* *
* Driver for Voipac PXA270 PCMCIA and CF sockets * Driver for Voipac PXA270 PCMCIA and CF sockets
* *
* Copyright (C) 2010 * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
* Marek Vasut <marek.vasut@gmail.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -22,6 +21,19 @@ ...@@ -22,6 +21,19 @@
#include "soc_common.h" #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[] = { static struct pcmcia_irqs cd_irqs[] = {
{ {
.sock = 0, .sock = 0,
...@@ -40,96 +52,34 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ...@@ -40,96 +52,34 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
int ret; int ret;
if (skt->nr == 0) { if (skt->nr == 0) {
ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD"); ret = gpio_request_array(vpac270_pcmcia_gpios,
if (ret) ARRAY_SIZE(vpac270_pcmcia_gpios));
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;
skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); if (!ret)
ret = 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;
} else { } else {
ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD"); ret = gpio_request_array(vpac270_cf_gpios,
if (ret) ARRAY_SIZE(vpac270_cf_gpios));
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;
skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); if (!ret)
ret = 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; return ret;
}
} }
static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{ {
gpio_free(GPIO11_VPAC270_PCMCIA_RESET); if (skt->nr == 0)
gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); gpio_request_array(vpac270_pcmcia_gpios,
gpio_free(GPIO35_VPAC270_PCMCIA_RDY); ARRAY_SIZE(vpac270_pcmcia_gpios));
gpio_free(GPIO84_VPAC270_PCMCIA_CD); else
gpio_free(GPIO16_VPAC270_CF_RESET); gpio_request_array(vpac270_cf_gpios,
gpio_free(GPIO12_VPAC270_CF_RDY); ARRAY_SIZE(vpac270_cf_gpios));
gpio_free(GPIO17_VPAC270_CF_CD);
} }
static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
......
...@@ -139,24 +139,6 @@ static const char ep0name [] = "ep0"; ...@@ -139,24 +139,6 @@ static const char ep0name [] = "ep0";
static void pxa25x_ep_fifo_flush (struct usb_ep *ep); static void pxa25x_ep_fifo_flush (struct usb_ep *ep);
static void nuke (struct pxa25x_ep *, int status); 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) */ /* one GPIO should control a D+ pullup, so host sees this device (or not) */
static void pullup_off(void) static void pullup_off(void)
{ {
...@@ -1055,7 +1037,7 @@ udc_seq_show(struct seq_file *m, void *_d) ...@@ -1055,7 +1037,7 @@ udc_seq_show(struct seq_file *m, void *_d)
"%s version: %s\nGadget driver: %s\nHost %s\n\n", "%s version: %s\nGadget driver: %s\nHost %s\n\n",
driver_name, DRIVER_VERSION SIZE_STR "(pio)", driver_name, DRIVER_VERSION SIZE_STR "(pio)",
dev->driver ? dev->driver->driver.name : "(none)", 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 */ /* registers for device and ep0 */
seq_printf(m, seq_printf(m,
...@@ -1094,7 +1076,7 @@ udc_seq_show(struct seq_file *m, void *_d) ...@@ -1094,7 +1076,7 @@ udc_seq_show(struct seq_file *m, void *_d)
(tmp & UDCCFR_ACM) ? " acm" : ""); (tmp & UDCCFR_ACM) ? " acm" : "");
} }
if (!is_vbus_present() || !dev->driver) if (dev->gadget.speed != USB_SPEED_FULL || !dev->driver)
goto done; goto done;
seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", 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,14 +1417,6 @@ lubbock_vbus_irq(int irq, void *_dev)
#endif #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) ...@@ -1766,12 +1740,9 @@ pxa25x_udc_irq(int irq, void *_dev)
if (unlikely(udccr & UDCCR_SUSIR)) { if (unlikely(udccr & UDCCR_SUSIR)) {
udc_ack_int_UDCCR(UDCCR_SUSIR); udc_ack_int_UDCCR(UDCCR_SUSIR);
handled = 1; handled = 1;
DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present() DBG(DBG_VERBOSE, "USB suspend\n");
? "" : "+disconnect");
if (!is_vbus_present()) if (dev->gadget.speed != USB_SPEED_UNKNOWN
stop_activity(dev, dev->driver);
else if (dev->gadget.speed != USB_SPEED_UNKNOWN
&& dev->driver && dev->driver
&& dev->driver->suspend) && dev->driver->suspend)
dev->driver->suspend(&dev->gadget); dev->driver->suspend(&dev->gadget);
...@@ -1786,8 +1757,7 @@ pxa25x_udc_irq(int irq, void *_dev) ...@@ -1786,8 +1757,7 @@ pxa25x_udc_irq(int irq, void *_dev)
if (dev->gadget.speed != USB_SPEED_UNKNOWN if (dev->gadget.speed != USB_SPEED_UNKNOWN
&& dev->driver && dev->driver
&& dev->driver->resume && dev->driver->resume)
&& is_vbus_present())
dev->driver->resume(&dev->gadget); dev->driver->resume(&dev->gadget);
} }
...@@ -2137,7 +2107,7 @@ static struct pxa25x_udc memory = { ...@@ -2137,7 +2107,7 @@ static struct pxa25x_udc memory = {
static int __init pxa25x_udc_probe(struct platform_device *pdev) static int __init pxa25x_udc_probe(struct platform_device *pdev)
{ {
struct pxa25x_udc *dev = &memory; struct pxa25x_udc *dev = &memory;
int retval, vbus_irq, irq; int retval, irq;
u32 chiprev; u32 chiprev;
/* insist on Intel/ARM/XScale */ /* insist on Intel/ARM/XScale */
...@@ -2199,19 +2169,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ...@@ -2199,19 +2169,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
dev->transceiver = otg_get_transceiver(); 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 (gpio_is_valid(dev->mach->gpio_pullup)) {
if ((retval = gpio_request(dev->mach->gpio_pullup, if ((retval = gpio_request(dev->mach->gpio_pullup,
"pca25x_udc GPIO PULLUP"))) { "pca25x_udc GPIO PULLUP"))) {
...@@ -2237,7 +2194,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ...@@ -2237,7 +2194,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
udc_disable(dev); udc_disable(dev);
udc_reinit(dev); udc_reinit(dev);
dev->vbus = !!is_vbus_present(); dev->vbus = 0;
/* irq setup after old hardware state is cleaned up */ /* irq setup after old hardware state is cleaned up */
retval = request_irq(irq, pxa25x_udc_irq, retval = request_irq(irq, pxa25x_udc_irq,
...@@ -2273,22 +2230,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ...@@ -2273,22 +2230,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
} }
} else } else
#endif #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); create_debug_files(dev);
return 0; return 0;
err_vbus_irq:
#ifdef CONFIG_ARCH_LUBBOCK #ifdef CONFIG_ARCH_LUBBOCK
free_irq(LUBBOCK_USB_DISC_IRQ, dev); free_irq(LUBBOCK_USB_DISC_IRQ, dev);
err_irq_lub: err_irq_lub:
...@@ -2298,9 +2243,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ...@@ -2298,9 +2243,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
if (gpio_is_valid(dev->mach->gpio_pullup)) if (gpio_is_valid(dev->mach->gpio_pullup))
gpio_free(dev->mach->gpio_pullup); gpio_free(dev->mach->gpio_pullup);
err_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) { if (dev->transceiver) {
otg_put_transceiver(dev->transceiver); otg_put_transceiver(dev->transceiver);
dev->transceiver = NULL; dev->transceiver = NULL;
...@@ -2337,10 +2279,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) ...@@ -2337,10 +2279,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
free_irq(LUBBOCK_USB_IRQ, dev); free_irq(LUBBOCK_USB_IRQ, dev);
} }
#endif #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)) if (gpio_is_valid(dev->mach->gpio_pullup))
gpio_free(dev->mach->gpio_pullup); gpio_free(dev->mach->gpio_pullup);
......
...@@ -627,7 +627,12 @@ static void overlay1fb_enable(struct pxafb_layer *ofb) ...@@ -627,7 +627,12 @@ static void overlay1fb_enable(struct pxafb_layer *ofb)
static void overlay1fb_disable(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); lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
...@@ -685,7 +690,12 @@ static void overlay2fb_enable(struct pxafb_layer *ofb) ...@@ -685,7 +690,12 @@ static void overlay2fb_enable(struct pxafb_layer *ofb)
static void overlay2fb_disable(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); lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
...@@ -720,12 +730,10 @@ static int overlayfb_open(struct fb_info *info, int user) ...@@ -720,12 +730,10 @@ static int overlayfb_open(struct fb_info *info, int user)
if (user == 0) if (user == 0)
return -ENODEV; return -ENODEV;
/* allow only one user at a time */ if (ofb->usage++ == 0)
if (atomic_inc_and_test(&ofb->usage))
return -EBUSY;
/* unblank the base framebuffer */ /* unblank the base framebuffer */
fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK); fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
return 0; return 0;
} }
...@@ -733,12 +741,15 @@ static int overlayfb_release(struct fb_info *info, int user) ...@@ -733,12 +741,15 @@ static int overlayfb_release(struct fb_info *info, int user)
{ {
struct pxafb_layer *ofb = (struct pxafb_layer*) info; struct pxafb_layer *ofb = (struct pxafb_layer*) info;
atomic_dec(&ofb->usage); if (ofb->usage == 1) {
ofb->ops->disable(ofb); 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->usage--;
ofb->video_mem = NULL; }
ofb->video_mem_size = 0;
return 0; return 0;
} }
...@@ -750,7 +761,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var, ...@@ -750,7 +761,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
int xpos, ypos, pfor, bpp; int xpos, ypos, pfor, bpp;
xpos = NONSTD_TO_XPOS(var->nonstd); xpos = NONSTD_TO_XPOS(var->nonstd);
ypos = NONSTD_TO_XPOS(var->nonstd); ypos = NONSTD_TO_YPOS(var->nonstd);
pfor = NONSTD_TO_PFOR(var->nonstd); pfor = NONSTD_TO_PFOR(var->nonstd);
bpp = pxafb_var_to_bpp(var); bpp = pxafb_var_to_bpp(var);
...@@ -794,7 +805,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var, ...@@ -794,7 +805,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
return 0; 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; struct fb_var_screeninfo *var = &ofb->fb.var;
int pfor = NONSTD_TO_PFOR(var->nonstd); int pfor = NONSTD_TO_PFOR(var->nonstd);
...@@ -812,27 +823,11 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb) ...@@ -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); 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) {
if (ofb->video_mem_size >= size) if (ofb->video_mem_size >= size)
return 0; return 0;
free_pages_exact(ofb->video_mem, ofb->video_mem_size);
} }
return -EINVAL;
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;
} }
static int overlayfb_set_par(struct fb_info *info) static int overlayfb_set_par(struct fb_info *info)
...@@ -841,13 +836,13 @@ 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; struct fb_var_screeninfo *var = &info->var;
int xpos, ypos, pfor, bpp, ret; int xpos, ypos, pfor, bpp, ret;
ret = overlayfb_map_video_memory(ofb); ret = overlayfb_check_video_memory(ofb);
if (ret) if (ret)
return ret; return ret;
bpp = pxafb_var_to_bpp(var); bpp = pxafb_var_to_bpp(var);
xpos = NONSTD_TO_XPOS(var->nonstd); xpos = NONSTD_TO_XPOS(var->nonstd);
ypos = NONSTD_TO_XPOS(var->nonstd); ypos = NONSTD_TO_YPOS(var->nonstd);
pfor = NONSTD_TO_PFOR(var->nonstd); pfor = NONSTD_TO_PFOR(var->nonstd);
ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) | 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,7 +886,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
ofb->id = id; ofb->id = id;
ofb->ops = &ofb_ops[id]; ofb->ops = &ofb_ops[id];
atomic_set(&ofb->usage, 0); ofb->usage = 0;
ofb->fbi = fbi; ofb->fbi = fbi;
init_completion(&ofb->branch_done); init_completion(&ofb->branch_done);
} }
...@@ -904,29 +899,60 @@ static inline int pxafb_overlay_supported(void) ...@@ -904,29 +899,60 @@ static inline int pxafb_overlay_supported(void)
return 0; 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; int i, ret;
if (!pxafb_overlay_supported()) if (!pxafb_overlay_supported())
return 0; return;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
init_pxafb_overlay(fbi, &fbi->overlay[i], i); struct pxafb_layer *ofb = &fbi->overlay[i];
ret = register_framebuffer(&fbi->overlay[i].fb); init_pxafb_overlay(fbi, ofb, i);
ret = register_framebuffer(&ofb->fb);
if (ret) { if (ret) {
dev_err(fbi->dev, "failed to register overlay %d\n", i); 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 */ /* mask all IU/BS/EOF/SOF interrupts */
lcd_writel(fbi, LCCR5, ~0); lcd_writel(fbi, LCCR5, ~0);
/* place overlay(s) on top of base */
fbi->lccr0 |= LCCR0_OUC;
pr_info("PXA Overlay driver loaded successfully!\n"); pr_info("PXA Overlay driver loaded successfully!\n");
return 0;
} }
static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) 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,8 +962,15 @@ static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
if (!pxafb_overlay_supported()) if (!pxafb_overlay_supported())
return; return;
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++) {
unregister_framebuffer(&fbi->overlay[i].fb); 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 #else
static inline void pxafb_overlay_init(struct pxafb_info *fbi) {} 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,7 +1401,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
(lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) || (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
(lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) || (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
(lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) || (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); pxafb_schedule_work(fbi, C_REENABLE);
return 0; return 0;
...@@ -1420,6 +1454,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi) ...@@ -1420,6 +1454,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
lcd_writel(fbi, FDADR0, fbi->fdadr[0]); lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
if (fbi->lccr0 & LCCR0_SDS)
lcd_writel(fbi, FDADR1, fbi->fdadr[1]); lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
} }
...@@ -1613,6 +1648,7 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) ...@@ -1613,6 +1648,7 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
switch (val) { switch (val) {
case CPUFREQ_PRECHANGE: case CPUFREQ_PRECHANGE:
if (!fbi->overlay[0].usage && !fbi->overlay[1].usage)
set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
break; break;
...@@ -1806,6 +1842,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev) ...@@ -1806,6 +1842,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
pxafb_decode_mach_info(fbi, inf); 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_waitqueue_head(&fbi->ctrlr_wait);
INIT_WORK(&fbi->task, pxafb_task); INIT_WORK(&fbi->task, pxafb_task);
mutex_init(&fbi->ctrlr_lock); mutex_init(&fbi->ctrlr_lock);
......
...@@ -92,7 +92,8 @@ struct pxafb_layer_ops { ...@@ -92,7 +92,8 @@ struct pxafb_layer_ops {
struct pxafb_layer { struct pxafb_layer {
struct fb_info fb; struct fb_info fb;
int id; int id;
atomic_t usage; int registered;
uint32_t usage;
uint32_t control[2]; uint32_t control[2];
struct pxafb_layer_ops *ops; struct pxafb_layer_ops *ops;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment