static int __init multipdp_init(void) { int ret; wake_lock_init(&pdp_wake_lock, WAKE_LOCK_SUSPEND, "MULTI_PDP"); pdp_arg_t pdp_arg = { .id = 1, .ifname = "ttyCSD", }; pdp_arg_t efs_arg = { .id = 8, .ifname = "ttyEFS", }; pdp_arg_t gps_arg = { .id = 5, .ifname = "ttyGPS", }; pdp_arg_t xtra_arg = { .id = 6, .ifname = "ttyXTRA", }; pdp_arg_t smd_arg = { .id = 25, .ifname = "ttySMD", }; pdp_arg_t pcm_arg = { .id = 30, .ifname = "ttyPCM", } ; #ifdef LOOP_BACK_TEST pdp_arg_t loopback_arg = { .id = 31, .ifname = "ttyLOBK", }; #endif /* run DPRAM I/O thread */ ret = kernel_thread(dpram_thread, NULL, CLONE_FS | CLONE_FILES); if (ret < 0) { EPRINTK("kernel_thread() failed\n"); return ret; } wait_for_completion(&dpram_complete); if (!dpram_task) { EPRINTK("DPRAM I/O thread error\n"); return -EIO; } /* create serial device for Circuit Switched Data */ ret = pdp_activate(&pdp_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for CSD\n"); goto err0; } ret = pdp_activate(&efs_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for EFS\n"); goto err1; } ret = pdp_activate(&gps_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for GPS\n"); goto err2; } ret = pdp_activate(&xtra_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for XTRA\n"); goto err3; } ret = pdp_activate(&smd_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for SMD\n"); goto err4; } ret = pdp_activate(&pcm_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for SMD\n"); goto err5; } #ifdef LOOP_BACK_TEST ret = pdp_activate(&loopback_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); if (ret < 0) { EPRINTK("failed to create a serial device for LoopBack\n"); goto err6; } #endif /* create app. interface device */ ret = misc_register(&multipdp_dev); if (ret < 0) { EPRINTK("misc_register() failed\n"); goto err1; } #ifdef LOOP_BACK_TEST ret = device_create_file(multipdp_dev.this_device, &dev_attr_loopback); #endif #ifdef CONFIG_PROC_FS create_proc_read_entry(APP_DEVNAME, 0, 0, multipdp_proc_read, NULL); #endif #ifdef NO_TTY_DPRAM printk("multipdp_init:multipdp_rx_noti_regi calling"); multipdp_rx_noti_regi(multipdp_rx_cback ); #endif // printk(KERN_INFO // "$Id: multipdp.c,v 1.10 2008/01/11 05:40:56 melonzz Exp $\n"); return 0; #ifdef LOOP_BACK_TEST err6: pdp_deactivate(&loopback_arg, 1); #endif err5: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&pcm_arg, 1); err4: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&smd_arg, 1); err3: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&xtra_arg, 1); err2: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&gps_arg, 1); err1: /* undo serial device for Circuit Switched Data */ pdp_deactivate(&pdp_arg, 1); err0: /* kill DPRAM I/O thread */ if (dpram_task) { send_sig(SIGUSR1, dpram_task, 1); wait_for_completion(&dpram_complete); } return ret; } static void __exit multipdp_exit(void) { wake_lock_destroy(&pdp_wake_lock); #ifdef CONFIG_PROC_FS remove_proc_entry(APP_DEVNAME, 0); #endif /* remove app. interface device */ misc_deregister(&multipdp_dev); /* clean up PDP context table */ pdp_cleanup(); /* kill DPRAM I/O thread */ if (dpram_task) { send_sig(SIGUSR1, dpram_task, 1); wait_for_completion(&dpram_complete); } } //module_init(multipdp_init); late_initcall(multipdp_init); module_exit(multipdp_exit); MODULE_AUTHOR("SAMSUNG ELECTRONICS CO., LTD"); MODULE_DESCRIPTION("Multiple PDP Muxer / Demuxer"); MODULE_LICENSE("GPL");
static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { struct tcf_skbmod *d = to_skbmod(a); unsigned char *b = skb_tail_pointer(skb); struct tcf_skbmod_params *p = rtnl_dereference(d->skbmod_p); struct tc_skbmod opt = { .index = d->tcf_index, .refcnt = d->tcf_refcnt - ref, .bindcnt = d->tcf_bindcnt - bind, .action = d->tcf_action, }; struct tcf_t t; opt.flags = p->flags; if (nla_put(skb, TCA_SKBMOD_PARMS, sizeof(opt), &opt)) goto nla_put_failure; if ((p->flags & SKBMOD_F_DMAC) && nla_put(skb, TCA_SKBMOD_DMAC, ETH_ALEN, p->eth_dst)) goto nla_put_failure; if ((p->flags & SKBMOD_F_SMAC) && nla_put(skb, TCA_SKBMOD_SMAC, ETH_ALEN, p->eth_src)) goto nla_put_failure; if ((p->flags & SKBMOD_F_ETYPE) && nla_put_u16(skb, TCA_SKBMOD_ETYPE, ntohs(p->eth_type))) goto nla_put_failure; tcf_tm_dump(&t, &d->tcf_tm); if (nla_put_64bit(skb, TCA_SKBMOD_TM, sizeof(t), &t, TCA_SKBMOD_PAD)) goto nla_put_failure; return skb->len; nla_put_failure: rcu_read_unlock(); nlmsg_trim(skb, b); return -1; } static int tcf_skbmod_walker(struct net *net, struct sk_buff *skb, struct netlink_callback *cb, int type, const struct tc_action_ops *ops) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); return tcf_generic_walker(tn, skb, cb, type, ops); } static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); return tcf_hash_search(tn, a, index); } static struct tc_action_ops act_skbmod_ops = { .kind = "skbmod", .type = TCA_ACT_SKBMOD, .owner = THIS_MODULE, .act = tcf_skbmod_run, .dump = tcf_skbmod_dump, .init = tcf_skbmod_init, .cleanup = tcf_skbmod_cleanup, .walk = tcf_skbmod_walker, .lookup = tcf_skbmod_search, .size = sizeof(struct tcf_skbmod), }; static __net_init int skbmod_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); return tc_action_net_init(tn, &act_skbmod_ops, SKBMOD_TAB_MASK); } static void __net_exit skbmod_exit_net(struct net *net) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); tc_action_net_exit(tn); } static struct pernet_operations skbmod_net_ops = { .init = skbmod_init_net, .exit = skbmod_exit_net, .id = &skbmod_net_id, .size = sizeof(struct tc_action_net), }; MODULE_AUTHOR("Jamal Hadi Salim, <*****@*****.**>"); MODULE_DESCRIPTION("SKB data mod-ing"); MODULE_LICENSE("GPL"); static int __init skbmod_init_module(void) { return tcf_register_action(&act_skbmod_ops, &skbmod_net_ops); } static void __exit skbmod_cleanup_module(void) { tcf_unregister_action(&act_skbmod_ops, &skbmod_net_ops); } module_init(skbmod_init_module); module_exit(skbmod_cleanup_module);
static int choke_dump(struct Qdisc *sch, struct sk_buff *skb) { struct choke_sched_data *q = qdisc_priv(sch); struct nlattr *opts = NULL; struct tc_red_qopt opt = { .limit = q->limit, .flags = q->flags, .qth_min = q->parms.qth_min >> q->parms.Wlog, .qth_max = q->parms.qth_max >> q->parms.Wlog, .Wlog = q->parms.Wlog, .Plog = q->parms.Plog, .Scell_log = q->parms.Scell_log, }; opts = nla_nest_start(skb, TCA_OPTIONS); if (opts == NULL) goto nla_put_failure; if (nla_put(skb, TCA_CHOKE_PARMS, sizeof(opt), &opt) || nla_put_u32(skb, TCA_CHOKE_MAX_P, q->parms.max_P)) goto nla_put_failure; return nla_nest_end(skb, opts); nla_put_failure: nla_nest_cancel(skb, opts); return -EMSGSIZE; } static int choke_dump_stats(struct Qdisc *sch, struct gnet_dump *d) { struct choke_sched_data *q = qdisc_priv(sch); struct tc_choke_xstats st = { .early = q->stats.prob_drop + q->stats.forced_drop, .marked = q->stats.prob_mark + q->stats.forced_mark, .pdrop = q->stats.pdrop, .other = q->stats.other, .matched = q->stats.matched, }; return gnet_stats_copy_app(d, &st, sizeof(st)); } static void choke_destroy(struct Qdisc *sch) { struct choke_sched_data *q = qdisc_priv(sch); tcf_destroy_chain(&q->filter_list); choke_free(q->tab); } static struct Qdisc *choke_leaf(struct Qdisc *sch, unsigned long arg) { return NULL; } static unsigned long choke_get(struct Qdisc *sch, u32 classid) { return 0; } static void choke_put(struct Qdisc *q, unsigned long cl) { } static unsigned long choke_bind(struct Qdisc *sch, unsigned long parent, u32 classid) { return 0; } static struct tcf_proto __rcu **choke_find_tcf(struct Qdisc *sch, unsigned long cl) { struct choke_sched_data *q = qdisc_priv(sch); if (cl) return NULL; return &q->filter_list; } static int choke_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { tcm->tcm_handle |= TC_H_MIN(cl); return 0; } static void choke_walk(struct Qdisc *sch, struct qdisc_walker *arg) { if (!arg->stop) { if (arg->fn(sch, 1, arg) < 0) { arg->stop = 1; return; } arg->count++; } } static const struct Qdisc_class_ops choke_class_ops = { .leaf = choke_leaf, .get = choke_get, .put = choke_put, .tcf_chain = choke_find_tcf, .bind_tcf = choke_bind, .unbind_tcf = choke_put, .dump = choke_dump_class, .walk = choke_walk, }; static struct sk_buff *choke_peek_head(struct Qdisc *sch) { struct choke_sched_data *q = qdisc_priv(sch); return (q->head != q->tail) ? q->tab[q->head] : NULL; } static struct Qdisc_ops choke_qdisc_ops __read_mostly = { .id = "choke", .priv_size = sizeof(struct choke_sched_data), .enqueue = choke_enqueue, .dequeue = choke_dequeue, .peek = choke_peek_head, .drop = choke_drop, .init = choke_init, .destroy = choke_destroy, .reset = choke_reset, .change = choke_change, .dump = choke_dump, .dump_stats = choke_dump_stats, .owner = THIS_MODULE, }; static int __init choke_module_init(void) { return register_qdisc(&choke_qdisc_ops); } static void __exit choke_module_exit(void) { unregister_qdisc(&choke_qdisc_ops); } module_init(choke_module_init) module_exit(choke_module_exit) MODULE_LICENSE("GPL");
static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "SC520", }; switch(cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if(get_user(new_options, p)) return -EFAULT; if(new_options & WDIOS_DISABLECARD) { wdt_turnoff(); retval = 0; } if(new_options & WDIOS_ENABLECARD) { wdt_startup(); retval = 0; } return retval; } case WDIOC_SETTIMEOUT: { int new_timeout; if(get_user(new_timeout, p)) return -EFAULT; if(wdt_set_heartbeat(new_timeout)) return -EINVAL; wdt_keepalive(); /* Fall through */ } case WDIOC_GETTIMEOUT: return put_user(timeout, p); } } static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, .ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &wdt_fops, }; /* * Notifier for system down */ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if(code==SYS_DOWN || code==SYS_HALT) wdt_turnoff(); return NOTIFY_DONE; } /* * The WDT needs to learn about soft shutdowns in order to * turn the timebomb registers off. */ static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; static void __exit sc520_wdt_unload(void) { if (!nowayout) wdt_turnoff(); /* Deregister */ misc_deregister(&wdt_miscdev); unregister_reboot_notifier(&wdt_notifier); iounmap(wdtmrctl); } static int __init sc520_wdt_init(void) { int rc = -EBUSY; spin_lock_init(&wdt_spinlock); init_timer(&timer); timer.function = wdt_timer_ping; timer.data = 0; /* Check that the timeout value is within it's range ; if not reset to the default */ if (wdt_set_heartbeat(timeout)) { wdt_set_heartbeat(WATCHDOG_TIMEOUT); printk(KERN_INFO PFX "timeout value must be 1<=timeout<=3600, using %d\n", WATCHDOG_TIMEOUT); } wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); if (!wdtmrctl) { printk(KERN_ERR PFX "Unable to remap memory\n"); rc = -ENOMEM; goto err_out_region2; } rc = register_reboot_notifier(&wdt_notifier); if (rc) { printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", rc); goto err_out_ioremap; } rc = misc_register(&wdt_miscdev); if (rc) { printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, rc); goto err_out_notifier; } printk(KERN_INFO PFX "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", timeout,nowayout); return 0; err_out_notifier: unregister_reboot_notifier(&wdt_notifier); err_out_ioremap: iounmap(wdtmrctl); err_out_region2: return rc; } module_init(sc520_wdt_init); module_exit(sc520_wdt_unload); MODULE_AUTHOR("Scott and Bill Jennings"); MODULE_DESCRIPTION("Driver for watchdog timer in AMD \"Elan\" SC520 uProcessor"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static int codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) { const struct codel_sched_data *q = qdisc_priv(sch); struct tc_codel_xstats st = { .maxpacket = q->stats.maxpacket, .count = q->vars.count, .lastcount = q->vars.lastcount, .drop_overlimit = q->drop_overlimit, .ldelay = codel_time_to_us(q->vars.ldelay), .dropping = q->vars.dropping, .ecn_mark = q->stats.ecn_mark, }; if (q->vars.dropping) { codel_tdiff_t delta = q->vars.drop_next - codel_get_time(); if (delta >= 0) st.drop_next = codel_time_to_us(delta); else st.drop_next = -codel_time_to_us(-delta); } return gnet_stats_copy_app(d, &st, sizeof(st)); } static void codel_reset(struct Qdisc *sch) { struct codel_sched_data *q = qdisc_priv(sch); qdisc_reset_queue(sch); codel_vars_init(&q->vars); } static struct Qdisc_ops codel_qdisc_ops __read_mostly = { .id = "codel", .priv_size = sizeof(struct codel_sched_data), .enqueue = codel_qdisc_enqueue, .dequeue = codel_qdisc_dequeue, .peek = qdisc_peek_dequeued, .init = codel_init, .reset = codel_reset, .change = codel_change, .dump = codel_dump, .dump_stats = codel_dump_stats, .owner = THIS_MODULE, }; static int __init codel_module_init(void) { return register_qdisc(&codel_qdisc_ops); } static void __exit codel_module_exit(void) { unregister_qdisc(&codel_qdisc_ops); } module_init(codel_module_init) module_exit(codel_module_exit) MODULE_DESCRIPTION("Controlled Delay queue discipline"); MODULE_AUTHOR("Dave Taht"); MODULE_AUTHOR("Eric Dumazet"); MODULE_LICENSE("Dual BSD/GPL");
static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb_tail_pointer(skb); struct tcf_nat *p = a->priv; struct tc_nat opt = { .old_addr = p->old_addr, .new_addr = p->new_addr, .mask = p->mask, .flags = p->flags, .index = p->tcf_index, .action = p->tcf_action, .refcnt = p->tcf_refcnt - ref, .bindcnt = p->tcf_bindcnt - bind, }; struct tcf_t t; if (nla_put(skb, TCA_NAT_PARMS, sizeof(opt), &opt)) goto nla_put_failure; tcf_tm_dump(&t, &p->tcf_tm); if (nla_put_64bit(skb, TCA_NAT_TM, sizeof(t), &t, TCA_NAT_PAD)) goto nla_put_failure; return skb->len; nla_put_failure: nlmsg_trim(skb, b); return -1; } static int tcf_nat_walker(struct net *net, struct sk_buff *skb, struct netlink_callback *cb, int type, struct tc_action *a) { struct tc_action_net *tn = net_generic(net, nat_net_id); return tcf_generic_walker(tn, skb, cb, type, a); } static int tcf_nat_search(struct net *net, struct tc_action *a, u32 index) { struct tc_action_net *tn = net_generic(net, nat_net_id); return tcf_hash_search(tn, a, index); } static struct tc_action_ops act_nat_ops = { .kind = "nat", .type = TCA_ACT_NAT, .owner = THIS_MODULE, .act = tcf_nat, .dump = tcf_nat_dump, .init = tcf_nat_init, .walk = tcf_nat_walker, .lookup = tcf_nat_search, }; static __net_init int nat_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, nat_net_id); return tc_action_net_init(tn, &act_nat_ops, NAT_TAB_MASK); } static void __net_exit nat_exit_net(struct net *net) { struct tc_action_net *tn = net_generic(net, nat_net_id); tc_action_net_exit(tn); } static struct pernet_operations nat_net_ops = { .init = nat_init_net, .exit = nat_exit_net, .id = &nat_net_id, .size = sizeof(struct tc_action_net), }; MODULE_DESCRIPTION("Stateless NAT actions"); MODULE_LICENSE("GPL"); static int __init nat_init_module(void) { return tcf_register_action(&act_nat_ops, &nat_net_ops); } static void __exit nat_cleanup_module(void) { tcf_unregister_action(&act_nat_ops, &nat_net_ops); } module_init(nat_init_module); module_exit(nat_cleanup_module);
static int philips_fmd1216_pll_init(struct dvb_frontend *fe) { struct cx8802_dev *dev= fe->dvb->priv; /* this message is to set up ATC and ALC */ static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; struct i2c_msg msg = { .addr = dev->core->pll_addr, .flags = 0, .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; int err; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { if (err < 0) return err; else return -EREMOTEIO; } return 0; } static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct cx8802_dev *dev= fe->dvb->priv; u8 buf[4]; struct i2c_msg msg = { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; int err; /* Switch PLL to DVB mode */ err = philips_fmd1216_pll_init(fe); if (err) return err; /* Tune PLL */ dvb_pll_configure(dev->core->pll_desc, buf, params->frequency, params->u.ofdm.bandwidth); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { printk(KERN_WARNING "cx88-dvb: %s error " "(addr %02x <- %02x, err = %i)\n", __FUNCTION__, dev->core->pll_addr, buf[0], err); if (err < 0) return err; else return -EREMOTEIO; } return 0; } static struct mt352_config dntv_live_dvbt_pro_config = { .demod_address = 0x0f, .no_tuner = 1, .demod_init = dntv_live_dvbt_pro_demod_init, }; #endif static struct zl10353_config dvico_fusionhdtv_hybrid = { .demod_address = 0x0f, .no_tuner = 1, }; static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { .demod_address = 0x0f, }; static struct cx22702_config connexant_refboard_config = { .demod_address = 0x43, .output_mode = CX22702_SERIAL_OUTPUT, }; static struct cx22702_config hauppauge_hvr_config = { .demod_address = 0x63, .output_mode = CX22702_SERIAL_OUTPUT, }; static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; return 0; } static struct or51132_config pchdtv_hd3000 = { .demod_address = 0x15, .set_ts_params = or51132_set_ts_param, }; static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; dprintk(1, "%s: index = %d\n", __FUNCTION__, index); if (index == 0) cx_clear(MO_GP0_IO, 8); else cx_set(MO_GP0_IO, 8); return 0; } static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; if (is_punctured) dev->ts_gen_cntrl |= 0x04; else dev->ts_gen_cntrl &= ~0x04; return 0; } static struct lgdt330x_config fusionhdtv_3_gold = { .demod_address = 0x0e, .demod_chip = LGDT3302, .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ .set_ts_params = lgdt330x_set_ts_param, }; static struct lgdt330x_config fusionhdtv_5_gold = { .demod_address = 0x0e, .demod_chip = LGDT3303, .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ .set_ts_params = lgdt330x_set_ts_param, }; static struct lgdt330x_config pchdtv_hd5500 = { .demod_address = 0x59, .demod_chip = LGDT3303, .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ .set_ts_params = lgdt330x_set_ts_param, }; static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; return 0; } static int nxt200x_set_pll_input(u8* buf, int input) { if (input) buf[3] |= 0x08; else buf[3] &= ~0x08; return 0; } static struct nxt200x_config ati_hdtvwonder = { .demod_address = 0x0a, .set_pll_input = nxt200x_set_pll_input, .set_ts_params = nxt200x_set_ts_param, }; static int cx24123_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; dev->ts_gen_cntrl = 0x02; return 0; } static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; if (voltage == SEC_VOLTAGE_OFF) cx_write(MO_GP0_IO, 0x000006fb); else cx_write(MO_GP0_IO, 0x000006f9); if (core->prev_set_voltage) return core->prev_set_voltage(fe, voltage); return 0; } static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; if (voltage == SEC_VOLTAGE_OFF) { dprintk(1,"LNB Voltage OFF\n"); cx_write(MO_GP0_IO, 0x0000efff); } if (core->prev_set_voltage) return core->prev_set_voltage(fe, voltage); return 0; } static struct cx24123_config geniatech_dvbs_config = { .demod_address = 0x55, .set_ts_params = cx24123_set_ts_param, }; static struct cx24123_config hauppauge_novas_config = { .demod_address = 0x55, .set_ts_params = cx24123_set_ts_param, }; static struct cx24123_config kworld_dvbs_100_config = { .demod_address = 0x15, .set_ts_params = cx24123_set_ts_param, .lnb_polarity = 1, }; static int dvb_register(struct cx8802_dev *dev) { /* init struct videobuf_dvb */ dev->dvb.name = dev->core->name; dev->ts_gen_cntrl = 0x0c; /* init frontend */ switch (dev->core->board) { case CX88_BOARD_HAUPPAUGE_DVB_T1: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_thomson_dtt759x); } break; case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: case CX88_BOARD_CONEXANT_DVB_T1: case CX88_BOARD_KWORLD_DVB_T_CX22702: case CX88_BOARD_WINFAST_DTV1000: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, &dev->core->i2c_adap, &dvb_pll_thomson_dtt7579); } break; case CX88_BOARD_WINFAST_DTV2000H: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_fmd1216me); } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, &dvb_pll_thomson_dtt7579); break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, &dvb_pll_thomson_dtt7579); } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: /* The tin box says DEE1601, but it seems to be DTT7579 * compatible, with a slightly different MT352 AGC gain. */ dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_dual, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_thomson_dtt7579); break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_thomson_dtt7579); } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_lg_z201); } break; case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_ADSTECH_DVB_T_PCI: dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_unknown_1); } break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #ifdef HAVE_VP3054_I2C dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_fmd1216me; dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, &((struct vp3054_i2c_state *)dev->card_priv)->adap); if (dev->dvb.frontend != NULL) { dev->dvb.frontend->ops.tuner_ops.set_params = dntv_live_dvbt_pro_tuner_set_params; } #else printk("%s: built without vp3054 support\n", dev->core->name); #endif break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_hybrid, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_thomson_fe6600); } break; case CX88_BOARD_PCHDTV_HD3000: dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_thomson_dtt761x); } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); /* Select RF connector callback */ fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_microtune_4042); } } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 9); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_thomson_dtt761x); } } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_gold, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(lgh06xf_attach, dev->dvb.frontend, &dev->core->i2c_adap); } } break; case CX88_BOARD_PCHDTV_HD5500: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &pchdtv_hd5500, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(lgh06xf_attach, dev->dvb.frontend, &dev->core->i2c_adap); } } break; case CX88_BOARD_ATI_HDTVWONDER: dev->dvb.frontend = dvb_attach(nxt200x_attach, &ati_hdtvwonder, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_tuv1236d); } break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: dev->dvb.frontend = dvb_attach(cx24123_attach, &hauppauge_novas_config, &dev->core->i2c_adap); if (dev->dvb.frontend) { dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->core->i2c_adap, 0x08, 0x00, 0x00); } break; case CX88_BOARD_KWORLD_DVBS_100: dev->dvb.frontend = dvb_attach(cx24123_attach, &kworld_dvbs_100_config, &dev->core->i2c_adap); if (dev->dvb.frontend) { dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; } break; case CX88_BOARD_GENIATECH_DVBS: dev->dvb.frontend = dvb_attach(cx24123_attach, &geniatech_dvbs_config, &dev->core->i2c_adap); if (dev->dvb.frontend) { dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; } break; case CX88_BOARD_HAUPPAUGE_HVR1300: dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_fmd1216me); } break; case CX88_BOARD_HAUPPAUGE_HVR3000: dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_fmd1216me); } break; default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->core->name); break; } if (NULL == dev->dvb.frontend) { printk("%s: frontend initialization failed\n",dev->core->name); return -1; } if (dev->core->pll_desc) { dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min; dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max; } /* Ensure all frontends negotiate bus access */ dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; /* Put the analog decoder in standby to keep it quiet */ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); /* register everything */ return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); } /* ----------------------------------------------------------- */ /* CX8802 MPEG -> mini driver - We have been given the hardware */ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __FUNCTION__); switch (core->board) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* We arrive here with either the cx23416 or the cx22702 * on the bus. Take the bus from the cx23416 and enable the * cx22702 demod */ cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */ cx_clear(MO_GP0_IO, 0x00000004); udelay(1000); break; default: err = -ENODEV; } return err; } /* CX8802 MPEG -> mini driver - We no longer have the hardware */ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __FUNCTION__); switch (core->board) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* Do Nothing, leave the cx22702 on the bus. */ break; default: err = -ENODEV; } return err; } static int cx8802_dvb_probe(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; int err; dprintk( 1, "%s\n", __FUNCTION__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", core->board, core->name, core->pci_bus, core->pci_slot); err = -ENODEV; if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB)) goto fail_core; #ifdef HAVE_VP3054_I2C err = vp3054_i2c_probe(dev); if (0 != err) goto fail_core; #endif /* dvb stuff */ printk("%s/2: cx2388x based dvb card\n", core->name); videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, dev->pci, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx88_buffer), dev); err = dvb_register(dev); if (err != 0) printk("%s dvb_register failed err = %d\n", __FUNCTION__, err); fail_core: return err; } static int cx8802_dvb_remove(struct cx8802_driver *drv) { struct cx8802_dev *dev = drv->core->dvbdev; /* dvb */ videobuf_dvb_unregister(&dev->dvb); #ifdef HAVE_VP3054_I2C vp3054_i2c_remove(dev); #endif return 0; } static struct cx8802_driver cx8802_dvb_driver = { .type_id = CX88_MPEG_DVB, .hw_access = CX8802_DRVCTL_SHARED, .probe = cx8802_dvb_probe, .remove = cx8802_dvb_remove, .advise_acquire = cx8802_dvb_advise_acquire, .advise_release = cx8802_dvb_advise_release, }; static int dvb_init(void) { printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n", (CX88_VERSION_CODE >> 16) & 0xff, (CX88_VERSION_CODE >> 8) & 0xff, CX88_VERSION_CODE & 0xff); #ifdef SNAPSHOT printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif return cx8802_register_driver(&cx8802_dvb_driver); } static void dvb_fini(void) { cx8802_unregister_driver(&cx8802_dvb_driver); } module_init(dvb_init); module_exit(dvb_fini);
static int vfe_probe(struct platform_device *pdev) { struct vfe_device *vfe_dev; /*struct msm_cam_subdev_info sd_info;*/ const struct of_device_id *match_dev; int rc = 0; struct msm_iova_partition vfe_partition = { .start = SZ_128K, .size = SZ_2G - SZ_128K, }; struct msm_iova_layout vfe_layout = { .partitions = &vfe_partition, .npartitions = 1, .client_name = "vfe", .domain_flags = 0, }; vfe_dev = kzalloc(sizeof(struct vfe_device), GFP_KERNEL); if (!vfe_dev) { pr_err("%s: no enough memory\n", __func__); rc = -ENOMEM; goto end; } if (pdev->dev.of_node) { of_property_read_u32((&pdev->dev)->of_node, "cell-index", &pdev->id); match_dev = of_match_device(msm_vfe_dt_match, &pdev->dev); if (!match_dev) { pr_err("%s: No vfe hardware info\n", __func__); rc = -EINVAL; goto probe_fail; } vfe_dev->hw_info = (struct msm_vfe_hardware_info *) match_dev->data; } else { vfe_dev->hw_info = (struct msm_vfe_hardware_info *) platform_get_device_id(pdev)->driver_data; } if (!vfe_dev->hw_info) { pr_err("%s: No vfe hardware info\n", __func__); rc = -EINVAL; goto probe_fail; } ISP_DBG("%s: device id = %d\n", __func__, pdev->id); vfe_dev->pdev = pdev; rc = vfe_dev->hw_info->vfe_ops.core_ops.get_platform_data(vfe_dev); if (rc < 0) { pr_err("%s: failed to get platform resources\n", __func__); rc = -ENOMEM; goto probe_fail; } INIT_LIST_HEAD(&vfe_dev->tasklet_q); tasklet_init(&vfe_dev->vfe_tasklet, msm_isp_do_tasklet, (unsigned long)vfe_dev); v4l2_subdev_init(&vfe_dev->subdev.sd, vfe_dev->hw_info->subdev_ops); vfe_dev->subdev.sd.internal_ops = vfe_dev->hw_info->subdev_internal_ops; snprintf(vfe_dev->subdev.sd.name, ARRAY_SIZE(vfe_dev->subdev.sd.name), "vfe"); vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS; v4l2_set_subdevdata(&vfe_dev->subdev.sd, vfe_dev); platform_set_drvdata(pdev, &vfe_dev->subdev.sd); mutex_init(&vfe_dev->realtime_mutex); mutex_init(&vfe_dev->core_mutex); spin_lock_init(&vfe_dev->tasklet_lock); spin_lock_init(&vfe_dev->shared_data_lock); media_entity_init(&vfe_dev->subdev.sd.entity, 0, NULL, 0); vfe_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE; vfe_dev->subdev.sd.entity.name = pdev->name; vfe_dev->subdev.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x2; rc = msm_sd_register(&vfe_dev->subdev); if (rc != 0) { pr_err("%s: msm_sd_register error = %d\n", __func__, rc); goto probe_fail; } vfe_dev->buf_mgr = &vfe_buf_mgr; v4l2_subdev_notify(&vfe_dev->subdev.sd, MSM_SD_NOTIFY_REQ_CB, &vfe_vb2_ops); rc = msm_isp_create_isp_buf_mgr(vfe_dev->buf_mgr, &vfe_vb2_ops, &vfe_layout); if (rc < 0) { pr_err("%s: Unable to create buffer manager\n", __func__); rc = -EINVAL; goto probe_fail; } /* create secure context banks*/ if (vfe_dev->hw_info->num_iommu_secure_ctx) { /*secure vfe layout*/ struct msm_iova_layout vfe_secure_layout = { .partitions = &vfe_partition, .npartitions = 1, .client_name = "vfe_secure", .domain_flags = 0, .is_secure = MSM_IOMMU_DOMAIN_SECURE, }; rc = msm_isp_create_secure_domain(vfe_dev->buf_mgr, &vfe_secure_layout); if (rc < 0) { pr_err("%s: fail to create secure domain\n", __func__); msm_sd_unregister(&vfe_dev->subdev); rc = -EINVAL; goto probe_fail; } } vfe_dev->buf_mgr->ops->register_ctx(vfe_dev->buf_mgr, &vfe_dev->iommu_ctx[0], &vfe_dev->iommu_secure_ctx[0], vfe_dev->hw_info->num_iommu_ctx, vfe_dev->hw_info->num_iommu_secure_ctx); vfe_dev->buf_mgr->init_done = 1; vfe_dev->vfe_open_cnt = 0; return rc; probe_fail: kfree(vfe_dev); end: return rc; } static struct platform_driver vfe_driver = { .probe = vfe_probe, .driver = { .name = "msm_vfe", .owner = THIS_MODULE, .of_match_table = msm_vfe_dt_match, }, .id_table = msm_vfe_dev_id, }; static int __init msm_vfe_init_module(void) { return platform_driver_register(&vfe_driver); } static void __exit msm_vfe_exit_module(void) { platform_driver_unregister(&vfe_driver); } module_init(msm_vfe_init_module); module_exit(msm_vfe_exit_module); MODULE_DESCRIPTION("MSM VFE driver"); MODULE_LICENSE("GPL v2");
int __init usb_mdc800_init (void) { /* Allocate Memory */ try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL)); memset(mdc800, 0, sizeof(struct mdc800_data)); mdc800->dev=0; mdc800->open=0; mdc800->state=NOT_CONNECTED; spin_lock_init (&mdc800->io_lock); init_waitqueue_head (&mdc800->irq_wait); init_waitqueue_head (&mdc800->write_wait); init_waitqueue_head (&mdc800->download_wait); try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL)); try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL)); try (mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL)); try (mdc800->irq_urb=usb_alloc_urb (0)); try (mdc800->download_urb=usb_alloc_urb (0)); try (mdc800->write_urb=usb_alloc_urb (0)); /* Register the driver */ if (usb_register (&mdc800_usb_driver) < 0) goto cleanup_on_fail; info ("Mustek Digital Camera Driver " VERSION " (MDC800)"); info (RELEASE_DATE " Henning Zabel <*****@*****.**>"); return 0; /* Clean driver up, when something fails */ cleanup_on_fail: if (mdc800 != 0) { err ("can't alloc memory!"); try_free_mem (mdc800->download_urb_buffer); try_free_mem (mdc800->write_urb_buffer); try_free_mem (mdc800->irq_urb_buffer); try_free_urb (mdc800->write_urb); try_free_urb (mdc800->download_urb); try_free_urb (mdc800->irq_urb); kfree (mdc800); } mdc800=0; return -1; } void __exit usb_mdc800_cleanup (void) { usb_deregister (&mdc800_usb_driver); usb_free_urb (mdc800->irq_urb); usb_free_urb (mdc800->download_urb); usb_free_urb (mdc800->write_urb); kfree (mdc800->irq_urb_buffer); kfree (mdc800->write_urb_buffer); kfree (mdc800->download_urb_buffer); kfree (mdc800); mdc800=0; } MODULE_AUTHOR ("Henning Zabel <*****@*****.**>"); MODULE_DESCRIPTION ("USB Driver for Mustek MDC800 Digital Camera"); module_init (usb_mdc800_init); module_exit (usb_mdc800_cleanup);
/* Try to route the packet according to the routing keys specified in * route_info. Keys are : * - ifindex : * 0 if no oif preferred, * otherwise set to the index of the desired oif * - route_info->gw : * 0 if no gateway specified, * otherwise set to the next host to which the pkt must be routed * If success, skb->dev is the output device to which the packet must * be sent and skb->dst is not NULL * * RETURN: -1 if an error occured * 1 if the packet was succesfully routed to the * destination desired * 0 if the kernel routing table could not route the packet * according to the keys specified */ static int route(struct sk_buff *skb, unsigned int ifindex, const struct ipt_route_target_info *route_info) { int err; struct rtable *rt; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) struct iphdr *iph = ip_hdr(skb); #else struct iphdr *iph = skb->nh.iph; #endif struct flowi fl = { .oif = ifindex, .nl_u = { .ip4_u = { .daddr = iph->daddr, .saddr = 0, .tos = RT_TOS(iph->tos), .scope = RT_SCOPE_UNIVERSE, } } }; /* The destination address may be overloaded by the target */ if (route_info->gw) fl.fl4_dst = route_info->gw; /* Trying to route the packet using the standard routing table. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) if ((err = ip_route_output_key(&init_net, &rt, &fl))) { #else if ((err = ip_route_output_key(&rt, &fl))) { #endif if (net_ratelimit()) DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err); return -1; } /* Drop old route. */ dst_release(skb->dst); skb->dst = NULL; /* Success if no oif specified or if the oif correspond to the * one desired */ if (!ifindex || rt->u.dst.dev->ifindex == ifindex) { skb->dst = &rt->u.dst; skb->dev = skb->dst->dev; skb->protocol = htons(ETH_P_IP); return 1; } /* The interface selected by the routing table is not the one * specified by the user. This may happen because the dst address * is one of our own addresses. */ if (net_ratelimit()) DEBUGP("ipt_ROUTE: failed to route as desired gw=%u.%u.%u.%u oif=%i (got oif=%i)\n", NIPQUAD(route_info->gw), ifindex, rt->u.dst.dev->ifindex); return 0; } /* Stolen from ip_finish_output2 * PRE : skb->dev is set to the device we are leaving by * skb->dst is not NULL * POST: the packet is sent with the link layer header pushed * the packet is destroyed */ static void ip_direct_send(struct sk_buff *skb) { struct dst_entry *dst = skb->dst; struct hh_cache *hh = dst->hh; struct net_device *dev = dst->dev; int hh_len = LL_RESERVED_SPACE(dev); unsigned seq; /* Be paranoid, rather than too clever. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { #else if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) { #endif struct sk_buff *skb2; skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev)); if (skb2 == NULL) { kfree_skb(skb); return; } if (skb->sk) skb_set_owner_w(skb2, skb->sk); kfree_skb(skb); skb = skb2; } if (hh) { do { int hh_alen; seq = read_seqbegin(&hh->hh_lock); hh_alen = HH_DATA_ALIGN(hh->hh_len); memcpy(skb->data - hh_alen, hh->hh_data, hh_alen); } while (read_seqretry(&hh->hh_lock, seq)); skb_push(skb, hh->hh_len); hh->hh_output(skb); } else if (dst->neighbour) dst->neighbour->output(skb); else { if (net_ratelimit()) DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n"); kfree_skb(skb); } } /* PRE : skb->dev is set to the device we are leaving by * POST: - the packet is directly sent to the skb->dev device, without * pushing the link layer header. * - the packet is destroyed */ static inline int dev_direct_send(struct sk_buff *skb) { return dev_queue_xmit(skb); } static unsigned int route_oif(const struct ipt_route_target_info *route_info, struct sk_buff *skb) { unsigned int ifindex = 0; struct net_device *dev_out = NULL; /* The user set the interface name to use. * Getting the current interface index. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) if ((dev_out = dev_get_by_name(&init_net, route_info->oif))) { #else if ((dev_out = dev_get_by_name(route_info->oif))) { #endif ifindex = dev_out->ifindex; } else { /* Unknown interface name : packet dropped */ if (net_ratelimit()) DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif); return NF_DROP; } /* Trying the standard way of routing packets */ switch (route(skb, ifindex, route_info)) { case 1: dev_put(dev_out); if (route_info->flags & IPT_ROUTE_CONTINUE) return IPT_CONTINUE; ip_direct_send(skb); return NF_STOLEN; case 0: /* Failed to send to oif. Trying the hard way */ if (route_info->flags & IPT_ROUTE_CONTINUE) return NF_DROP; if (net_ratelimit()) DEBUGP("ipt_ROUTE: forcing the use of %i\n", ifindex); /* We have to force the use of an interface. * This interface must be a tunnel interface since * otherwise we can't guess the hw address for * the packet. For a tunnel interface, no hw address * is needed. */ if ((dev_out->type != ARPHRD_TUNNEL) && (dev_out->type != ARPHRD_IPGRE)) { if (net_ratelimit()) DEBUGP("ipt_ROUTE: can't guess the hw addr !\n"); dev_put(dev_out); return NF_DROP; } /* Send the packet. This will also free skb * Do not go through the POST_ROUTING hook because * skb->dst is not set and because it will probably * get confused by the destination IP address. */ skb->dev = dev_out; dev_direct_send(skb); dev_put(dev_out); return NF_STOLEN; default: /* Unexpected error */ dev_put(dev_out); return NF_DROP; } } static unsigned int route_iif(const struct ipt_route_target_info *route_info, struct sk_buff *skb) { struct net_device *dev_in = NULL; /* Getting the current interface index. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) if (!(dev_in = dev_get_by_name(&init_net, route_info->iif))) { #else if (!(dev_in = dev_get_by_name(route_info->iif))) { #endif if (net_ratelimit()) DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->iif); return NF_DROP; } skb->dev = dev_in; dst_release(skb->dst); skb->dst = NULL; netif_rx(skb); dev_put(dev_in); return NF_STOLEN; } static unsigned int route_gw(const struct ipt_route_target_info *route_info, struct sk_buff *skb) { if (route(skb, 0, route_info)!=1) return NF_DROP; if (route_info->flags & IPT_ROUTE_CONTINUE) return IPT_CONTINUE; ip_direct_send(skb); return NF_STOLEN; } /* To detect and deter routed packet loopback when using the --tee option, * we take a page out of the raw.patch book: on the copied skb, we set up * a fake ->nfct entry, pointing to the local &route_tee_track. We skip * routing packets when we see they already have that ->nfct. */ static struct nf_conn route_tee_track; static unsigned int #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, const void *targinfo, void *userinfo) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, const void *targinfo, void *userinfo) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, const struct xt_target *target, const void *targinfo, void *userinfo) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, const struct xt_target *target, const void *targinfo) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) target(struct sk_buff *skb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, const struct xt_target *target, const void *targinfo) #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) */ target(struct sk_buff *skb, const struct xt_target_param *par) #endif { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) const struct ipt_route_target_info *route_info = targinfo; #else const struct ipt_route_target_info *route_info = par->targinfo; unsigned int hooknum = par->hooknum; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) struct sk_buff *skb = *pskb; #endif unsigned int res; if (skb->nfct == &route_tee_track.ct_general) { /* Loopback - a packet we already routed, is to be * routed another time. Avoid that, now. */ if (net_ratelimit()) DEBUGP(KERN_DEBUG "ipt_ROUTE: loopback - DROP!\n"); return NF_DROP; } /* If we are at PREROUTING or INPUT hook * the TTL isn't decreased by the IP stack */ if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_IN) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) struct iphdr *iph = ip_hdr(skb); #else struct iphdr *iph = skb->nh.iph; #endif if (iph->ttl <= 1) { struct rtable *rt; struct flowi fl = { .oif = 0, .nl_u = { .ip4_u = { .daddr = iph->daddr, .saddr = iph->saddr, .tos = RT_TOS(iph->tos), .scope = ((iph->tos & RTO_ONLINK) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE) } } }; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) if (ip_route_output_key(&init_net, &rt, &fl)) { #else if (ip_route_output_key(&rt, &fl)) { #endif return NF_DROP; } if (skb->dev == rt->u.dst.dev) { /* Drop old route. */ dst_release(skb->dst); skb->dst = &rt->u.dst; /* this will traverse normal stack, and * thus call conntrack on the icmp packet */ icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); } return NF_DROP; } /* * If we are at INPUT the checksum must be recalculated since * the length could change as the result of a defragmentation. */ if(hooknum == NF_INET_LOCAL_IN) { iph->ttl = iph->ttl - 1; iph->check = 0; iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); } else { ip_decrease_ttl(iph); } } if ((route_info->flags & IPT_ROUTE_TEE)) { /* * Copy the skb, and route the copy. Will later return * IPT_CONTINUE for the original skb, which should continue * on its way as if nothing happened. The copy should be * independantly delivered to the ROUTE --gw. */ skb = skb_copy(skb, GFP_ATOMIC); if (!skb) { if (net_ratelimit()) DEBUGP(KERN_DEBUG "ipt_ROUTE: copy failed!\n"); return IPT_CONTINUE; } } /* Tell conntrack to forget this packet since it may get confused * when a packet is leaving with dst address == our address. * Good idea ? Dunno. Need advice. * * NEW: mark the skb with our &route_tee_track, so we avoid looping * on any already routed packet. */ if (!(route_info->flags & IPT_ROUTE_CONTINUE)) { nf_conntrack_put(skb->nfct); skb->nfct = &route_tee_track.ct_general; skb->nfctinfo = IP_CT_NEW; nf_conntrack_get(skb->nfct); } if (route_info->oif[0] != '\0') { res = route_oif(route_info, skb); } else if (route_info->iif[0] != '\0') { res = route_iif(route_info, skb); } else if (route_info->gw) { res = route_gw(route_info, skb); } else { if (net_ratelimit()) DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n"); res = IPT_CONTINUE; } if ((route_info->flags & IPT_ROUTE_TEE)) res = IPT_CONTINUE; return res; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) static int checkentry(const char *tablename, const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) static int checkentry(const char *tablename, const void *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static int checkentry(const char *tablename, const void *e, const struct xt_target *target, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) static int checkentry(const char *tablename, const void *e, const struct xt_target *target, void *targinfo, unsigned int hook_mask) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) static bool checkentry(const char *tablename, const void *e, const struct xt_target *target, void *targinfo, unsigned int hook_mask) #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) */ static bool checkentry(const struct xt_tgchk_param *par) #endif { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) const char *tablename = par->table; unsigned int hook_mask = par->hook_mask; #endif if (strcmp(tablename, "mangle") != 0) { printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n", tablename); return 0; } if (hook_mask & ~( (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) | (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_POST_ROUTING))) { printk("ipt_ROUTE: bad hook\n"); return 0; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) if (targinfosize != IPT_ALIGN(sizeof(struct ipt_route_target_info))) { printk(KERN_WARNING "ipt_ROUTE: targinfosize %u != %Zu\n", targinfosize, IPT_ALIGN(sizeof(struct ipt_route_target_info))); return 0; } #endif return 1; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) static struct ipt_target xt_route_reg = { #else static struct ipt_target ipt_route_reg = { #endif .name = "ROUTE", #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) .family = AF_INET, #endif .target = target, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) .targetsize = sizeof(struct ipt_route_target_info), #endif .checkentry = checkentry, .me = THIS_MODULE, }; static int __init init(void) { /* Set up fake conntrack (stolen from raw.patch): - to never be deleted, not in any hashes */ atomic_set(&route_tee_track.ct_general.use, 1); /* - and look it like as a confirmed connection */ set_bit(IPS_CONFIRMED_BIT, &route_tee_track.status); /* Initialize fake conntrack so that NAT will skip it */ route_tee_track.status |= IPS_NAT_DONE_MASK; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) return xt_register_target(&xt_route_reg); #else return ipt_register_target(&ipt_route_reg); #endif } static void __exit fini(void) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) xt_unregister_target(&xt_route_reg); #else ipt_unregister_target(&ipt_route_reg); #endif } module_init(init); module_exit(fini);
static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb_tail_pointer(skb); struct tcf_csum *p = to_tcf_csum(a); struct tc_csum opt = { .update_flags = p->update_flags, .index = p->tcf_index, .action = p->tcf_action, .refcnt = p->tcf_refcnt - ref, .bindcnt = p->tcf_bindcnt - bind, }; struct tcf_t t; if (nla_put(skb, TCA_CSUM_PARMS, sizeof(opt), &opt)) goto nla_put_failure; tcf_tm_dump(&t, &p->tcf_tm); if (nla_put_64bit(skb, TCA_CSUM_TM, sizeof(t), &t, TCA_CSUM_PAD)) goto nla_put_failure; return skb->len; nla_put_failure: nlmsg_trim(skb, b); return -1; } static int tcf_csum_walker(struct net *net, struct sk_buff *skb, struct netlink_callback *cb, int type, const struct tc_action_ops *ops) { struct tc_action_net *tn = net_generic(net, csum_net_id); return tcf_generic_walker(tn, skb, cb, type, ops); } static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, csum_net_id); return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_csum_ops = { .kind = "csum", .type = TCA_ACT_CSUM, .owner = THIS_MODULE, .act = tcf_csum, .dump = tcf_csum_dump, .init = tcf_csum_init, .walk = tcf_csum_walker, .lookup = tcf_csum_search, .size = sizeof(struct tcf_csum), }; static __net_init int csum_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, csum_net_id); return tc_action_net_init(tn, &act_csum_ops); } static void __net_exit csum_exit_net(struct net *net) { struct tc_action_net *tn = net_generic(net, csum_net_id); tc_action_net_exit(tn); } static struct pernet_operations csum_net_ops = { .init = csum_init_net, .exit = csum_exit_net, .id = &csum_net_id, .size = sizeof(struct tc_action_net), }; MODULE_DESCRIPTION("Checksum updating actions"); MODULE_LICENSE("GPL"); static int __init csum_init_module(void) { return tcf_register_action(&act_csum_ops, &csum_net_ops); } static void __exit csum_cleanup_module(void) { tcf_unregister_action(&act_csum_ops, &csum_net_ops); } module_init(csum_init_module); module_exit(csum_cleanup_module);
static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x07, .port_ops = &cs5530_port_ops }; /* The docking connector doesn't do UDMA, and it seems not MWDMA */ static const struct ata_port_info info_palmax_secondary = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .port_ops = &cs5530_port_ops }; const struct ata_port_info *ppi[] = { &info, NULL }; int rc; rc = pcim_enable_device(pdev); if (rc) return rc; /* Chip initialisation */ if (cs5530_init_chip()) return -ENODEV; if (cs5530_is_palmax()) ppi[1] = &info_palmax_secondary; /* Now kick off ATA set up */ return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL); } #ifdef CONFIG_PM static int cs5530_reinit_one(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); int rc; rc = ata_pci_device_do_resume(pdev); if (rc) return rc; /* If we fail on resume we are doomed */ if (cs5530_init_chip()) return -EIO; ata_host_resume(host); return 0; } #endif /* CONFIG_PM */ static const struct pci_device_id cs5530[] = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), }, { }, }; static struct pci_driver cs5530_pci_driver = { .name = DRV_NAME, .id_table = cs5530, .probe = cs5530_init_one, .remove = ata_pci_remove_one, #ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = cs5530_reinit_one, #endif }; static int __init cs5530_init(void) { return pci_register_driver(&cs5530_pci_driver); } static void __exit cs5530_exit(void) { pci_unregister_driver(&cs5530_pci_driver); } MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, cs5530); MODULE_VERSION(DRV_VERSION); module_init(cs5530_init); module_exit(cs5530_exit);
static int omap_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int new_margin; static struct watchdog_info ident = { .identity = "OMAP Watchdog", .options = WDIOF_SETTIMEOUT, .firmware_version = 0, }; switch (cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: return copy_to_user((struct watchdog_info __user *)arg, &ident, sizeof(ident)); case WDIOC_GETSTATUS: return put_user(0, (int __user *)arg); case WDIOC_GETBOOTSTATUS: if (cpu_is_omap16xx()) return put_user(omap_readw(ARM_SYSST), (int __user *)arg); if (cpu_is_omap24xx()) return put_user(omap_prcm_get_reset_sources(), (int __user *)arg); case WDIOC_KEEPALIVE: omap_wdt_ping(); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_margin, (int __user *)arg)) return -EFAULT; omap_wdt_adjust_timeout(new_margin); omap_wdt_disable(); omap_wdt_set_timeout(); omap_wdt_enable(); omap_wdt_ping(); /* Fall */ case WDIOC_GETTIMEOUT: return put_user(timer_margin, (int __user *)arg); } } static const struct file_operations omap_wdt_fops = { .owner = THIS_MODULE, .write = omap_wdt_write, .ioctl = omap_wdt_ioctl, .open = omap_wdt_open, .release = omap_wdt_release, }; static struct miscdevice omap_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &omap_wdt_fops }; static int __init omap_wdt_probe(struct platform_device *pdev) { struct resource *res, *mem; int ret; /* reserve static register mappings */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; mem = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if (mem == NULL) return -EBUSY; platform_set_drvdata(pdev, mem); omap_wdt_users = 0; if (cpu_is_omap16xx()) { armwdt_ck = clk_get(&pdev->dev, "armwdt_ck"); if (IS_ERR(armwdt_ck)) { ret = PTR_ERR(armwdt_ck); armwdt_ck = NULL; goto fail; } } if (cpu_is_omap24xx()) { mpu_wdt_ick = clk_get(&pdev->dev, "mpu_wdt_ick"); if (IS_ERR(mpu_wdt_ick)) { ret = PTR_ERR(mpu_wdt_ick); mpu_wdt_ick = NULL; goto fail; } mpu_wdt_fck = clk_get(&pdev->dev, "mpu_wdt_fck"); if (IS_ERR(mpu_wdt_fck)) { ret = PTR_ERR(mpu_wdt_fck); mpu_wdt_fck = NULL; goto fail; } } omap_wdt_disable(); omap_wdt_adjust_timeout(timer_margin); omap_wdt_miscdev.parent = &pdev->dev; ret = misc_register(&omap_wdt_miscdev); if (ret) goto fail; pr_info("OMAP Watchdog Timer: initial timeout %d sec\n", timer_margin); /* autogate OCP interface clock */ omap_writel(0x01, OMAP_WATCHDOG_SYS_CONFIG); return 0; fail: if (armwdt_ck) clk_put(armwdt_ck); if (mpu_wdt_ick) clk_put(mpu_wdt_ick); if (mpu_wdt_fck) clk_put(mpu_wdt_fck); release_resource(mem); return ret; } static void omap_wdt_shutdown(struct platform_device *pdev) { omap_wdt_disable(); } static int omap_wdt_remove(struct platform_device *pdev) { struct resource *mem = platform_get_drvdata(pdev); misc_deregister(&omap_wdt_miscdev); release_resource(mem); if (armwdt_ck) clk_put(armwdt_ck); if (mpu_wdt_ick) clk_put(mpu_wdt_ick); if (mpu_wdt_fck) clk_put(mpu_wdt_fck); return 0; } #ifdef CONFIG_PM /* REVISIT ... not clear this is the best way to handle system suspend; and * it's very inappropriate for selective device suspend (e.g. suspending this * through sysfs rather than by stopping the watchdog daemon). Also, this * may not play well enough with NOWAYOUT... */ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state) { if (omap_wdt_users) omap_wdt_disable(); return 0; } static int omap_wdt_resume(struct platform_device *pdev) { if (omap_wdt_users) { omap_wdt_enable(); omap_wdt_ping(); } return 0; } #else #define omap_wdt_suspend NULL #define omap_wdt_resume NULL #endif static struct platform_driver omap_wdt_driver = { .probe = omap_wdt_probe, .remove = omap_wdt_remove, .shutdown = omap_wdt_shutdown, .suspend = omap_wdt_suspend, .resume = omap_wdt_resume, .driver = { .owner = THIS_MODULE, .name = "omap_wdt", }, }; static int __init omap_wdt_init(void) { return platform_driver_register(&omap_wdt_driver); } static void __exit omap_wdt_exit(void) { platform_driver_unregister(&omap_wdt_driver); } module_init(omap_wdt_init); module_exit(omap_wdt_exit); MODULE_AUTHOR("George G. Davis"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "Acquire WDT", }; switch(cmd) { case WDIOC_GETSUPPORT: return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: acq_ping(); return 0; case WDIOC_GETTIMEOUT: return put_user(WATCHDOG_TIMEOUT, (int *)arg); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; if (get_user(options, (int *)arg)) return -EFAULT; if (options & WDIOS_DISABLECARD) { acq_stop(); retval = 0; } if (options & WDIOS_ENABLECARD) { acq_ping(); retval = 0; } return retval; } default: return -ENOIOCTLCMD; } } static int acq_open(struct inode *inode, struct file *file) { if (test_and_set_bit(0, &acq_is_open)) return -EBUSY; if (nowayout) __module_get(THIS_MODULE); /* Activate */ acq_ping(); return 0; } static int acq_close(struct inode *inode, struct file *file) { if (expect_close == 42) { acq_stop(); } else { printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); acq_ping(); } clear_bit(0, &acq_is_open); expect_close = 0; return 0; } /* * Notifier for system down */ static int acq_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if(code==SYS_DOWN || code==SYS_HALT) { /* Turn the WDT off */ acq_stop(); } return NOTIFY_DONE; } /* * Kernel Interfaces */ static struct file_operations acq_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = acq_write, .ioctl = acq_ioctl, .open = acq_open, .release = acq_close, }; static struct miscdevice acq_miscdev= { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &acq_fops, }; /* * The WDT card needs to learn about soft shutdowns in order to * turn the timebomb registers off. */ static struct notifier_block acq_notifier = { .notifier_call = acq_notify_sys, .next = NULL, .priority = 0, }; static int __init acq_init(void) { int ret; printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); if (wdt_stop != wdt_start) { if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", wdt_stop); ret = -EIO; goto out; } } if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", wdt_start); ret = -EIO; goto unreg_stop; } ret = register_reboot_notifier(&acq_notifier); if (ret != 0) { printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); goto unreg_regions; } ret = misc_register(&acq_miscdev); if (ret != 0) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto unreg_reboot; } printk (KERN_INFO PFX "initialized. (nowayout=%d)\n", nowayout); out: return ret; unreg_reboot: unregister_reboot_notifier(&acq_notifier); unreg_regions: release_region(wdt_start, 1); unreg_stop: if (wdt_stop != wdt_start) release_region(wdt_stop, 1); goto out; } static void __exit acq_exit(void) { misc_deregister(&acq_miscdev); unregister_reboot_notifier(&acq_notifier); if(wdt_stop != wdt_start) release_region(wdt_stop,1); release_region(wdt_start,1); } module_init(acq_init); module_exit(acq_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Unkown"); MODULE_DESCRIPTION("Acquire Single Board Computer Watchdog Timer driver");
int register_dvb(struct tm6000_core *dev) { int ret = -1; struct tm6000_dvb *dvb = dev->dvb; mutex_init(&dvb->mutex); dvb->streams = 0; /* attach the frontend */ ret = tm6000_dvb_attach_frontend(dev); if (ret < 0) { printk(KERN_ERR "tm6000: couldn't attach the frontend!\n"); goto err; } ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T", THIS_MODULE, &dev->udev->dev, adapter_nr); dvb->adapter.priv = dev; if (dvb->frontend) { switch (dev->tuner_type) { case TUNER_XC2028: { struct xc2028_config cfg = { .i2c_adap = &dev->i2c_adap, .i2c_addr = dev->tuner_addr, }; dvb->frontend->callback = tm6000_tuner_callback; ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); if (ret < 0) { printk(KERN_ERR "tm6000: couldn't register frontend\n"); goto adapter_err; } if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { printk(KERN_ERR "tm6000: couldn't register " "frontend (xc3028)\n"); ret = -EINVAL; goto frontend_err; } printk(KERN_INFO "tm6000: XC2028/3028 asked to be " "attached to frontend!\n"); break; } case TUNER_XC5000: { struct xc5000_config cfg = { .i2c_address = dev->tuner_addr, }; dvb->frontend->callback = tm6000_xc5000_callback; ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); if (ret < 0) { printk(KERN_ERR "tm6000: couldn't register frontend\n"); goto adapter_err; } if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) { printk(KERN_ERR "tm6000: couldn't register " "frontend (xc5000)\n"); ret = -EINVAL; goto frontend_err; } printk(KERN_INFO "tm6000: XC5000 asked to be " "attached to frontend!\n"); break; } } } else printk(KERN_ERR "tm6000: no frontend found\n"); dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING; dvb->demux.priv = dev; dvb->demux.filternum = 8; dvb->demux.feednum = 8; dvb->demux.start_feed = tm6000_start_feed; dvb->demux.stop_feed = tm6000_stop_feed; dvb->demux.write_to_decoder = NULL; ret = dvb_dmx_init(&dvb->demux); if (ret < 0) { printk("tm6000: dvb_dmx_init failed (errno = %d)\n", ret); goto frontend_err; } dvb->dmxdev.filternum = dev->dvb->demux.filternum; dvb->dmxdev.demux = &dev->dvb->demux.dmx; dvb->dmxdev.capabilities = 0; ret = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); if (ret < 0) { printk("tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret); goto dvb_dmx_err; } return 0; dvb_dmx_err: dvb_dmx_release(&dvb->demux); frontend_err: if (dvb->frontend) { dvb_frontend_detach(dvb->frontend); dvb_unregister_frontend(dvb->frontend); } adapter_err: dvb_unregister_adapter(&dvb->adapter); err: return ret; } void unregister_dvb(struct tm6000_core *dev) { struct tm6000_dvb *dvb = dev->dvb; if (dvb->bulk_urb != NULL) { struct urb *bulk_urb = dvb->bulk_urb; kfree(bulk_urb->transfer_buffer); bulk_urb->transfer_buffer = NULL; usb_unlink_urb(bulk_urb); usb_free_urb(bulk_urb); } /* mutex_lock(&tm6000_driver.open_close_mutex); */ if (dvb->frontend) { dvb_frontend_detach(dvb->frontend); dvb_unregister_frontend(dvb->frontend); } dvb_dmxdev_release(&dvb->dmxdev); dvb_dmx_release(&dvb->demux); dvb_unregister_adapter(&dvb->adapter); mutex_destroy(&dvb->mutex); /* mutex_unlock(&tm6000_driver.open_close_mutex); */ } static int dvb_init(struct tm6000_core *dev) { struct tm6000_dvb *dvb; int rc; if (!dev) return 0; if (!dev->caps.has_dvb) return 0; dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL); if (!dvb) { printk(KERN_INFO "Cannot allocate memory\n"); return -ENOMEM; } dev->dvb = dvb; rc = register_dvb(dev); if (rc < 0) { kfree(dvb); dev->dvb = NULL; return 0; } return 0; } static int dvb_fini(struct tm6000_core *dev) { if (!dev) return 0; if (!dev->caps.has_dvb) return 0; if (dev->dvb) { unregister_dvb(dev); kfree(dev->dvb); dev->dvb = NULL; } return 0; } static struct tm6000_ops dvb_ops = { .type = TM6000_DVB, .name = "TM6000 dvb Extension", .init = dvb_init, .fini = dvb_fini, }; static int __init tm6000_dvb_register(void) { return tm6000_register_extension(&dvb_ops); } static void __exit tm6000_dvb_unregister(void) { tm6000_unregister_extension(&dvb_ops); } module_init(tm6000_dvb_register); module_exit(tm6000_dvb_unregister);
static int __devinit sec_nfc_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; #else static int __devinit sec_nfc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; #endif struct sec_nfc_info *info; struct sec_nfc_platform_data *pdata = dev->platform_data; int ret = 0; if (!pdata) { dev_err(dev, "No platform data\n"); ret = -ENOMEM; goto err_pdata; } info = kzalloc(sizeof(struct sec_nfc_info), GFP_KERNEL); if (!info) { dev_err(dev, "failed to allocate memory for sec_nfc_info\n"); ret = -ENOMEM; goto err_info_alloc; } info->dev = dev; info->pdata = pdata; info->state = SEC_NFC_ST_OFF; mutex_init(&info->mutex); dev_set_drvdata(dev, info); #ifdef CONFIG_SEC_NFC_I2C info->buflen = SEC_NFC_MAX_BUFFER_SIZE; info->buf = kzalloc(SEC_NFC_MAX_BUFFER_SIZE, GFP_KERNEL); if (!info->buf) { dev_err(dev, "failed to allocate memory for sec_nfc_info->buf\n"); ret = -ENOMEM; goto err_buf_alloc; } /* pdata->cfg_gpio(); */ ret = gpio_request(pdata->irq, "nfc_int"); if (ret) { dev_err(dev, "[NFC] GPIO request is failed to register IRQ\n"); goto err_irq_req; } info->i2c_dev = client; info->read_irq = SEC_NFC_NONE; mutex_init(&info->read_mutex); init_waitqueue_head(&info->read_wait); i2c_set_clientdata(client, info); dev_info(dev, "%s : requesting IRQ %d\n", __func__, client->irq); /* ret = request_threaded_irq(pdata->irq, NULL, sec_nfc_irq_thread_fn, */ ret = request_threaded_irq(client->irq, NULL, sec_nfc_irq_thread_fn, IRQF_TRIGGER_RISING | IRQF_ONESHOT, SEC_NFC_DRIVER_NAME, info); /* ret = request_irq(client->irq, sec_nfc_irq_thread_fn, IRQF_TRIGGER_RISING, SEC_NFC_DRIVER_NAME, info); */ if (ret < 0) { dev_err(dev, "failed to register IRQ handler\n"); goto err_irq_req; } #endif info->miscdev.minor = MISC_DYNAMIC_MINOR; info->miscdev.name = SEC_NFC_DRIVER_NAME; info->miscdev.fops = &sec_nfc_fops; info->miscdev.parent = dev; ret = misc_register(&info->miscdev); if (ret < 0) { dev_err(dev, "failed to register Device\n"); goto err_dev_reg; } ret = gpio_request(pdata->ven, "nfc_ven"); if (ret) { dev_err(dev, "failed to get gpio ven\n"); goto err_gpio_ven; } ret = gpio_request(pdata->firm, "nfc_firm"); if (ret) { dev_err(dev, "failed to get gpio firm\n"); goto err_gpio_firm; } gpio_direction_output(pdata->ven, 0); gpio_direction_output(pdata->firm, 0); if (info->pdata->power_onoff) info->pdata->power_onoff(1); else pr_info("%s : no power control function\n", __func__); dev_dbg(dev, "%s: info: %p, pdata %p\n", __func__, info, pdata); return 0; err_gpio_firm: gpio_free(pdata->firm); err_gpio_ven: gpio_free(pdata->ven); err_dev_reg: #ifdef CONFIG_SEC_NFC_I2C err_irq_req: gpio_free(pdata->irq); err_buf_alloc: #endif err_info_alloc: kfree(info); err_pdata: return ret; } #ifdef CONFIG_SEC_NFC_I2C static int __devexit sec_nfc_remove(struct i2c_client *client) { struct sec_nfc_info *info = i2c_get_clientdata(client); struct sec_nfc_platform_data *pdata = client->dev.platform_data; #else static int __devexit sec_nfc_remove(struct platform_device *pdev) { struct sec_nfc_info *info = dev_get_drvdata(&pdev->dev); struct sec_nfc_platform_data *pdata = pdev->dev.platform_data; #endif dev_dbg(info->dev, "%s\n", __func__); misc_deregister(&info->miscdev); if (info->state != SEC_NFC_ST_OFF) { gpio_set_value(pdata->firm, 0); gpio_set_value(pdata->ven, 0); } gpio_free(pdata->firm); gpio_free(pdata->ven); #ifdef CONFIG_SEC_NFC_I2C free_irq(pdata->irq, info); #endif kfree(info); return 0; } #ifdef CONFIG_SEC_NFC_I2C static struct i2c_device_id sec_nfc_id_table[] = { #else /* CONFIG_SEC_NFC_I2C */ static struct platform_device_id sec_nfc_id_table[] = { #endif { SEC_NFC_DRIVER_NAME, 0 }, { } }; #ifdef CONFIG_SEC_NFC_I2C MODULE_DEVICE_TABLE(i2c, sec_nfc_id_table); static struct i2c_driver sec_nfc_driver = { #else MODULE_DEVICE_TABLE(platform, sec_nfc_id_table); static struct platform_driver sec_nfc_driver = { #endif .probe = sec_nfc_probe, .id_table = sec_nfc_id_table, .remove = sec_nfc_remove, .driver = { .name = SEC_NFC_DRIVER_NAME, #ifdef CONFIG_PM .pm = &sec_nfc_pm_ops, #endif }, }; static int __init sec_nfc_init(void) { #ifdef CONFIG_SEC_NFC_I2C return i2c_add_driver(&sec_nfc_driver); #else return platform_driver_register(&sec_nfc_driver); #endif } static void __exit sec_nfc_exit(void) { #ifdef CONFIG_SEC_NFC_I2C i2c_del_driver(&sec_nfc_driver); #else platform_driver_unregister(&sec_nfc_driver); #endif } module_init(sec_nfc_init); module_exit(sec_nfc_exit); MODULE_DESCRIPTION("Samsung sec_nfc driver"); MODULE_LICENSE("GPL");
static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA5, .port_ops = &marvell_ops, }; static const struct ata_port_info info_sata = { /* Slave possible as its magically mapped not real */ .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA6, .port_ops = &marvell_ops, }; const struct ata_port_info *ppi[] = { &info, &info_sata }; if (pdev->device == 0x6101) ppi[1] = &ata_dummy_port_info; return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL); } static const struct pci_device_id marvell_pci_tbl[] = { { PCI_DEVICE(0x11AB, 0x6101), }, { PCI_DEVICE(0x11AB, 0x6121), }, { PCI_DEVICE(0x11AB, 0x6123), }, { PCI_DEVICE(0x11AB, 0x6145), }, { } /* terminate list */ }; static struct pci_driver marvell_pci_driver = { .name = DRV_NAME, .id_table = marvell_pci_tbl, .probe = marvell_init_one, .remove = ata_pci_remove_one, #ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, #endif }; static int __init marvell_init(void) { return pci_register_driver(&marvell_pci_driver); } static void __exit marvell_exit(void) { pci_unregister_driver(&marvell_pci_driver); } module_init(marvell_init); module_exit(marvell_exit); MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("SCSI low-level driver for Marvell ATA in legacy mode"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, marvell_pci_tbl); MODULE_VERSION(DRV_VERSION);
static int asr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .identity = "IBM ASR" }; void __user *argp = (void __user *)arg; int __user *p = argp; int heartbeat; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: asr_toggle(); return 0; /* * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT * and WDIOC_GETTIMEOUT always returns 256. */ case WDIOC_GETTIMEOUT: heartbeat = 256; return put_user(heartbeat, p); case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { asr_disable(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { asr_enable(); asr_toggle(); retval = 0; } return retval; } } return -ENOIOCTLCMD; } static int asr_open(struct inode *inode, struct file *file) { if(test_and_set_bit(0, &asr_is_open)) return -EBUSY; asr_toggle(); asr_enable(); return nonseekable_open(inode, file); } static int asr_release(struct inode *inode, struct file *file) { if (asr_expect_close == 42) asr_disable(); else { printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); asr_toggle(); } clear_bit(0, &asr_is_open); asr_expect_close = 0; return 0; } static struct file_operations asr_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = asr_write, .ioctl = asr_ioctl, .open = asr_open, .release = asr_release, }; static struct miscdevice asr_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &asr_fops, }; struct ibmasr_id { const char *desc; int type; }; static struct ibmasr_id __initdata ibmasr_id_table[] = { { "IBM Automatic Server Restart - eserver xSeries 220", ASMTYPE_TOPAZ }, { "IBM Automatic Server Restart - Machine Type 8673", ASMTYPE_PEARL }, { "IBM Automatic Server Restart - Machine Type 8480", ASMTYPE_JASPER }, { "IBM Automatic Server Restart - Machine Type 8482", ASMTYPE_JUNIPER }, { "IBM Automatic Server Restart - Machine Type 8648", ASMTYPE_SPRUCE }, { NULL } }; static int __init ibmasr_init(void) { struct ibmasr_id *id; int rc; for (id = ibmasr_id_table; id->desc; id++) { if (dmi_find_device(DMI_DEV_TYPE_OTHER, id->desc, NULL)) { asr_type = id->type; break; } } if (!asr_type) return -ENODEV; rc = misc_register(&asr_miscdev); if (rc < 0) { printk(KERN_ERR PFX "failed to register misc device\n"); return rc; } rc = asr_get_base_address(); if (rc) { misc_deregister(&asr_miscdev); return rc; } return 0; } static void __exit ibmasr_exit(void) { if (!nowayout) asr_disable(); misc_deregister(&asr_miscdev); release_region(asr_base, asr_length); } module_init(ibmasr_init); module_exit(ibmasr_exit); module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); MODULE_AUTHOR("Andrey Panin"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int timeout; static struct watchdog_info info = { .options = WDIOF_KEEPALIVEPING, .firmware_version = 0, .identity = "MPC8xx watchdog", }; switch (cmd) { case WDIOC_GETSUPPORT: if (copy_to_user((void *)arg, &info, sizeof(info))) return -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: if (put_user(wdt_status, (int *)arg)) return -EFAULT; wdt_status &= ~WDIOF_KEEPALIVEPING; break; case WDIOC_GETTEMP: return -EOPNOTSUPP; case WDIOC_SETOPTIONS: return -EOPNOTSUPP; case WDIOC_KEEPALIVE: m8xx_wdt_reset(); wdt_status |= WDIOF_KEEPALIVEPING; break; case WDIOC_SETTIMEOUT: return -EOPNOTSUPP; case WDIOC_GETTIMEOUT: timeout = m8xx_wdt_get_timeout(); if (put_user(timeout, (int *)arg)) return -EFAULT; break; default: return -ENOIOCTLCMD; } return 0; } static const struct file_operations mpc8xx_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = mpc8xx_wdt_write, .ioctl = mpc8xx_wdt_ioctl, .open = mpc8xx_wdt_open, .release = mpc8xx_wdt_release, }; static struct miscdevice mpc8xx_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &mpc8xx_wdt_fops, }; static int __init mpc8xx_wdt_init(void) { return misc_register(&mpc8xx_wdt_miscdev); } static void __exit mpc8xx_wdt_exit(void) { misc_deregister(&mpc8xx_wdt_miscdev); m8xx_wdt_reset(); mpc8xx_wdt_handler_enable(); } module_init(mpc8xx_wdt_init); module_exit(mpc8xx_wdt_exit); MODULE_AUTHOR("Florian Schirmer <*****@*****.**>"); MODULE_DESCRIPTION("MPC8xx watchdog driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static int attach_xc3028(u8 addr, struct cx8802_dev *dev) { struct dvb_frontend *fe; struct xc2028_ctrl ctl; struct xc2028_config cfg = { .i2c_adap = &dev->core->i2c_adap, .i2c_addr = addr, .ctrl = &ctl, .callback = cx88_tuner_callback, }; if (!dev->dvb.frontend) { printk(KERN_ERR "%s/2: dvb frontend not attached. " "Can't attach xc3028\n", dev->core->name); return -EINVAL; } /* * Some xc3028 devices may be hidden by an I2C gate. This is known * to happen with some s5h1409-based devices. * Now that I2C gate is open, sets up xc3028 configuration */ cx88_setup_xc3028(dev->core, &ctl); fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); if (!fe) { printk(KERN_ERR "%s/2: xc3028 attach failed\n", dev->core->name); return -EINVAL; } printk(KERN_INFO "%s/2: xc3028 attached\n", dev->core->name); return 0; } static int dvb_register(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; /* init struct videobuf_dvb */ dev->dvb.name = core->name; dev->ts_gen_cntrl = 0x0c; /* init frontend */ switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_DVB_T1: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &core->i2c_adap, DVB_PLL_THOMSON_DTT759X)) goto frontend_detach; } break; case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: case CX88_BOARD_CONEXANT_DVB_T1: case CX88_BOARD_KWORLD_DVB_T_CX22702: case CX88_BOARD_WINFAST_DTV1000: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, &core->i2c_adap, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_WINFAST_DTV2000H: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: case CX88_BOARD_HAUPPAUGE_HVR1300: case CX88_BOARD_HAUPPAUGE_HVR3000: dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: /* The tin box says DEE1601, but it seems to be DTT7579 * compatible, with a slightly different MT352 AGC gain. */ dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_dual, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_LG_Z201)) goto frontend_detach; } break; case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_ADSTECH_DVB_T_PCI: dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_UNKNOWN_1)) goto frontend_detach; } break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) /* MT352 is on a secondary I2C bus made from some GPIO lines */ dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, &dev->vp3054->adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) goto frontend_detach; } #else printk(KERN_ERR "%s/2: built without vp3054 support\n", core->name); #endif break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_hybrid, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_FE6600)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &core->i2c_adap); if (dev->dvb.frontend == NULL) dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_mt352_xc3028, &core->i2c_adap); /* * On this board, the demod provides the I2C bus pullup. * We must not permit gate_ctrl to be performed, or * the xc3028 cannot communicate on the bus. */ if (dev->dvb.frontend) dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; if (attach_xc3028(0x61, dev) < 0) return -EINVAL; break; case CX88_BOARD_PCHDTV_HD3000: dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); /* Select RF connector callback */ fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_MICROTUNE_4042FI5)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 9); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_gold, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; if (!dvb_attach(tda9887_attach, dev->dvb.frontend, &core->i2c_adap, 0x43)) goto frontend_detach; } break; case CX88_BOARD_PCHDTV_HD5500: dev->ts_gen_cntrl = 0x08; /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &pchdtv_hd5500, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF)) goto frontend_detach; if (!dvb_attach(tda9887_attach, dev->dvb.frontend, &core->i2c_adap, 0x43)) goto frontend_detach; } break; case CX88_BOARD_ATI_HDTVWONDER: dev->dvb.frontend = dvb_attach(nxt200x_attach, &ati_hdtvwonder, &core->i2c_adap); if (dev->dvb.frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, &core->i2c_adap, 0x61, TUNER_PHILIPS_TUV1236D)) goto frontend_detach; } break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: dev->dvb.frontend = dvb_attach(cx24123_attach, &hauppauge_novas_config, &core->i2c_adap); if (dev->dvb.frontend) { if (!dvb_attach(isl6421_attach, dev->dvb.frontend, &core->i2c_adap, 0x08, 0x00, 0x00)) goto frontend_detach; } break; case CX88_BOARD_KWORLD_DVBS_100: dev->dvb.frontend = dvb_attach(cx24123_attach, &kworld_dvbs_100_config, &core->i2c_adap); if (dev->dvb.frontend) { core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; } break; case CX88_BOARD_GENIATECH_DVBS: dev->dvb.frontend = dvb_attach(cx24123_attach, &geniatech_dvbs_config, &core->i2c_adap); if (dev->dvb.frontend) { core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; } break; case CX88_BOARD_PINNACLE_PCTV_HD_800i: dev->dvb.frontend = dvb_attach(s5h1409_attach, &pinnacle_pctv_hd_800i_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { /* tuner_config.video_dev must point to * i2c_adap.algo_data */ if (!dvb_attach(xc5000_attach, dev->dvb.frontend, &core->i2c_adap, &pinnacle_pctv_hd_800i_tuner_config, core->i2c_adap.algo_data)) goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: dev->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_hdtv5_pci_nano_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { .i2c_adap = &core->i2c_adap, .i2c_addr = 0x61, .callback = cx88_pci_nano_callback, }; static struct xc2028_ctrl ctl = { .fname = "xc3028-v27.fw", .max_len = 64, .scode_table = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) fe->ops.tuner_ops.set_config(fe, &ctl); } break; case CX88_BOARD_PINNACLE_HYBRID_PCTV: dev->dvb.frontend = dvb_attach(zl10353_attach, &cx88_geniatech_x8000_mt, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_GENIATECH_X8000_MT: dev->ts_gen_cntrl = 0x00; dev->dvb.frontend = dvb_attach(zl10353_attach, &cx88_geniatech_x8000_mt, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_KWORLD_ATSC_120: dev->dvb.frontend = dvb_attach(s5h1409_attach, &kworld_atsc_120_config, &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) goto frontend_detach; break; case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: dev->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_fusionhdtv7_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { /* tuner_config.video_dev must point to * i2c_adap.algo_data */ if (!dvb_attach(xc5000_attach, dev->dvb.frontend, &core->i2c_adap, &dvico_fusionhdtv7_tuner_config, core->i2c_adap.algo_data)) goto frontend_detach; } break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", core->name); break; } if (NULL == dev->dvb.frontend) { printk(KERN_ERR "%s/2: frontend initialization failed\n", core->name); return -EINVAL; } /* Ensure all frontends negotiate bus access */ dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; /* Put the analog decoder in standby to keep it quiet */ cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL); /* register everything */ return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, adapter_nr); frontend_detach: if (dev->dvb.frontend) { dvb_frontend_detach(dev->dvb.frontend); dev->dvb.frontend = NULL; } return -EINVAL; } /* ----------------------------------------------------------- */ /* CX8802 MPEG -> mini driver - We have been given the hardware */ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* We arrive here with either the cx23416 or the cx22702 * on the bus. Take the bus from the cx23416 and enable the * cx22702 demod */ cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */ cx_clear(MO_GP0_IO, 0x00000004); udelay(1000); break; default: err = -ENODEV; } return err; } /* CX8802 MPEG -> mini driver - We no longer have the hardware */ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* Do Nothing, leave the cx22702 on the bus. */ break; default: err = -ENODEV; } return err; } static int cx8802_dvb_probe(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; int err; dprintk( 1, "%s\n", __func__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", core->boardnr, core->name, core->pci_bus, core->pci_slot); err = -ENODEV; if (!(core->board.mpeg & CX88_MPEG_DVB)) goto fail_core; /* If vp3054 isn't enabled, a stub will just return 0 */ err = vp3054_i2c_probe(dev); if (0 != err) goto fail_core; /* dvb stuff */ printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx88_buffer), dev); err = dvb_register(dev); if (err != 0) printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", core->name, err); fail_core: return err; } static int cx8802_dvb_remove(struct cx8802_driver *drv) { struct cx8802_dev *dev = drv->core->dvbdev; /* dvb */ if (dev->dvb.frontend) videobuf_dvb_unregister(&dev->dvb); vp3054_i2c_remove(dev); return 0; } static struct cx8802_driver cx8802_dvb_driver = { .type_id = CX88_MPEG_DVB, .hw_access = CX8802_DRVCTL_SHARED, .probe = cx8802_dvb_probe, .remove = cx8802_dvb_remove, .advise_acquire = cx8802_dvb_advise_acquire, .advise_release = cx8802_dvb_advise_release, }; static int dvb_init(void) { printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n", (CX88_VERSION_CODE >> 16) & 0xff, (CX88_VERSION_CODE >> 8) & 0xff, CX88_VERSION_CODE & 0xff); #ifdef SNAPSHOT printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif return cx8802_register_driver(&cx8802_dvb_driver); } static void dvb_fini(void) { cx8802_unregister_driver(&cx8802_dvb_driver); } module_init(dvb_init); module_exit(dvb_fini);
static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) { struct gred_sched *table = qdisc_priv(sch); struct nlattr *parms, *opts = NULL; int i; struct tc_gred_sopt sopt = { .DPs = table->DPs, .def_DP = table->def, .grio = gred_rio_mode(table), .flags = table->red_flags, }; opts = nla_nest_start(skb, TCA_OPTIONS); if (opts == NULL) goto nla_put_failure; NLA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt); parms = nla_nest_start(skb, TCA_GRED_PARMS); if (parms == NULL) goto nla_put_failure; for (i = 0; i < MAX_DPs; i++) { struct gred_sched_data *q = table->tab[i]; struct tc_gred_qopt opt; memset(&opt, 0, sizeof(opt)); if (!q) { /* hack -- fix at some point with proper message This is how we indicate to tc that there is no VQ at this DP */ opt.DP = MAX_DPs + i; goto append_opt; } opt.limit = q->limit; opt.DP = q->DP; opt.backlog = q->backlog; opt.prio = q->prio; opt.qth_min = q->parms.qth_min >> q->parms.Wlog; opt.qth_max = q->parms.qth_max >> q->parms.Wlog; opt.Wlog = q->parms.Wlog; opt.Plog = q->parms.Plog; opt.Scell_log = q->parms.Scell_log; opt.other = q->stats.other; opt.early = q->stats.prob_drop; opt.forced = q->stats.forced_drop; opt.pdrop = q->stats.pdrop; opt.packets = q->packetsin; opt.bytesin = q->bytesin; if (gred_wred_mode(table)) { q->parms.qidlestart = table->tab[table->def]->parms.qidlestart; q->parms.qavg = table->tab[table->def]->parms.qavg; } opt.qave = red_calc_qavg(&q->parms, q->parms.qavg); append_opt: if (nla_append(skb, sizeof(opt), &opt) < 0) goto nla_put_failure; } nla_nest_end(skb, parms); return nla_nest_end(skb, opts); nla_put_failure: nla_nest_cancel(skb, opts); return -EMSGSIZE; } static void gred_destroy(struct Qdisc *sch) { struct gred_sched *table = qdisc_priv(sch); int i; for (i = 0; i < table->DPs; i++) { if (table->tab[i]) gred_destroy_vq(table->tab[i]); } } static struct Qdisc_ops gred_qdisc_ops __read_mostly = { .id = "gred", .priv_size = sizeof(struct gred_sched), .enqueue = gred_enqueue, .dequeue = gred_dequeue, .peek = qdisc_peek_head, .drop = gred_drop, .init = gred_init, .reset = gred_reset, .destroy = gred_destroy, .change = gred_change, .dump = gred_dump, .owner = THIS_MODULE, }; static int __init gred_module_init(void) { return register_qdisc(&gred_qdisc_ops); } static void __exit gred_module_exit(void) { unregister_qdisc(&gred_qdisc_ops); } module_init(gred_module_init) module_exit(gred_module_exit) MODULE_LICENSE("GPL");
static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb_tail_pointer(skb); struct tcf_gact *gact = a->priv; struct tcf_t t; struct tc_gact opt = { .index = gact->tcf_index, .refcnt = gact->tcf_refcnt - ref, .bindcnt = gact->tcf_bindcnt - bind, .action = gact->tcf_action, }; NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt); #ifdef CONFIG_GACT_PROB if (gact->tcfg_ptype) { struct tc_gact_p p_opt = { .paction = gact->tcfg_paction, .pval = gact->tcfg_pval, .ptype = gact->tcfg_ptype, }; NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt); } #endif t.install = jiffies_to_clock_t(jiffies - gact->tcf_tm.install); t.lastuse = jiffies_to_clock_t(jiffies - gact->tcf_tm.lastuse); t.expires = jiffies_to_clock_t(gact->tcf_tm.expires); NLA_PUT(skb, TCA_GACT_TM, sizeof(t), &t); return skb->len; nla_put_failure: nlmsg_trim(skb, b); return -1; } static struct tc_action_ops act_gact_ops = { .kind = "gact", .hinfo = &gact_hash_info, .type = TCA_ACT_GACT, .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_gact, .dump = tcf_gact_dump, .cleanup = tcf_gact_cleanup, .lookup = tcf_hash_search, .init = tcf_gact_init, .walk = tcf_generic_walker }; MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); MODULE_DESCRIPTION("Generic Classifier actions"); MODULE_LICENSE("GPL"); static int __init gact_init_module(void) { #ifdef CONFIG_GACT_PROB printk("GACT probability on\n"); #else printk("GACT probability NOT on\n"); #endif return tcf_register_action(&act_gact_ops); } static void __exit gact_cleanup_module(void) { tcf_unregister_action(&act_gact_ops); } module_init(gact_init_module); module_exit(gact_cleanup_module);
static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) { const struct pm8xxx_keypad_platform_data *pdata = dev_get_platdata(&pdev->dev); const struct matrix_keymap_data *keymap_data; struct pmic8xxx_kp *kp; int rc; u8 ctrl_val; struct device *sec_key; struct pm_gpio kypd_drv = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_LOW, .function = PM_GPIO_FUNC_1, .inv_int_pol = 1, }; struct pm_gpio kypd_sns = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_UP_31P5, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_NO, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 1, }; if (!pdata || !pdata->num_cols || !pdata->num_rows || pdata->num_cols > PM8XXX_MAX_COLS || pdata->num_rows > PM8XXX_MAX_ROWS || pdata->num_cols < PM8XXX_MIN_COLS) { dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } if (!pdata->scan_delay_ms || pdata->scan_delay_ms > MAX_SCAN_DELAY || pdata->scan_delay_ms < MIN_SCAN_DELAY || !is_power_of_2(pdata->scan_delay_ms)) { dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); return -EINVAL; } if (!pdata->row_hold_ns || pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); return -EINVAL; } if (!pdata->debounce_ms || ((pdata->debounce_ms % 5) != 0) || pdata->debounce_ms > MAX_DEBOUNCE_TIME || pdata->debounce_ms < MIN_DEBOUNCE_TIME) { dev_err(&pdev->dev, "invalid debounce time supplied\n"); return -EINVAL; } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data supplied\n"); return -EINVAL; } kp = kzalloc(sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; platform_set_drvdata(pdev, kp); kp->pdata = pdata; kp->dev = &pdev->dev; kp->input = input_allocate_device(); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); rc = -ENOMEM; goto err_alloc_device; } kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); rc = -ENXIO; goto err_get_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); rc = -ENXIO; goto err_get_irq; } kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; kp->input->dev.parent = &pdev->dev; kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; kp->input->id.vendor = 0x0001; kp->input->evbit[0] = BIT_MASK(EV_KEY); if (pdata->rep) __set_bit(EV_REP, kp->input->evbit); kp->input->keycode = kp->keycodes; kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; kp->input->keycodesize = sizeof(kp->keycodes); kp->input->open = pmic8xxx_kp_open; kp->input->close = pmic8xxx_kp_close; matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, kp->input->keycode, kp->input->keybit); get_volumekey_matrix(keymap_data, &volup_matrix, &voldown_matrix); input_set_capability(kp->input, EV_MSC, MSC_SCAN); input_set_drvdata(kp->input, kp); /* initialize keypad state */ memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); rc = pmic8xxx_kpd_init(kp); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); goto err_get_irq; } rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, pdata->num_cols, kp, &kypd_sns); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); goto err_gpio_config; } rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, pdata->num_rows, kp, &kypd_drv); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); goto err_gpio_config; } rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); goto err_get_irq; } rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); goto err_req_stuck_irq; } rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); goto err_pmic_reg_read; } rc = request_threaded_irq(MSM_GPIO_KEY_VOLUP_IRQ , NULL, pmic8058_volume_up_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "vol_up", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request vol_up irq\n"); goto err_req_sense_irq; } rc = request_threaded_irq(MSM_GPIO_KEY_VOLDOWN_IRQ , NULL, pmic8058_volume_down_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "vol_down", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request vol_down irq\n"); goto err_req_sense_irq; } kp->ctrl_reg = ctrl_val; #if defined CONFIG_MACH_VITAL2REFRESH gpio_tlmm_config(GPIO_CFG(MSM_HALL_IC, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); input_set_capability(kp->input, EV_SW, SW_LID); if (gpio_get_value(MSM_HALL_IC)) { input_report_switch(kp->input, SW_LID, 1); } else { input_report_switch(kp->input, SW_LID, 0); } input_sync(kp->input); printk(KERN_INFO "[input_report_switch] slide_int - !gpio_hall_ic %s\n", gpio_get_value(MSM_HALL_IC) == 0 ? "OPEN" : "CLOSE"); rc = request_threaded_irq(MSM_GPIO_TO_INT(MSM_HALL_IC), NULL, hall_ic_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "hall_ic", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request hall_ic irq\n"); goto err_hall_ic_irq; } #endif rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); goto err_pmic_reg_read; } sec_key = device_create(sec_class, NULL, 0, NULL, "sec_key"); if (IS_ERR(sec_key)) pr_err("Failed to create device(sec_key)!\n"); rc = device_create_file(sec_key, &dev_attr_sec_key_pressed); if (rc) { pr_err("Failed to create device file - pressed(%s), err(%d)!\n", dev_attr_sec_key_pressed.attr.name, rc); } dev_set_drvdata(sec_key, kp); device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; err_pmic_reg_read: free_irq(kp->key_stuck_irq, kp); err_req_stuck_irq: free_irq(kp->key_sense_irq, kp); #if defined CONFIG_MACH_VITAL2REFRESH err_hall_ic_irq: #endif err_req_sense_irq: err_gpio_config: err_get_irq: input_free_device(kp->input); err_alloc_device: platform_set_drvdata(pdev, NULL); kfree(kp); return rc; } static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) { struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); device_init_wakeup(&pdev->dev, 0); free_irq(kp->key_stuck_irq, kp); free_irq(kp->key_sense_irq, kp); input_unregister_device(kp->input); kfree(kp); platform_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM_SLEEP static int pmic8xxx_kp_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { enable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); #if defined CONFIG_MACH_VITAL2REFRESH enable_irq_wake(MSM_GPIO_TO_INT(MSM_HALL_IC)); /* to wakeup in case of sleep */ #endif if (input_dev->users) pmic8xxx_kp_disable(kp); mutex_unlock(&input_dev->mutex); } return 0; } static int pmic8xxx_kp_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { disable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); #if defined CONFIG_MACH_VITAL2REFRESH disable_irq_wake(MSM_GPIO_TO_INT(MSM_HALL_IC)); /* to match irq pair */ #endif if (input_dev->users) pmic8xxx_kp_enable(kp); mutex_unlock(&input_dev->mutex); } return 0; } #endif static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, pmic8xxx_kp_suspend, pmic8xxx_kp_resume); static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, .remove = __devexit_p(pmic8xxx_kp_remove), .driver = { .name = PM8XXX_KEYPAD_DEV_NAME, .owner = THIS_MODULE, .pm = &pm8xxx_kp_pm_ops, }, }; static int __init pmic8xxx_kp_init(void) { return platform_driver_register(&pmic8xxx_kp_driver); } module_init(pmic8xxx_kp_init); static void __exit pmic8xxx_kp_exit(void) { platform_driver_unregister(&pmic8xxx_kp_driver); } module_exit(pmic8xxx_kp_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("PMIC8XXX keypad driver"); MODULE_VERSION("1.0"); MODULE_ALIAS("platform:pmic8xxx_keypad"); MODULE_AUTHOR("Trilok Soni <*****@*****.**>");
static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb_tail_pointer(skb); struct tcf_sample *s = to_sample(a); struct tc_sample opt = { .index = s->tcf_index, .action = s->tcf_action, .refcnt = s->tcf_refcnt - ref, .bindcnt = s->tcf_bindcnt - bind, }; struct tcf_t t; if (nla_put(skb, TCA_SAMPLE_PARMS, sizeof(opt), &opt)) goto nla_put_failure; tcf_tm_dump(&t, &s->tcf_tm); if (nla_put_64bit(skb, TCA_SAMPLE_TM, sizeof(t), &t, TCA_SAMPLE_PAD)) goto nla_put_failure; if (nla_put_u32(skb, TCA_SAMPLE_RATE, s->rate)) goto nla_put_failure; if (s->truncate) if (nla_put_u32(skb, TCA_SAMPLE_TRUNC_SIZE, s->trunc_size)) goto nla_put_failure; if (nla_put_u32(skb, TCA_SAMPLE_PSAMPLE_GROUP, s->psample_group_num)) goto nla_put_failure; return skb->len; nla_put_failure: nlmsg_trim(skb, b); return -1; } static int tcf_sample_walker(struct net *net, struct sk_buff *skb, struct netlink_callback *cb, int type, const struct tc_action_ops *ops) { struct tc_action_net *tn = net_generic(net, sample_net_id); return tcf_generic_walker(tn, skb, cb, type, ops); } static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, sample_net_id); return tcf_hash_search(tn, a, index); } static struct tc_action_ops act_sample_ops = { .kind = "sample", .type = TCA_ACT_SAMPLE, .owner = THIS_MODULE, .act = tcf_sample_act, .dump = tcf_sample_dump, .init = tcf_sample_init, .cleanup = tcf_sample_cleanup, .walk = tcf_sample_walker, .lookup = tcf_sample_search, .size = sizeof(struct tcf_sample), }; static __net_init int sample_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, sample_net_id); return tc_action_net_init(tn, &act_sample_ops, SAMPLE_TAB_MASK); } static void __net_exit sample_exit_net(struct net *net) { struct tc_action_net *tn = net_generic(net, sample_net_id); tc_action_net_exit(tn); } static struct pernet_operations sample_net_ops = { .init = sample_init_net, .exit = sample_exit_net, .id = &sample_net_id, .size = sizeof(struct tc_action_net), }; static int __init sample_init_module(void) { return tcf_register_action(&act_sample_ops, &sample_net_ops); } static void __exit sample_cleanup_module(void) { tcf_unregister_action(&act_sample_ops, &sample_net_ops); } module_init(sample_init_module); module_exit(sample_cleanup_module); MODULE_AUTHOR("Yotam Gigi <*****@*****.**>"); MODULE_DESCRIPTION("Packet sampling action"); MODULE_LICENSE("GPL v2");
static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "ALiM7101", }; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { wdt_turnoff(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { wdt_startup(); retval = 0; } return retval; } case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; case WDIOC_SETTIMEOUT: { int new_timeout; if (get_user(new_timeout, p)) return -EFAULT; /* arbitrary upper limit */ if (new_timeout < 1 || new_timeout > 3600) return -EINVAL; timeout = new_timeout; wdt_keepalive(); /* Fall through */ } case WDIOC_GETTIMEOUT: return put_user(timeout, p); default: return -ENOTTY; } } static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, .unlocked_ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &wdt_fops, }; static int wdt_restart_handle(struct notifier_block *this, unsigned long mode, void *cmd) { /* * Cobalt devices have no way of rebooting themselves other * than getting the watchdog to pull reset, so we restart the * watchdog on reboot with no heartbeat. */ wdt_change(WDT_ENABLE); /* loop until the watchdog fires */ while (true) ; return NOTIFY_DONE; } static struct notifier_block wdt_restart_handler = { .notifier_call = wdt_restart_handle, .priority = 128, }; /* * Notifier for system down */ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) wdt_turnoff(); return NOTIFY_DONE; } /* * The WDT needs to learn about soft shutdowns in order to * turn the timebomb registers off. */ static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; static void __exit alim7101_wdt_unload(void) { wdt_turnoff(); /* Deregister */ misc_deregister(&wdt_miscdev); unregister_reboot_notifier(&wdt_notifier); unregister_restart_handler(&wdt_restart_handler); pci_dev_put(alim7101_pmu); } static int __init alim7101_wdt_init(void) { int rc = -EBUSY; struct pci_dev *ali1543_south; char tmp; pr_info("Steve Hill <*****@*****.**>\n"); alim7101_pmu = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); if (!alim7101_pmu) { pr_info("ALi M7101 PMU not present - WDT not set\n"); return -EBUSY; } /* Set the WDT in the PMU to 1 second */ pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02); ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); if (!ali1543_south) { pr_info("ALi 1543 South-Bridge not present - WDT not set\n"); goto err_out; } pci_read_config_byte(ali1543_south, 0x5e, &tmp); pci_dev_put(ali1543_south); if ((tmp & 0x1e) == 0x00) { if (!use_gpio) { pr_info("Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); goto err_out; } nowayout = 1; } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { pr_info("ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); goto err_out; } if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ timeout = WATCHDOG_TIMEOUT; pr_info("timeout value must be 1 <= x <= 3600, using %d\n", timeout); } rc = register_reboot_notifier(&wdt_notifier); if (rc) { pr_err("cannot register reboot notifier (err=%d)\n", rc); goto err_out; } rc = register_restart_handler(&wdt_restart_handler); if (rc) { pr_err("cannot register restart handler (err=%d)\n", rc); goto err_out_reboot; } rc = misc_register(&wdt_miscdev); if (rc) { pr_err("cannot register miscdev on minor=%d (err=%d)\n", wdt_miscdev.minor, rc); goto err_out_restart; } if (nowayout) __module_get(THIS_MODULE); pr_info("WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", timeout, nowayout); return 0; err_out_restart: unregister_restart_handler(&wdt_restart_handler); err_out_reboot: unregister_reboot_notifier(&wdt_notifier); err_out: pci_dev_put(alim7101_pmu); return rc; } module_init(alim7101_wdt_init); module_exit(alim7101_wdt_unload); static const struct pci_device_id alim7101_pci_tbl[] __used = { { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533) }, { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) }, { } }; MODULE_DEVICE_TABLE(pci, alim7101_pci_tbl); MODULE_AUTHOR("Steve Hill"); MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver"); MODULE_LICENSE("GPL");
static void imx_fpga_ack_irq(struct irq_data *data) { struct irq_mng *mng = irq_data_get_irq_chip_data(data); unsigned int irq = data->irq; #else static void imx_fpga_ack_irq(unsigned int irq) { struct irq_mng *mng = &global_mng; #endif int shadow; shadow = 1 << ((irq - IRQ_FPGA_START) % NB_IT); pr_debug("%s: irq %d ack:0x%x\n", __FUNCTION__, irq, shadow); writew(shadow, mng->membase + FPGA_ISR); } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) static void imx_fpga_mask_irq(struct irq_data *data) { struct irq_mng *mng = irq_data_get_irq_chip_data(data); unsigned int irq = data->irq; #else static void imx_fpga_mask_irq(unsigned int irq) { struct irq_mng *mng = &global_mng; #endif int shadow; shadow = readw(mng->membase + FPGA_IMR); shadow &= ~( 1 << ((irq - IRQ_FPGA_START) % NB_IT)); pr_debug("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow); writew(shadow, mng->membase + FPGA_IMR); } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) static void imx_fpga_unmask_irq(struct irq_data *data) { struct irq_mng *mng = irq_data_get_irq_chip_data(data); unsigned int irq = data->irq; #else static void imx_fpga_unmask_irq(unsigned int irq) { struct irq_mng *mng = &global_mng; #endif int shadow; shadow = readw(mng->membase + FPGA_IMR); shadow |= 1 << ((irq - IRQ_FPGA_START) % NB_IT); pr_debug("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow); writew(shadow, mng->membase + FPGA_IMR); } static irqreturn_t ocore_irq_mng_interrupt(int irq, void *data) { struct irq_mng *mng = data; struct irq_desc *desc; unsigned int mask; mask = readw(mng->membase + FPGA_ISR); pr_debug("%s: mask:0x%04x\n", __FUNCTION__, mask); do { irq = IRQ_FPGA_START; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) desc = irq_to_desc(irq); #else desc = irq_desc + irq; #endif /* handle irqs */ while (mask) { if (mask & 1) { pr_debug("handling irq %d 0x%08x\n", irq, (unsigned int)desc); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) desc->handle_irq(irq, desc); #else desc_handle_irq(irq, desc); #endif } irq++; desc++; mask >>= 1; } mask = readw(mng->membase + FPGA_ISR); } while (mask != 0); return IRQ_HANDLED; } static struct irq_chip imx_fpga_chip = { .name = "FPGA", #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) .irq_ack = imx_fpga_ack_irq, .irq_mask = imx_fpga_mask_irq, .irq_unmask = imx_fpga_unmask_irq, #else .ack = imx_fpga_ack_irq, .mask = imx_fpga_mask_irq, .unmask = imx_fpga_unmask_irq, #endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) .irq_set_type = imx_fpga_irq_type, #else .set_type = imx_fpga_irq_type, #endif }; #ifdef CONFIG_PM static int ocore_irq_mng_suspend(struct platform_device *pdev, pm_message_t state) { dev_dbg(&pdev->dev, "suspended\n"); return 0; } static int ocore_irq_mng_resume(struct platform_device *pdev) { dev_dbg(&pdev->dev, "resumed\n"); return 0; } #else # define ocore_irq_mng_suspend NULL # define ocore_irq_mng_resume NULL #endif /* CONFIG_PM */ #if LINUX_VERSION_CODE > KERNEL_VERSION(3,8,0) /* __dev* stuff is removed from Linux since 30/11/2012 */ #define __devinit #define __devexit #endif static int __devinit ocore_irq_mng_probe(struct platform_device *pdev) { struct ocore_irq_mng_pdata *pdata = pdev->dev.platform_data; unsigned int irq; u16 id; int ret = 0; struct resource *mem_res; struct resource *irq_res; struct irq_mng *mng; if (!pdata) { dev_err(&pdev->dev, "Platform data required !\n"); return -ENODEV; } /* get resources */ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { dev_err(&pdev->dev, "can't find mem resource\n"); return -EINVAL; } irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) { dev_err(&pdev->dev, "can't find irq resource\n"); return -EINVAL; } mem_res = request_mem_region(mem_res->start, resource_size(mem_res), pdev->name); if (!mem_res) { dev_err(&pdev->dev, "iomem already in use\n"); return -EBUSY; } /* allocate memory for private structure */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) mng = kmalloc(sizeof(struct irq_mng), GFP_KERNEL); #else mng = &global_mng; #endif if (!mng) { ret = -ENOMEM; goto out_release_mem; } pdata->mng = mng; mng->membase = ioremap(mem_res->start, resource_size(mem_res)); if (!mng->membase) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto out_dev_free; } mng->mem_res = mem_res; mng->irq_res = irq_res; /* check if ID is correct */ id = readw(mng->membase + ID_OFFSET); if (id != pdata->idnum) { printk(KERN_WARNING "For irq_mngr id:%d doesn't match with id" "read %d,\n is device present ?\n", pdata->idnum, id); ret = -ENODEV; goto out_iounmap; } /* Mask all interrupts initially */ writew(0, mng->membase + FPGA_IMR); for (irq = IRQ_FPGA(0); irq < IRQ_FPGA(NB_IT); irq++) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) irq_set_chip_data(irq, mng); irq_set_chip_and_handler_name(irq, &imx_fpga_chip, handle_edge_irq, NULL); #else set_irq_chip_data(irq, mng); set_irq_chip_and_handler(irq, &imx_fpga_chip, handle_edge_irq); #endif set_irq_flags(irq, IRQF_VALID); } /* clear pending interrupts */ writew(0xffff, mng->membase + FPGA_ISR); ret = request_irq(mng->irq_res->start, ocore_irq_mng_interrupt, #if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) IRQF_SAMPLE_RANDOM, #else 0, #endif "ocore_irq_mng", mng); if (ret < 0) { printk(KERN_ERR "Can't register irq %d\n", mng->irq_res->start); goto request_irq_error; } pr_debug("FPGA IRQs initialized (Parent=%d)\n", mng->irq_res->start); return 0; request_irq_error: out_iounmap: iounmap(mng->membase); out_dev_free: #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) kfree(mng); #endif out_release_mem: release_mem_region(mem_res->start, resource_size(mem_res)); return ret; } static int __devexit ocore_irq_mng_remove(struct platform_device *pdev) { struct ocore_irq_mng_pdata *pdata = pdev->dev.platform_data; struct irq_mng *mng = pdata->mng; unsigned int irq; for (irq = IRQ_FPGA(0); irq < IRQ_FPGA(NB_IT); irq++) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) irq_set_chip(irq, NULL); irq_set_handler(irq, NULL); #else set_irq_chip(irq, NULL); set_irq_handler(irq, NULL); #endif set_irq_flags(irq, 0); } free_irq(mng->irq_res->start, mng); release_mem_region(mng->mem_res->start, resource_size(mng->mem_res)); iounmap(mng->membase); kfree(mng); return 0; } static struct platform_driver ocore_irq_mng_driver = { .probe = ocore_irq_mng_probe, .remove = ocore_irq_mng_remove, .suspend = ocore_irq_mng_suspend, .resume = ocore_irq_mng_resume, .driver = { .name = DRIVER_NAME, }, }; static int __init ocore_irq_mng_init(void) { return platform_driver_register(&ocore_irq_mng_driver); } static void __exit ocore_irq_mng_exit(void) { platform_driver_unregister(&ocore_irq_mng_driver); } module_init(ocore_irq_mng_init); module_exit(ocore_irq_mng_exit); MODULE_AUTHOR("Julien Boibessot, <*****@*****.**>"); MODULE_DESCRIPTION("Armadeus OpenCore IRQ manager"); MODULE_LICENSE("GPL");
static int hvfb_probe(struct hv_device *hdev, const struct hv_vmbus_device_id *dev_id) { struct fb_info *info; struct hvfb_par *par; int ret; info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device); if (!info) { pr_err("No memory for framebuffer info\n"); return -ENOMEM; } par = info->par; par->info = info; par->fb_ready = false; init_completion(&par->wait); INIT_DELAYED_WORK(&par->dwork, hvfb_update_work); /* Connect to VSP */ hv_set_drvdata(hdev, info); ret = synthvid_connect_vsp(hdev); if (ret) { pr_err("Unable to connect to VSP\n"); goto error1; } ret = hvfb_getmem(info); if (ret) { pr_err("No memory for framebuffer\n"); goto error2; } hvfb_get_option(info); pr_info("Screen resolution: %dx%d, Color depth: %d\n", screen_width, screen_height, screen_depth); /* Set up fb_info */ info->flags = FBINFO_DEFAULT; info->var.xres_virtual = info->var.xres = screen_width; info->var.yres_virtual = info->var.yres = screen_height; info->var.bits_per_pixel = screen_depth; if (info->var.bits_per_pixel == 16) { info->var.red = (struct fb_bitfield){11, 5, 0}; info->var.green = (struct fb_bitfield){5, 6, 0}; info->var.blue = (struct fb_bitfield){0, 5, 0}; info->var.transp = (struct fb_bitfield){0, 0, 0}; } else { info->var.red = (struct fb_bitfield){16, 8, 0}; info->var.green = (struct fb_bitfield){8, 8, 0}; info->var.blue = (struct fb_bitfield){0, 8, 0}; info->var.transp = (struct fb_bitfield){24, 8, 0}; } info->var.activate = FB_ACTIVATE_NOW; info->var.height = -1; info->var.width = -1; info->var.vmode = FB_VMODE_NONINTERLACED; strcpy(info->fix.id, KBUILD_MODNAME); info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_TRUECOLOR; info->fix.line_length = screen_width * screen_depth / 8; info->fix.accel = FB_ACCEL_NONE; info->fbops = &hvfb_ops; info->pseudo_palette = par->pseudo_palette; /* Send config to host */ ret = synthvid_send_config(hdev); if (ret) goto error; ret = register_framebuffer(info); if (ret) { pr_err("Unable to register framebuffer\n"); goto error; } par->fb_ready = true; par->synchronous_fb = false; par->hvfb_panic_nb.notifier_call = hvfb_on_panic; atomic_notifier_chain_register(&panic_notifier_list, &par->hvfb_panic_nb); return 0; error: hvfb_putmem(info); error2: vmbus_close(hdev->channel); error1: cancel_delayed_work_sync(&par->dwork); hv_set_drvdata(hdev, NULL); framebuffer_release(info); return ret; } static int hvfb_remove(struct hv_device *hdev) { struct fb_info *info = hv_get_drvdata(hdev); struct hvfb_par *par = info->par; atomic_notifier_chain_unregister(&panic_notifier_list, &par->hvfb_panic_nb); par->update = false; par->fb_ready = false; unregister_framebuffer(info); cancel_delayed_work_sync(&par->dwork); vmbus_close(hdev->channel); hv_set_drvdata(hdev, NULL); hvfb_putmem(info); framebuffer_release(info); return 0; } static const struct pci_device_id pci_stub_id_table[] = { { .vendor = PCI_VENDOR_ID_MICROSOFT, .device = PCI_DEVICE_ID_HYPERV_VIDEO, }, { /* end of list */ } }; static const struct hv_vmbus_device_id id_table[] = { /* Synthetic Video Device GUID */ {HV_SYNTHVID_GUID}, {} }; MODULE_DEVICE_TABLE(pci, pci_stub_id_table); MODULE_DEVICE_TABLE(vmbus, id_table); static struct hv_driver hvfb_drv = { .name = KBUILD_MODNAME, .id_table = id_table, .probe = hvfb_probe, .remove = hvfb_remove, }; static int hvfb_pci_stub_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { return 0; } static void hvfb_pci_stub_remove(struct pci_dev *pdev) { } static struct pci_driver hvfb_pci_stub_driver = { .name = KBUILD_MODNAME, .id_table = pci_stub_id_table, .probe = hvfb_pci_stub_probe, .remove = hvfb_pci_stub_remove, }; static int __init hvfb_drv_init(void) { int ret; ret = vmbus_driver_register(&hvfb_drv); if (ret != 0) return ret; ret = pci_register_driver(&hvfb_pci_stub_driver); if (ret != 0) { vmbus_driver_unregister(&hvfb_drv); return ret; } return 0; } static void __exit hvfb_drv_exit(void) { pci_unregister_driver(&hvfb_pci_stub_driver); vmbus_driver_unregister(&hvfb_drv); } module_init(hvfb_drv_init); module_exit(hvfb_drv_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver");
static long wb_smsc_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int new_timeout; union { struct watchdog_info __user *ident; int __user *i; } uarg; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 0, .identity = "SMsC 37B787 Watchdog", }; uarg.i = (int __user *)arg; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: return put_user(wb_smsc_wdt_status(), uarg.i); case WDIOC_GETBOOTSTATUS: return put_user(0, uarg.i); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; if (get_user(options, uarg.i)) return -EFAULT; if (options & WDIOS_DISABLECARD) { wb_smsc_wdt_disable(); retval = 0; } if (options & WDIOS_ENABLECARD) { wb_smsc_wdt_enable(); retval = 0; } return retval; } case WDIOC_KEEPALIVE: wb_smsc_wdt_reset_timer(); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_timeout, uarg.i)) return -EFAULT; /* the API states this is given in secs */ if (unit == UNIT_MINUTE) new_timeout /= 60; if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) return -EINVAL; timeout = new_timeout; wb_smsc_wdt_set_timeout(timeout); /* fall through - and return the new timeout... */ case WDIOC_GETTIMEOUT: new_timeout = timeout; if (unit == UNIT_MINUTE) new_timeout *= 60; return put_user(new_timeout, uarg.i); default: return -ENOTTY; } } /* -- Notifier funtions -----------------------------------------*/ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) { /* set timeout to 0, to avoid possible race-condition */ timeout = 0; wb_smsc_wdt_disable(); } return NOTIFY_DONE; } /* -- Module's structures ---------------------------------------*/ static const struct file_operations wb_smsc_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = wb_smsc_wdt_write, .unlocked_ioctl = wb_smsc_wdt_ioctl, .open = wb_smsc_wdt_open, .release = wb_smsc_wdt_release, }; static struct notifier_block wb_smsc_wdt_notifier = { .notifier_call = wb_smsc_wdt_notify_sys, }; static struct miscdevice wb_smsc_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &wb_smsc_wdt_fops, }; /* -- Module init functions -------------------------------------*/ /* module's "constructor" */ static int __init wb_smsc_wdt_init(void) { int ret; pr_info("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { pr_err("Unable to register IO port %#x\n", IOPORT); ret = -EBUSY; goto out_pnp; } /* set new maximum, if it's too big */ if (timeout > MAX_TIMEOUT) timeout = MAX_TIMEOUT; /* init the watchdog timer */ wb_smsc_wdt_initialize(); ret = register_reboot_notifier(&wb_smsc_wdt_notifier); if (ret) { pr_err("Unable to register reboot notifier err = %d\n", ret); goto out_io; } ret = misc_register(&wb_smsc_wdt_miscdev); if (ret) { pr_err("Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); goto out_rbt; } /* output info */ pr_info("Timeout set to %d %s\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); pr_info("Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); out_clean: return ret; out_rbt: unregister_reboot_notifier(&wb_smsc_wdt_notifier); out_io: release_region(IOPORT, IOPORT_SIZE); out_pnp: goto out_clean; } /* module's "destructor" */ static void __exit wb_smsc_wdt_exit(void) { /* Stop the timer before we leave */ if (!nowayout) { wb_smsc_wdt_shutdown(); pr_info("Watchdog disabled\n"); } misc_deregister(&wb_smsc_wdt_miscdev); unregister_reboot_notifier(&wb_smsc_wdt_notifier); release_region(IOPORT, IOPORT_SIZE); pr_info("SMsC 37B787 watchdog component driver removed\n"); } module_init(wb_smsc_wdt_init); module_exit(wb_smsc_wdt_exit); MODULE_AUTHOR("Sven Anders <*****@*****.**>"); MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")"); MODULE_LICENSE("GPL"); #ifdef SMSC_SUPPORT_MINUTES module_param(unit, int, 0); MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); #endif module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
/* * keypad controller should be initialized in the following sequence * only, otherwise it might get into FSM stuck state. * * - Initialize keypad control parameters, like no. of rows, columns, * timing values etc., * - configure rows and column gpios pull up/down. * - set irq edge type. * - enable the keypad controller. */ static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) { const struct pm8xxx_keypad_platform_data *pdata = pdev->dev.platform_data; const struct matrix_keymap_data *keymap_data; struct pmic8xxx_kp *kp; int rc; u8 ctrl_val; struct pm_gpio kypd_drv = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_LOW, .function = PM_GPIO_FUNC_1, .inv_int_pol = 1, }; struct pm_gpio kypd_sns = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_UP_31P5, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_NO, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 1, }; if (!pdata || !pdata->num_cols || !pdata->num_rows || pdata->num_cols > PM8XXX_MAX_COLS || pdata->num_rows > PM8XXX_MAX_ROWS || pdata->num_cols < PM8XXX_MIN_COLS) { dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } if (!pdata->scan_delay_ms || pdata->scan_delay_ms > MAX_SCAN_DELAY || pdata->scan_delay_ms < MIN_SCAN_DELAY || !is_power_of_2(pdata->scan_delay_ms)) { dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); return -EINVAL; } if (!pdata->row_hold_ns || pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); return -EINVAL; } if (!pdata->debounce_ms || ((pdata->debounce_ms % 5) != 0) || pdata->debounce_ms > MAX_DEBOUNCE_TIME || pdata->debounce_ms < MIN_DEBOUNCE_TIME) { dev_err(&pdev->dev, "invalid debounce time supplied\n"); return -EINVAL; } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data supplied\n"); return -EINVAL; } kp = kzalloc(sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; platform_set_drvdata(pdev, kp); kp->pdata = pdata; kp->dev = &pdev->dev; kp->input = input_allocate_device(); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); rc = -ENOMEM; goto err_alloc_device; } kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); rc = -ENXIO; goto err_get_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); rc = -ENXIO; goto err_get_irq; } kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; kp->input->dev.parent = &pdev->dev; kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; kp->input->id.vendor = 0x0001; kp->input->evbit[0] = BIT_MASK(EV_KEY); if (pdata->rep) __set_bit(EV_REP, kp->input->evbit); kp->input->keycode = kp->keycodes; kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; kp->input->keycodesize = sizeof(kp->keycodes); kp->input->open = pmic8xxx_kp_open; kp->input->close = pmic8xxx_kp_close; matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, kp->input->keycode, kp->input->keybit); input_set_capability(kp->input, EV_MSC, MSC_SCAN); input_set_drvdata(kp->input, kp); /* initialize keypad state */ memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); rc = pmic8xxx_kpd_init(kp); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); goto err_get_irq; } rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, pdata->num_cols, kp, &kypd_sns); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); goto err_gpio_config; } rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, pdata->num_rows, kp, &kypd_drv); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); goto err_gpio_config; } rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); goto err_get_irq; } rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); goto err_req_stuck_irq; } rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); goto err_pmic_reg_read; } kp->ctrl_reg = ctrl_val; rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); goto err_pmic_reg_read; } device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; err_pmic_reg_read: free_irq(kp->key_stuck_irq, NULL); err_req_stuck_irq: free_irq(kp->key_sense_irq, NULL); err_gpio_config: err_get_irq: input_free_device(kp->input); err_alloc_device: platform_set_drvdata(pdev, NULL); kfree(kp); return rc; } static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) { struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); device_init_wakeup(&pdev->dev, 0); free_irq(kp->key_stuck_irq, NULL); free_irq(kp->key_sense_irq, NULL); input_unregister_device(kp->input); kfree(kp); platform_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM_SLEEP static int pmic8xxx_kp_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { enable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); if (input_dev->users) pmic8xxx_kp_disable(kp); mutex_unlock(&input_dev->mutex); } return 0; } static int pmic8xxx_kp_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { disable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); if (input_dev->users) pmic8xxx_kp_enable(kp); mutex_unlock(&input_dev->mutex); } return 0; } #endif static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, pmic8xxx_kp_suspend, pmic8xxx_kp_resume); static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, .remove = __devexit_p(pmic8xxx_kp_remove), .driver = { .name = PM8XXX_KEYPAD_DEV_NAME, .owner = THIS_MODULE, .pm = &pm8xxx_kp_pm_ops, }, }; static int __init pmic8xxx_kp_init(void) { return platform_driver_register(&pmic8xxx_kp_driver); } module_init(pmic8xxx_kp_init); static void __exit pmic8xxx_kp_exit(void) { platform_driver_unregister(&pmic8xxx_kp_driver); } module_exit(pmic8xxx_kp_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("PMIC8XXX keypad driver"); MODULE_VERSION("1.0"); MODULE_ALIAS("platform:pmic8xxx_keypad");
static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) { unsigned char *b = skb_tail_pointer(skb); struct tcf_nat *p = a->priv; struct tc_nat opt = { .old_addr = p->old_addr, .new_addr = p->new_addr, .mask = p->mask, .flags = p->flags, .index = p->tcf_index, .action = p->tcf_action, .refcnt = p->tcf_refcnt - ref, .bindcnt = p->tcf_bindcnt - bind, }; struct tcf_t t; int s; NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt); t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install); t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse); t.expires = jiffies_to_clock_t(p->tcf_tm.expires); NLA_PUT(skb, TCA_NAT_TM, sizeof(t), &t); kfree(opt); return skb->len; nla_put_failure: nlmsg_trim(skb, b); kfree(opt); return -1; } static struct tc_action_ops act_nat_ops = { .kind = "nat", .hinfo = &nat_hash_info, .type = TCA_ACT_NAT, .capab = TCA_CAP_NONE, .owner = THIS_MODULE, .act = tcf_nat, .dump = tcf_nat_dump, .cleanup = tcf_nat_cleanup, .lookup = tcf_hash_search, .init = tcf_nat_init, .walk = tcf_generic_walker }; MODULE_DESCRIPTION("Stateless NAT actions"); MODULE_LICENSE("GPL"); static int __init nat_init_module(void) { return tcf_register_action(&act_nat_ops); } static void __exit nat_cleanup_module(void) { tcf_unregister_action(&act_nat_ops); } module_init(nat_init_module); module_exit(nat_cleanup_module);