+#define MMC_POLL_RATE msecs_to_jiffies(1000)
+
+static void lubbock_mmc_poll(unsigned long);
+static irq_handler_t mmc_detect_int;
+
+static struct timer_list mmc_timer = {
+ .function = lubbock_mmc_poll,
+};
+
+static void lubbock_mmc_poll(unsigned long data)
+{
+ unsigned long flags;
+
+ /* clear any previous irq state, then ... */
+ local_irq_save(flags);
+ LUB_IRQ_SET_CLR &= ~(1 << 0);
+ local_irq_restore(flags);
+
+ /* poll until mmc/sd card is removed */
+ if (LUB_IRQ_SET_CLR & (1 << 0))
+ mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
+ else {
+ (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data);
+ enable_irq(LUBBOCK_SD_IRQ);
+ }
+}
+
+static irqreturn_t lubbock_detect_int(int irq, void *data)
+{
+ /* IRQ is level triggered; disable, and poll for removal */
+ disable_irq(irq);
+ mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
+
+ return mmc_detect_int(irq, data);
+}
+
+static int lubbock_mci_init(struct device *dev,
+ irq_handler_t detect_int,
+ void *data)
+{
+ /* setup GPIO for PXA25x MMC controller */
+ pxa_gpio_mode(GPIO6_MMCCLK_MD);
+ pxa_gpio_mode(GPIO8_MMCCS0_MD);
+
+ /* detect card insert/eject */
+ mmc_detect_int = detect_int;
+ init_timer(&mmc_timer);
+ mmc_timer.data = (unsigned long) data;
+ return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
+ IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data);
+}
+
+static int lubbock_mci_get_ro(struct device *dev)
+{
+ return (LUB_MISC_RD & (1 << 2)) != 0;
+}
+
+static void lubbock_mci_exit(struct device *dev, void *data)
+{
+ free_irq(LUBBOCK_SD_IRQ, data);
+ del_timer_sync(&mmc_timer);
+}
+
+static struct pxamci_platform_data lubbock_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .detect_delay = 1,
+ .init = lubbock_mci_init,
+ .get_ro = lubbock_mci_get_ro,
+ .exit = lubbock_mci_exit,
+};
+
+static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (mode & IR_SIRMODE) {
+ LUB_MISC_WR &= ~(1 << 4);
+ } else if (mode & IR_FIRMODE) {
+ LUB_MISC_WR |= 1 << 4;
+ }
+ local_irq_restore(flags);
+}
+
+static struct pxaficp_platform_data lubbock_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE,
+ .transceiver_mode = lubbock_irda_transceiver_mode,
+};
+